| import Clip from './Clip.js'; | 
| import * as color from '../tool/color.js'; | 
| import { eqNaN, extend, isArrayLike, isFunction, isGradientObject, isNumber, isString, keys, logError, map } from '../core/util.js'; | 
| import easingFuncs from './easing.js'; | 
| import { createCubicEasingFunc } from './cubicEasing.js'; | 
| import { isLinearGradient, isRadialGradient } from '../svg/helper.js'; | 
| ; | 
| var arraySlice = Array.prototype.slice; | 
| function interpolateNumber(p0, p1, percent) { | 
|     return (p1 - p0) * percent + p0; | 
| } | 
| function interpolate1DArray(out, p0, p1, percent) { | 
|     var len = p0.length; | 
|     for (var i = 0; i < len; i++) { | 
|         out[i] = interpolateNumber(p0[i], p1[i], percent); | 
|     } | 
|     return out; | 
| } | 
| function interpolate2DArray(out, p0, p1, percent) { | 
|     var len = p0.length; | 
|     var len2 = len && p0[0].length; | 
|     for (var i = 0; i < len; i++) { | 
|         if (!out[i]) { | 
|             out[i] = []; | 
|         } | 
|         for (var j = 0; j < len2; j++) { | 
|             out[i][j] = interpolateNumber(p0[i][j], p1[i][j], percent); | 
|         } | 
|     } | 
|     return out; | 
| } | 
| function add1DArray(out, p0, p1, sign) { | 
|     var len = p0.length; | 
|     for (var i = 0; i < len; i++) { | 
|         out[i] = p0[i] + p1[i] * sign; | 
|     } | 
|     return out; | 
| } | 
| function add2DArray(out, p0, p1, sign) { | 
|     var len = p0.length; | 
|     var len2 = len && p0[0].length; | 
|     for (var i = 0; i < len; i++) { | 
|         if (!out[i]) { | 
|             out[i] = []; | 
|         } | 
|         for (var j = 0; j < len2; j++) { | 
|             out[i][j] = p0[i][j] + p1[i][j] * sign; | 
|         } | 
|     } | 
|     return out; | 
| } | 
| function fillColorStops(val0, val1) { | 
|     var len0 = val0.length; | 
|     var len1 = val1.length; | 
|     var shorterArr = len0 > len1 ? val1 : val0; | 
|     var shorterLen = Math.min(len0, len1); | 
|     var last = shorterArr[shorterLen - 1] || { color: [0, 0, 0, 0], offset: 0 }; | 
|     for (var i = shorterLen; i < Math.max(len0, len1); i++) { | 
|         shorterArr.push({ | 
|             offset: last.offset, | 
|             color: last.color.slice() | 
|         }); | 
|     } | 
| } | 
| function fillArray(val0, val1, arrDim) { | 
|     var arr0 = val0; | 
|     var arr1 = val1; | 
|     if (!arr0.push || !arr1.push) { | 
|         return; | 
|     } | 
|     var arr0Len = arr0.length; | 
|     var arr1Len = arr1.length; | 
|     if (arr0Len !== arr1Len) { | 
|         var isPreviousLarger = arr0Len > arr1Len; | 
|         if (isPreviousLarger) { | 
|             arr0.length = arr1Len; | 
|         } | 
|         else { | 
|             for (var i = arr0Len; i < arr1Len; i++) { | 
|                 arr0.push(arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i])); | 
|             } | 
|         } | 
|     } | 
|     var len2 = arr0[0] && arr0[0].length; | 
|     for (var i = 0; i < arr0.length; i++) { | 
|         if (arrDim === 1) { | 
|             if (isNaN(arr0[i])) { | 
|                 arr0[i] = arr1[i]; | 
|             } | 
|         } | 
|         else { | 
|             for (var j = 0; j < len2; j++) { | 
|                 if (isNaN(arr0[i][j])) { | 
|                     arr0[i][j] = arr1[i][j]; | 
|                 } | 
|             } | 
|         } | 
|     } | 
| } | 
| export function cloneValue(value) { | 
|     if (isArrayLike(value)) { | 
|         var len = value.length; | 
|         if (isArrayLike(value[0])) { | 
|             var ret = []; | 
|             for (var i = 0; i < len; i++) { | 
|                 ret.push(arraySlice.call(value[i])); | 
|             } | 
|             return ret; | 
|         } | 
|         return arraySlice.call(value); | 
|     } | 
|     return value; | 
| } | 
| function rgba2String(rgba) { | 
|     rgba[0] = Math.floor(rgba[0]) || 0; | 
|     rgba[1] = Math.floor(rgba[1]) || 0; | 
|     rgba[2] = Math.floor(rgba[2]) || 0; | 
|     rgba[3] = rgba[3] == null ? 1 : rgba[3]; | 
|     return 'rgba(' + rgba.join(',') + ')'; | 
| } | 
| function guessArrayDim(value) { | 
|     return isArrayLike(value && value[0]) ? 2 : 1; | 
| } | 
| var VALUE_TYPE_NUMBER = 0; | 
| var VALUE_TYPE_1D_ARRAY = 1; | 
| var VALUE_TYPE_2D_ARRAY = 2; | 
| var VALUE_TYPE_COLOR = 3; | 
| var VALUE_TYPE_LINEAR_GRADIENT = 4; | 
| var VALUE_TYPE_RADIAL_GRADIENT = 5; | 
| var VALUE_TYPE_UNKOWN = 6; | 
| function isGradientValueType(valType) { | 
|     return valType === VALUE_TYPE_LINEAR_GRADIENT || valType === VALUE_TYPE_RADIAL_GRADIENT; | 
| } | 
| function isArrayValueType(valType) { | 
|     return valType === VALUE_TYPE_1D_ARRAY || valType === VALUE_TYPE_2D_ARRAY; | 
| } | 
| var tmpRgba = [0, 0, 0, 0]; | 
| var Track = (function () { | 
|     function Track(propName) { | 
|         this.keyframes = []; | 
|         this.discrete = false; | 
|         this._invalid = false; | 
|         this._needsSort = false; | 
|         this._lastFr = 0; | 
|         this._lastFrP = 0; | 
|         this.propName = propName; | 
|     } | 
|     Track.prototype.isFinished = function () { | 
|         return this._finished; | 
|     }; | 
|     Track.prototype.setFinished = function () { | 
|         this._finished = true; | 
|         if (this._additiveTrack) { | 
|             this._additiveTrack.setFinished(); | 
|         } | 
|     }; | 
|     Track.prototype.needsAnimate = function () { | 
|         return this.keyframes.length >= 1; | 
|     }; | 
|     Track.prototype.getAdditiveTrack = function () { | 
|         return this._additiveTrack; | 
|     }; | 
|     Track.prototype.addKeyframe = function (time, rawValue, easing) { | 
|         this._needsSort = true; | 
|         var keyframes = this.keyframes; | 
|         var len = keyframes.length; | 
|         var discrete = false; | 
|         var valType = VALUE_TYPE_UNKOWN; | 
|         var value = rawValue; | 
|         if (isArrayLike(rawValue)) { | 
|             var arrayDim = guessArrayDim(rawValue); | 
|             valType = arrayDim; | 
|             if (arrayDim === 1 && !isNumber(rawValue[0]) | 
|                 || arrayDim === 2 && !isNumber(rawValue[0][0])) { | 
|                 discrete = true; | 
|             } | 
|         } | 
|         else { | 
|             if (isNumber(rawValue) && !eqNaN(rawValue)) { | 
|                 valType = VALUE_TYPE_NUMBER; | 
|             } | 
|             else if (isString(rawValue)) { | 
|                 if (!isNaN(+rawValue)) { | 
|                     valType = VALUE_TYPE_NUMBER; | 
|                 } | 
|                 else { | 
|                     var colorArray = color.parse(rawValue); | 
|                     if (colorArray) { | 
|                         value = colorArray; | 
|                         valType = VALUE_TYPE_COLOR; | 
|                     } | 
|                 } | 
|             } | 
|             else if (isGradientObject(rawValue)) { | 
|                 var parsedGradient = extend({}, value); | 
|                 parsedGradient.colorStops = map(rawValue.colorStops, function (colorStop) { return ({ | 
|                     offset: colorStop.offset, | 
|                     color: color.parse(colorStop.color) | 
|                 }); }); | 
|                 if (isLinearGradient(rawValue)) { | 
|                     valType = VALUE_TYPE_LINEAR_GRADIENT; | 
|                 } | 
|                 else if (isRadialGradient(rawValue)) { | 
|                     valType = VALUE_TYPE_RADIAL_GRADIENT; | 
|                 } | 
|                 value = parsedGradient; | 
|             } | 
|         } | 
|         if (len === 0) { | 
|             this.valType = valType; | 
|         } | 
|         else if (valType !== this.valType || valType === VALUE_TYPE_UNKOWN) { | 
|             discrete = true; | 
|         } | 
|         this.discrete = this.discrete || discrete; | 
|         var kf = { | 
|             time: time, | 
|             value: value, | 
|             rawValue: rawValue, | 
|             percent: 0 | 
|         }; | 
|         if (easing) { | 
|             kf.easing = easing; | 
|             kf.easingFunc = isFunction(easing) | 
|                 ? easing | 
|                 : easingFuncs[easing] || createCubicEasingFunc(easing); | 
|         } | 
|         keyframes.push(kf); | 
|         return kf; | 
|     }; | 
|     Track.prototype.prepare = function (maxTime, additiveTrack) { | 
|         var kfs = this.keyframes; | 
|         if (this._needsSort) { | 
|             kfs.sort(function (a, b) { | 
|                 return a.time - b.time; | 
|             }); | 
|         } | 
|         var valType = this.valType; | 
|         var kfsLen = kfs.length; | 
|         var lastKf = kfs[kfsLen - 1]; | 
|         var isDiscrete = this.discrete; | 
|         var isArr = isArrayValueType(valType); | 
|         var isGradient = isGradientValueType(valType); | 
|         for (var i = 0; i < kfsLen; i++) { | 
|             var kf = kfs[i]; | 
|             var value = kf.value; | 
|             var lastValue = lastKf.value; | 
|             kf.percent = kf.time / maxTime; | 
|             if (!isDiscrete) { | 
|                 if (isArr && i !== kfsLen - 1) { | 
|                     fillArray(value, lastValue, valType); | 
|                 } | 
|                 else if (isGradient) { | 
|                     fillColorStops(value.colorStops, lastValue.colorStops); | 
|                 } | 
|             } | 
|         } | 
|         if (!isDiscrete | 
|             && valType !== VALUE_TYPE_RADIAL_GRADIENT | 
|             && additiveTrack | 
|             && this.needsAnimate() | 
|             && additiveTrack.needsAnimate() | 
|             && valType === additiveTrack.valType | 
|             && !additiveTrack._finished) { | 
|             this._additiveTrack = additiveTrack; | 
|             var startValue = kfs[0].value; | 
|             for (var i = 0; i < kfsLen; i++) { | 
|                 if (valType === VALUE_TYPE_NUMBER) { | 
|                     kfs[i].additiveValue = kfs[i].value - startValue; | 
|                 } | 
|                 else if (valType === VALUE_TYPE_COLOR) { | 
|                     kfs[i].additiveValue = | 
|                         add1DArray([], kfs[i].value, startValue, -1); | 
|                 } | 
|                 else if (isArrayValueType(valType)) { | 
|                     kfs[i].additiveValue = valType === VALUE_TYPE_1D_ARRAY | 
|                         ? add1DArray([], kfs[i].value, startValue, -1) | 
|                         : add2DArray([], kfs[i].value, startValue, -1); | 
|                 } | 
|             } | 
|         } | 
|     }; | 
|     Track.prototype.step = function (target, percent) { | 
|         if (this._finished) { | 
|             return; | 
|         } | 
|         if (this._additiveTrack && this._additiveTrack._finished) { | 
|             this._additiveTrack = null; | 
|         } | 
|         var isAdditive = this._additiveTrack != null; | 
|         var valueKey = isAdditive ? 'additiveValue' : 'value'; | 
|         var valType = this.valType; | 
|         var keyframes = this.keyframes; | 
|         var kfsNum = keyframes.length; | 
|         var propName = this.propName; | 
|         var isValueColor = valType === VALUE_TYPE_COLOR; | 
|         var frameIdx; | 
|         var lastFrame = this._lastFr; | 
|         var mathMin = Math.min; | 
|         var frame; | 
|         var nextFrame; | 
|         if (kfsNum === 1) { | 
|             frame = nextFrame = keyframes[0]; | 
|         } | 
|         else { | 
|             if (percent < 0) { | 
|                 frameIdx = 0; | 
|             } | 
|             else if (percent < this._lastFrP) { | 
|                 var start = mathMin(lastFrame + 1, kfsNum - 1); | 
|                 for (frameIdx = start; frameIdx >= 0; frameIdx--) { | 
|                     if (keyframes[frameIdx].percent <= percent) { | 
|                         break; | 
|                     } | 
|                 } | 
|                 frameIdx = mathMin(frameIdx, kfsNum - 2); | 
|             } | 
|             else { | 
|                 for (frameIdx = lastFrame; frameIdx < kfsNum; frameIdx++) { | 
|                     if (keyframes[frameIdx].percent > percent) { | 
|                         break; | 
|                     } | 
|                 } | 
|                 frameIdx = mathMin(frameIdx - 1, kfsNum - 2); | 
|             } | 
|             nextFrame = keyframes[frameIdx + 1]; | 
|             frame = keyframes[frameIdx]; | 
|         } | 
|         if (!(frame && nextFrame)) { | 
|             return; | 
|         } | 
|         this._lastFr = frameIdx; | 
|         this._lastFrP = percent; | 
|         var interval = (nextFrame.percent - frame.percent); | 
|         var w = interval === 0 ? 1 : mathMin((percent - frame.percent) / interval, 1); | 
|         if (nextFrame.easingFunc) { | 
|             w = nextFrame.easingFunc(w); | 
|         } | 
|         var targetArr = isAdditive ? this._additiveValue | 
|             : (isValueColor ? tmpRgba : target[propName]); | 
|         if ((isArrayValueType(valType) || isValueColor) && !targetArr) { | 
|             targetArr = this._additiveValue = []; | 
|         } | 
|         if (this.discrete) { | 
|             target[propName] = w < 1 ? frame.rawValue : nextFrame.rawValue; | 
|         } | 
|         else if (isArrayValueType(valType)) { | 
|             valType === VALUE_TYPE_1D_ARRAY | 
|                 ? interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w) | 
|                 : interpolate2DArray(targetArr, frame[valueKey], nextFrame[valueKey], w); | 
|         } | 
|         else if (isGradientValueType(valType)) { | 
|             var val = frame[valueKey]; | 
|             var nextVal_1 = nextFrame[valueKey]; | 
|             var isLinearGradient_1 = valType === VALUE_TYPE_LINEAR_GRADIENT; | 
|             target[propName] = { | 
|                 type: isLinearGradient_1 ? 'linear' : 'radial', | 
|                 x: interpolateNumber(val.x, nextVal_1.x, w), | 
|                 y: interpolateNumber(val.y, nextVal_1.y, w), | 
|                 colorStops: map(val.colorStops, function (colorStop, idx) { | 
|                     var nextColorStop = nextVal_1.colorStops[idx]; | 
|                     return { | 
|                         offset: interpolateNumber(colorStop.offset, nextColorStop.offset, w), | 
|                         color: rgba2String(interpolate1DArray([], colorStop.color, nextColorStop.color, w)) | 
|                     }; | 
|                 }), | 
|                 global: nextVal_1.global | 
|             }; | 
|             if (isLinearGradient_1) { | 
|                 target[propName].x2 = interpolateNumber(val.x2, nextVal_1.x2, w); | 
|                 target[propName].y2 = interpolateNumber(val.y2, nextVal_1.y2, w); | 
|             } | 
|             else { | 
|                 target[propName].r = interpolateNumber(val.r, nextVal_1.r, w); | 
|             } | 
|         } | 
|         else if (isValueColor) { | 
|             interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w); | 
|             if (!isAdditive) { | 
|                 target[propName] = rgba2String(targetArr); | 
|             } | 
|         } | 
|         else { | 
|             var value = interpolateNumber(frame[valueKey], nextFrame[valueKey], w); | 
|             if (isAdditive) { | 
|                 this._additiveValue = value; | 
|             } | 
|             else { | 
|                 target[propName] = value; | 
|             } | 
|         } | 
|         if (isAdditive) { | 
|             this._addToTarget(target); | 
|         } | 
|     }; | 
|     Track.prototype._addToTarget = function (target) { | 
|         var valType = this.valType; | 
|         var propName = this.propName; | 
|         var additiveValue = this._additiveValue; | 
|         if (valType === VALUE_TYPE_NUMBER) { | 
|             target[propName] = target[propName] + additiveValue; | 
|         } | 
|         else if (valType === VALUE_TYPE_COLOR) { | 
|             color.parse(target[propName], tmpRgba); | 
|             add1DArray(tmpRgba, tmpRgba, additiveValue, 1); | 
|             target[propName] = rgba2String(tmpRgba); | 
|         } | 
|         else if (valType === VALUE_TYPE_1D_ARRAY) { | 
|             add1DArray(target[propName], target[propName], additiveValue, 1); | 
|         } | 
|         else if (valType === VALUE_TYPE_2D_ARRAY) { | 
|             add2DArray(target[propName], target[propName], additiveValue, 1); | 
|         } | 
|     }; | 
|     return Track; | 
| }()); | 
| var Animator = (function () { | 
|     function Animator(target, loop, allowDiscreteAnimation, additiveTo) { | 
|         this._tracks = {}; | 
|         this._trackKeys = []; | 
|         this._maxTime = 0; | 
|         this._started = 0; | 
|         this._clip = null; | 
|         this._target = target; | 
|         this._loop = loop; | 
|         if (loop && additiveTo) { | 
|             logError('Can\' use additive animation on looped animation.'); | 
|             return; | 
|         } | 
|         this._additiveAnimators = additiveTo; | 
|         this._allowDiscrete = allowDiscreteAnimation; | 
|     } | 
|     Animator.prototype.getMaxTime = function () { | 
|         return this._maxTime; | 
|     }; | 
|     Animator.prototype.getDelay = function () { | 
|         return this._delay; | 
|     }; | 
|     Animator.prototype.getLoop = function () { | 
|         return this._loop; | 
|     }; | 
|     Animator.prototype.getTarget = function () { | 
|         return this._target; | 
|     }; | 
|     Animator.prototype.changeTarget = function (target) { | 
|         this._target = target; | 
|     }; | 
|     Animator.prototype.when = function (time, props, easing) { | 
|         return this.whenWithKeys(time, props, keys(props), easing); | 
|     }; | 
|     Animator.prototype.whenWithKeys = function (time, props, propNames, easing) { | 
|         var tracks = this._tracks; | 
|         for (var i = 0; i < propNames.length; i++) { | 
|             var propName = propNames[i]; | 
|             var track = tracks[propName]; | 
|             if (!track) { | 
|                 track = tracks[propName] = new Track(propName); | 
|                 var initialValue = void 0; | 
|                 var additiveTrack = this._getAdditiveTrack(propName); | 
|                 if (additiveTrack) { | 
|                     var addtiveTrackKfs = additiveTrack.keyframes; | 
|                     var lastFinalKf = addtiveTrackKfs[addtiveTrackKfs.length - 1]; | 
|                     initialValue = lastFinalKf && lastFinalKf.value; | 
|                     if (additiveTrack.valType === VALUE_TYPE_COLOR && initialValue) { | 
|                         initialValue = rgba2String(initialValue); | 
|                     } | 
|                 } | 
|                 else { | 
|                     initialValue = this._target[propName]; | 
|                 } | 
|                 if (initialValue == null) { | 
|                     continue; | 
|                 } | 
|                 if (time > 0) { | 
|                     track.addKeyframe(0, cloneValue(initialValue), easing); | 
|                 } | 
|                 this._trackKeys.push(propName); | 
|             } | 
|             track.addKeyframe(time, cloneValue(props[propName]), easing); | 
|         } | 
|         this._maxTime = Math.max(this._maxTime, time); | 
|         return this; | 
|     }; | 
|     Animator.prototype.pause = function () { | 
|         this._clip.pause(); | 
|         this._paused = true; | 
|     }; | 
|     Animator.prototype.resume = function () { | 
|         this._clip.resume(); | 
|         this._paused = false; | 
|     }; | 
|     Animator.prototype.isPaused = function () { | 
|         return !!this._paused; | 
|     }; | 
|     Animator.prototype.duration = function (duration) { | 
|         this._maxTime = duration; | 
|         this._force = true; | 
|         return this; | 
|     }; | 
|     Animator.prototype._doneCallback = function () { | 
|         this._setTracksFinished(); | 
|         this._clip = null; | 
|         var doneList = this._doneCbs; | 
|         if (doneList) { | 
|             var len = doneList.length; | 
|             for (var i = 0; i < len; i++) { | 
|                 doneList[i].call(this); | 
|             } | 
|         } | 
|     }; | 
|     Animator.prototype._abortedCallback = function () { | 
|         this._setTracksFinished(); | 
|         var animation = this.animation; | 
|         var abortedList = this._abortedCbs; | 
|         if (animation) { | 
|             animation.removeClip(this._clip); | 
|         } | 
|         this._clip = null; | 
|         if (abortedList) { | 
|             for (var i = 0; i < abortedList.length; i++) { | 
|                 abortedList[i].call(this); | 
|             } | 
|         } | 
|     }; | 
|     Animator.prototype._setTracksFinished = function () { | 
|         var tracks = this._tracks; | 
|         var tracksKeys = this._trackKeys; | 
|         for (var i = 0; i < tracksKeys.length; i++) { | 
|             tracks[tracksKeys[i]].setFinished(); | 
|         } | 
|     }; | 
|     Animator.prototype._getAdditiveTrack = function (trackName) { | 
|         var additiveTrack; | 
|         var additiveAnimators = this._additiveAnimators; | 
|         if (additiveAnimators) { | 
|             for (var i = 0; i < additiveAnimators.length; i++) { | 
|                 var track = additiveAnimators[i].getTrack(trackName); | 
|                 if (track) { | 
|                     additiveTrack = track; | 
|                 } | 
|             } | 
|         } | 
|         return additiveTrack; | 
|     }; | 
|     Animator.prototype.start = function (easing) { | 
|         if (this._started > 0) { | 
|             return; | 
|         } | 
|         this._started = 1; | 
|         var self = this; | 
|         var tracks = []; | 
|         var maxTime = this._maxTime || 0; | 
|         for (var i = 0; i < this._trackKeys.length; i++) { | 
|             var propName = this._trackKeys[i]; | 
|             var track = this._tracks[propName]; | 
|             var additiveTrack = this._getAdditiveTrack(propName); | 
|             var kfs = track.keyframes; | 
|             var kfsNum = kfs.length; | 
|             track.prepare(maxTime, additiveTrack); | 
|             if (track.needsAnimate()) { | 
|                 if (!this._allowDiscrete && track.discrete) { | 
|                     var lastKf = kfs[kfsNum - 1]; | 
|                     if (lastKf) { | 
|                         self._target[track.propName] = lastKf.rawValue; | 
|                     } | 
|                     track.setFinished(); | 
|                 } | 
|                 else { | 
|                     tracks.push(track); | 
|                 } | 
|             } | 
|         } | 
|         if (tracks.length || this._force) { | 
|             var clip = new Clip({ | 
|                 life: maxTime, | 
|                 loop: this._loop, | 
|                 delay: this._delay || 0, | 
|                 onframe: function (percent) { | 
|                     self._started = 2; | 
|                     var additiveAnimators = self._additiveAnimators; | 
|                     if (additiveAnimators) { | 
|                         var stillHasAdditiveAnimator = false; | 
|                         for (var i = 0; i < additiveAnimators.length; i++) { | 
|                             if (additiveAnimators[i]._clip) { | 
|                                 stillHasAdditiveAnimator = true; | 
|                                 break; | 
|                             } | 
|                         } | 
|                         if (!stillHasAdditiveAnimator) { | 
|                             self._additiveAnimators = null; | 
|                         } | 
|                     } | 
|                     for (var i = 0; i < tracks.length; i++) { | 
|                         tracks[i].step(self._target, percent); | 
|                     } | 
|                     var onframeList = self._onframeCbs; | 
|                     if (onframeList) { | 
|                         for (var i = 0; i < onframeList.length; i++) { | 
|                             onframeList[i](self._target, percent); | 
|                         } | 
|                     } | 
|                 }, | 
|                 ondestroy: function () { | 
|                     self._doneCallback(); | 
|                 } | 
|             }); | 
|             this._clip = clip; | 
|             if (this.animation) { | 
|                 this.animation.addClip(clip); | 
|             } | 
|             if (easing) { | 
|                 clip.setEasing(easing); | 
|             } | 
|         } | 
|         else { | 
|             this._doneCallback(); | 
|         } | 
|         return this; | 
|     }; | 
|     Animator.prototype.stop = function (forwardToLast) { | 
|         if (!this._clip) { | 
|             return; | 
|         } | 
|         var clip = this._clip; | 
|         if (forwardToLast) { | 
|             clip.onframe(1); | 
|         } | 
|         this._abortedCallback(); | 
|     }; | 
|     Animator.prototype.delay = function (time) { | 
|         this._delay = time; | 
|         return this; | 
|     }; | 
|     Animator.prototype.during = function (cb) { | 
|         if (cb) { | 
|             if (!this._onframeCbs) { | 
|                 this._onframeCbs = []; | 
|             } | 
|             this._onframeCbs.push(cb); | 
|         } | 
|         return this; | 
|     }; | 
|     Animator.prototype.done = function (cb) { | 
|         if (cb) { | 
|             if (!this._doneCbs) { | 
|                 this._doneCbs = []; | 
|             } | 
|             this._doneCbs.push(cb); | 
|         } | 
|         return this; | 
|     }; | 
|     Animator.prototype.aborted = function (cb) { | 
|         if (cb) { | 
|             if (!this._abortedCbs) { | 
|                 this._abortedCbs = []; | 
|             } | 
|             this._abortedCbs.push(cb); | 
|         } | 
|         return this; | 
|     }; | 
|     Animator.prototype.getClip = function () { | 
|         return this._clip; | 
|     }; | 
|     Animator.prototype.getTrack = function (propName) { | 
|         return this._tracks[propName]; | 
|     }; | 
|     Animator.prototype.getTracks = function () { | 
|         var _this = this; | 
|         return map(this._trackKeys, function (key) { return _this._tracks[key]; }); | 
|     }; | 
|     Animator.prototype.stopTracks = function (propNames, forwardToLast) { | 
|         if (!propNames.length || !this._clip) { | 
|             return true; | 
|         } | 
|         var tracks = this._tracks; | 
|         var tracksKeys = this._trackKeys; | 
|         for (var i = 0; i < propNames.length; i++) { | 
|             var track = tracks[propNames[i]]; | 
|             if (track && !track.isFinished()) { | 
|                 if (forwardToLast) { | 
|                     track.step(this._target, 1); | 
|                 } | 
|                 else if (this._started === 1) { | 
|                     track.step(this._target, 0); | 
|                 } | 
|                 track.setFinished(); | 
|             } | 
|         } | 
|         var allAborted = true; | 
|         for (var i = 0; i < tracksKeys.length; i++) { | 
|             if (!tracks[tracksKeys[i]].isFinished()) { | 
|                 allAborted = false; | 
|                 break; | 
|             } | 
|         } | 
|         if (allAborted) { | 
|             this._abortedCallback(); | 
|         } | 
|         return allAborted; | 
|     }; | 
|     Animator.prototype.saveTo = function (target, trackKeys, firstOrLast) { | 
|         if (!target) { | 
|             return; | 
|         } | 
|         trackKeys = trackKeys || this._trackKeys; | 
|         for (var i = 0; i < trackKeys.length; i++) { | 
|             var propName = trackKeys[i]; | 
|             var track = this._tracks[propName]; | 
|             if (!track || track.isFinished()) { | 
|                 continue; | 
|             } | 
|             var kfs = track.keyframes; | 
|             var kf = kfs[firstOrLast ? 0 : kfs.length - 1]; | 
|             if (kf) { | 
|                 target[propName] = cloneValue(kf.rawValue); | 
|             } | 
|         } | 
|     }; | 
|     Animator.prototype.__changeFinalValue = function (finalProps, trackKeys) { | 
|         trackKeys = trackKeys || keys(finalProps); | 
|         for (var i = 0; i < trackKeys.length; i++) { | 
|             var propName = trackKeys[i]; | 
|             var track = this._tracks[propName]; | 
|             if (!track) { | 
|                 continue; | 
|             } | 
|             var kfs = track.keyframes; | 
|             if (kfs.length > 1) { | 
|                 var lastKf = kfs.pop(); | 
|                 track.addKeyframe(lastKf.time, finalProps[propName]); | 
|                 track.prepare(this._maxTime, track.getAdditiveTrack()); | 
|             } | 
|         } | 
|     }; | 
|     return Animator; | 
| }()); | 
| export default Animator; |