http://git-wip-us.apache.org/repos/asf/nifi-fds/blob/4a326208/node_modules/@angular/animations/@angular/animations/browser.js ---------------------------------------------------------------------- diff --git a/node_modules/@angular/animations/@angular/animations/browser.js b/node_modules/@angular/animations/@angular/animations/browser.js new file mode 100644 index 0000000..36c981b --- /dev/null +++ b/node_modules/@angular/animations/@angular/animations/browser.js @@ -0,0 +1,4774 @@ +/** + * @license Angular v4.4.6 + * (c) 2010-2017 Google, Inc. https://angular.io/ + * License: MIT + */ +import { AUTO_STYLE, NoopAnimationPlayer, sequence, style, ɵAnimationGroupPlayer, ɵPRE_STYLE } from '@angular/animations'; + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +function optimizeGroupPlayer(players) { + switch (players.length) { + case 0: + return new NoopAnimationPlayer(); + case 1: + return players[0]; + default: + return new ɵAnimationGroupPlayer(players); + } +} +function normalizeKeyframes(driver, normalizer, element, keyframes, preStyles = {}, postStyles = {}) { + const errors = []; + const normalizedKeyframes = []; + let previousOffset = -1; + let previousKeyframe = null; + keyframes.forEach(kf => { + const offset = kf['offset']; + const isSameOffset = offset == previousOffset; + const normalizedKeyframe = (isSameOffset && previousKeyframe) || {}; + Object.keys(kf).forEach(prop => { + let normalizedProp = prop; + let normalizedValue = kf[prop]; + if (prop !== 'offset') { + normalizedProp = normalizer.normalizePropertyName(normalizedProp, errors); + switch (normalizedValue) { + case ɵPRE_STYLE: + normalizedValue = preStyles[prop]; + break; + case AUTO_STYLE: + normalizedValue = postStyles[prop]; + break; + default: + normalizedValue = + normalizer.normalizeStyleValue(prop, normalizedProp, normalizedValue, errors); + break; + } + } + normalizedKeyframe[normalizedProp] = normalizedValue; + }); + if (!isSameOffset) { + normalizedKeyframes.push(normalizedKeyframe); + } + previousKeyframe = normalizedKeyframe; + previousOffset = offset; + }); + if (errors.length) { + const LINE_START = '\n - '; + throw new Error(`Unable to animate due to the following errors:${LINE_START}${errors.join(LINE_START)}`); + } + return normalizedKeyframes; +} +function listenOnPlayer(player, eventName, event, callback) { + switch (eventName) { + case 'start': + player.onStart(() => callback(event && copyAnimationEvent(event, 'start', player.totalTime))); + break; + case 'done': + player.onDone(() => callback(event && copyAnimationEvent(event, 'done', player.totalTime))); + break; + case 'destroy': + player.onDestroy(() => callback(event && copyAnimationEvent(event, 'destroy', player.totalTime))); + break; + } +} +function copyAnimationEvent(e, phaseName, totalTime) { + const event = makeAnimationEvent(e.element, e.triggerName, e.fromState, e.toState, phaseName || e.phaseName, totalTime == undefined ? e.totalTime : totalTime); + const data = e['_data']; + if (data != null) { + event['_data'] = data; + } + return event; +} +function makeAnimationEvent(element, triggerName, fromState, toState, phaseName = '', totalTime = 0) { + return { element, triggerName, fromState, toState, phaseName, totalTime }; +} +function getOrSetAsInMap(map, key, defaultValue) { + let value; + if (map instanceof Map) { + value = map.get(key); + if (!value) { + map.set(key, value = defaultValue); + } + } + else { + value = map[key]; + if (!value) { + value = map[key] = defaultValue; + } + } + return value; +} +function parseTimelineCommand(command) { + const separatorPos = command.indexOf(':'); + const id = command.substring(1, separatorPos); + const action = command.substr(separatorPos + 1); + return [id, action]; +} +let _contains = (elm1, elm2) => false; +let _matches = (element, selector) => false; +let _query = (element, selector, multi) => { + return []; +}; +if (typeof Element != 'undefined') { + // this is well supported in all browsers + _contains = (elm1, elm2) => { return elm1.contains(elm2); }; + if (Element.prototype.matches) { + _matches = (element, selector) => element.matches(selector); + } + else { + const proto = Element.prototype; + const fn = proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || + proto.oMatchesSelector || proto.webkitMatchesSelector; + if (fn) { + _matches = (element, selector) => fn.apply(element, [selector]); + } + } + _query = (element, selector, multi) => { + let results = []; + if (multi) { + results.push(...element.querySelectorAll(selector)); + } + else { + const elm = element.querySelector(selector); + if (elm) { + results.push(elm); + } + } + return results; + }; +} +const matchesElement = _matches; +const containsElement = _contains; +const invokeQuery = _query; + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +/** + * @experimental + */ +class NoopAnimationDriver { + matchesElement(element, selector) { + return matchesElement(element, selector); + } + containsElement(elm1, elm2) { return containsElement(elm1, elm2); } + query(element, selector, multi) { + return invokeQuery(element, selector, multi); + } + computeStyle(element, prop, defaultValue) { + return defaultValue || ''; + } + animate(element, keyframes, duration, delay, easing, previousPlayers = []) { + return new NoopAnimationPlayer(); + } +} +/** + * @experimental + */ +class AnimationDriver { +} +AnimationDriver.NOOP = new NoopAnimationDriver(); + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +const ONE_SECOND = 1000; +const SUBSTITUTION_EXPR_START = '{{'; +const SUBSTITUTION_EXPR_END = '}}'; +const ENTER_CLASSNAME = 'ng-enter'; +const LEAVE_CLASSNAME = 'ng-leave'; +const ENTER_SELECTOR = '.ng-enter'; +const LEAVE_SELECTOR = '.ng-leave'; +const NG_TRIGGER_CLASSNAME = 'ng-trigger'; +const NG_TRIGGER_SELECTOR = '.ng-trigger'; +const NG_ANIMATING_CLASSNAME = 'ng-animating'; +const NG_ANIMATING_SELECTOR = '.ng-animating'; +function resolveTimingValue(value) { + if (typeof value == 'number') + return value; + const matches = value.match(/^(-?[\.\d]+)(m?s)/); + if (!matches || matches.length < 2) + return 0; + return _convertTimeValueToMS(parseFloat(matches[1]), matches[2]); +} +function _convertTimeValueToMS(value, unit) { + switch (unit) { + case 's': + return value * ONE_SECOND; + default: + return value; + } +} +function resolveTiming(timings, errors, allowNegativeValues) { + return timings.hasOwnProperty('duration') ? + timings : + parseTimeExpression(timings, errors, allowNegativeValues); +} +function parseTimeExpression(exp, errors, allowNegativeValues) { + const regex = /^(-?[\.\d]+)(m?s)(?:\s+(-?[\.\d]+)(m?s))?(?:\s+([-a-z]+(?:\(.+?\))?))?$/i; + let duration; + let delay = 0; + let easing = ''; + if (typeof exp === 'string') { + const matches = exp.match(regex); + if (matches === null) { + errors.push(`The provided timing value "${exp}" is invalid.`); + return { duration: 0, delay: 0, easing: '' }; + } + duration = _convertTimeValueToMS(parseFloat(matches[1]), matches[2]); + const delayMatch = matches[3]; + if (delayMatch != null) { + delay = _convertTimeValueToMS(Math.floor(parseFloat(delayMatch)), matches[4]); + } + const easingVal = matches[5]; + if (easingVal) { + easing = easingVal; + } + } + else { + duration = exp; + } + if (!allowNegativeValues) { + let containsErrors = false; + let startIndex = errors.length; + if (duration < 0) { + errors.push(`Duration values below 0 are not allowed for this animation step.`); + containsErrors = true; + } + if (delay < 0) { + errors.push(`Delay values below 0 are not allowed for this animation step.`); + containsErrors = true; + } + if (containsErrors) { + errors.splice(startIndex, 0, `The provided timing value "${exp}" is invalid.`); + } + } + return { duration, delay, easing }; +} +function copyObj(obj, destination = {}) { + Object.keys(obj).forEach(prop => { destination[prop] = obj[prop]; }); + return destination; +} +function normalizeStyles(styles) { + const normalizedStyles = {}; + if (Array.isArray(styles)) { + styles.forEach(data => copyStyles(data, false, normalizedStyles)); + } + else { + copyStyles(styles, false, normalizedStyles); + } + return normalizedStyles; +} +function copyStyles(styles, readPrototype, destination = {}) { + if (readPrototype) { + // we make use of a for-in loop so that the + // prototypically inherited properties are + // revealed from the backFill map + for (let prop in styles) { + destination[prop] = styles[prop]; + } + } + else { + copyObj(styles, destination); + } + return destination; +} +function setStyles(element, styles) { + if (element['style']) { + Object.keys(styles).forEach(prop => { + const camelProp = dashCaseToCamelCase(prop); + element.style[camelProp] = styles[prop]; + }); + } +} +function eraseStyles(element, styles) { + if (element['style']) { + Object.keys(styles).forEach(prop => { + const camelProp = dashCaseToCamelCase(prop); + element.style[camelProp] = ''; + }); + } +} +function normalizeAnimationEntry(steps) { + if (Array.isArray(steps)) { + if (steps.length == 1) + return steps[0]; + return sequence(steps); + } + return steps; +} +function validateStyleParams(value, options, errors) { + const params = options.params || {}; + const matches = extractStyleParams(value); + if (matches.length) { + matches.forEach(varName => { + if (!params.hasOwnProperty(varName)) { + errors.push(`Unable to resolve the local animation param ${varName} in the given list of values`); + } + }); + } +} +const PARAM_REGEX = new RegExp(`${SUBSTITUTION_EXPR_START}\\s*(.+?)\\s*${SUBSTITUTION_EXPR_END}`, 'g'); +function extractStyleParams(value) { + let params = []; + if (typeof value === 'string') { + const val = value.toString(); + let match; + while (match = PARAM_REGEX.exec(val)) { + params.push(match[1]); + } + PARAM_REGEX.lastIndex = 0; + } + return params; +} +function interpolateParams(value, params, errors) { + const original = value.toString(); + const str = original.replace(PARAM_REGEX, (_, varName) => { + let localVal = params[varName]; + // this means that the value was never overidden by the data passed in by the user + if (!params.hasOwnProperty(varName)) { + errors.push(`Please provide a value for the animation param ${varName}`); + localVal = ''; + } + return localVal.toString(); + }); + // we do this to assert that numeric values stay as they are + return str == original ? value : str; +} +function iteratorToArray(iterator) { + const arr = []; + let item = iterator.next(); + while (!item.done) { + arr.push(item.value); + item = iterator.next(); + } + return arr; +} + +const DASH_CASE_REGEXP = /-+([a-z0-9])/g; +function dashCaseToCamelCase(input) { + return input.replace(DASH_CASE_REGEXP, (...m) => m[1].toUpperCase()); +} +function allowPreviousPlayerStylesMerge(duration, delay) { + return duration === 0 || delay === 0; +} +function visitDslNode(visitor, node, context) { + switch (node.type) { + case 7 /* Trigger */: + return visitor.visitTrigger(node, context); + case 0 /* State */: + return visitor.visitState(node, context); + case 1 /* Transition */: + return visitor.visitTransition(node, context); + case 2 /* Sequence */: + return visitor.visitSequence(node, context); + case 3 /* Group */: + return visitor.visitGroup(node, context); + case 4 /* Animate */: + return visitor.visitAnimate(node, context); + case 5 /* Keyframes */: + return visitor.visitKeyframes(node, context); + case 6 /* Style */: + return visitor.visitStyle(node, context); + case 8 /* Reference */: + return visitor.visitReference(node, context); + case 9 /* AnimateChild */: + return visitor.visitAnimateChild(node, context); + case 10 /* AnimateRef */: + return visitor.visitAnimateRef(node, context); + case 11 /* Query */: + return visitor.visitQuery(node, context); + case 12 /* Stagger */: + return visitor.visitStagger(node, context); + default: + throw new Error(`Unable to resolve animation metadata node #${node.type}`); + } +} + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +const ANY_STATE = '*'; +/** + * @param {?} transitionValue + * @param {?} errors + * @return {?} + */ +function parseTransitionExpr(transitionValue, errors) { + const /** @type {?} */ expressions = []; + if (typeof transitionValue == 'string') { + ((transitionValue)) + .split(/\s*,\s*/) + .forEach(str => parseInnerTransitionStr(str, expressions, errors)); + } + else { + expressions.push(/** @type {?} */ (transitionValue)); + } + return expressions; +} +/** + * @param {?} eventStr + * @param {?} expressions + * @param {?} errors + * @return {?} + */ +function parseInnerTransitionStr(eventStr, expressions, errors) { + if (eventStr[0] == ':') { + eventStr = parseAnimationAlias(eventStr, errors); + } + const /** @type {?} */ match = eventStr.match(/^(\*|[-\w]+)\s*(<?[=-]>)\s*(\*|[-\w]+)$/); + if (match == null || match.length < 4) { + errors.push(`The provided transition expression "${eventStr}" is not supported`); + return expressions; + } + const /** @type {?} */ fromState = match[1]; + const /** @type {?} */ separator = match[2]; + const /** @type {?} */ toState = match[3]; + expressions.push(makeLambdaFromStates(fromState, toState)); + const /** @type {?} */ isFullAnyStateExpr = fromState == ANY_STATE && toState == ANY_STATE; + if (separator[0] == '<' && !isFullAnyStateExpr) { + expressions.push(makeLambdaFromStates(toState, fromState)); + } +} +/** + * @param {?} alias + * @param {?} errors + * @return {?} + */ +function parseAnimationAlias(alias, errors) { + switch (alias) { + case ':enter': + return 'void => *'; + case ':leave': + return '* => void'; + default: + errors.push(`The transition alias value "${alias}" is not supported`); + return '* => *'; + } +} +const TRUE_BOOLEAN_VALUES = new Set(); +TRUE_BOOLEAN_VALUES.add('true'); +TRUE_BOOLEAN_VALUES.add('1'); +const FALSE_BOOLEAN_VALUES = new Set(); +FALSE_BOOLEAN_VALUES.add('false'); +FALSE_BOOLEAN_VALUES.add('0'); +/** + * @param {?} lhs + * @param {?} rhs + * @return {?} + */ +function makeLambdaFromStates(lhs, rhs) { + const /** @type {?} */ LHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(lhs) || FALSE_BOOLEAN_VALUES.has(lhs); + const /** @type {?} */ RHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(rhs) || FALSE_BOOLEAN_VALUES.has(rhs); + return (fromState, toState) => { + let /** @type {?} */ lhsMatch = lhs == ANY_STATE || lhs == fromState; + let /** @type {?} */ rhsMatch = rhs == ANY_STATE || rhs == toState; + if (!lhsMatch && LHS_MATCH_BOOLEAN && typeof fromState === 'boolean') { + lhsMatch = fromState ? TRUE_BOOLEAN_VALUES.has(lhs) : FALSE_BOOLEAN_VALUES.has(lhs); + } + if (!rhsMatch && RHS_MATCH_BOOLEAN && typeof toState === 'boolean') { + rhsMatch = toState ? TRUE_BOOLEAN_VALUES.has(rhs) : FALSE_BOOLEAN_VALUES.has(rhs); + } + return lhsMatch && rhsMatch; + }; +} + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +const SELF_TOKEN = ':self'; +const SELF_TOKEN_REGEX = new RegExp(`\s*${SELF_TOKEN}\s*,?`, 'g'); +/** + * @param {?} metadata + * @param {?} errors + * @return {?} + */ +function buildAnimationAst(metadata, errors) { + return new AnimationAstBuilderVisitor().build(metadata, errors); +} +const LEAVE_TOKEN = ':leave'; +const LEAVE_TOKEN_REGEX = new RegExp(LEAVE_TOKEN, 'g'); +const ENTER_TOKEN = ':enter'; +const ENTER_TOKEN_REGEX = new RegExp(ENTER_TOKEN, 'g'); +const ROOT_SELECTOR = ''; +class AnimationAstBuilderVisitor { + /** + * @param {?} metadata + * @param {?} errors + * @return {?} + */ + build(metadata, errors) { + const /** @type {?} */ context = new AnimationAstBuilderContext(errors); + this._resetContextStyleTimingState(context); + return (visitDslNode(this, normalizeAnimationEntry(metadata), context)); + } + /** + * @param {?} context + * @return {?} + */ + _resetContextStyleTimingState(context) { + context.currentQuerySelector = ROOT_SELECTOR; + context.collectedStyles = {}; + context.collectedStyles[ROOT_SELECTOR] = {}; + context.currentTime = 0; + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + visitTrigger(metadata, context) { + let /** @type {?} */ queryCount = context.queryCount = 0; + let /** @type {?} */ depCount = context.depCount = 0; + const /** @type {?} */ states = []; + const /** @type {?} */ transitions = []; + metadata.definitions.forEach(def => { + this._resetContextStyleTimingState(context); + if (def.type == 0 /* State */) { + const /** @type {?} */ stateDef = (def); + const /** @type {?} */ name = stateDef.name; + name.split(/\s*,\s*/).forEach(n => { + stateDef.name = n; + states.push(this.visitState(stateDef, context)); + }); + stateDef.name = name; + } + else if (def.type == 1 /* Transition */) { + const /** @type {?} */ transition = this.visitTransition(/** @type {?} */ (def), context); + queryCount += transition.queryCount; + depCount += transition.depCount; + transitions.push(transition); + } + else { + context.errors.push('only state() and transition() definitions can sit inside of a trigger()'); + } + }); + return { + type: 7 /* Trigger */, + name: metadata.name, states, transitions, queryCount, depCount, + options: null + }; + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + visitState(metadata, context) { + const /** @type {?} */ styleAst = this.visitStyle(metadata.styles, context); + const /** @type {?} */ astParams = (metadata.options && metadata.options.params) || null; + if (styleAst.containsDynamicStyles) { + const /** @type {?} */ missingSubs = new Set(); + const /** @type {?} */ params = astParams || {}; + styleAst.styles.forEach(value => { + if (isObject(value)) { + const /** @type {?} */ stylesObj = (value); + Object.keys(stylesObj).forEach(prop => { + extractStyleParams(stylesObj[prop]).forEach(sub => { + if (!params.hasOwnProperty(sub)) { + missingSubs.add(sub); + } + }); + }); + } + }); + if (missingSubs.size) { + const /** @type {?} */ missingSubsArr = iteratorToArray(missingSubs.values()); + context.errors.push(`state("${metadata.name}", ...) must define default values for all the following style substitutions: ${missingSubsArr.join(', ')}`); + } + } + return { + type: 0 /* State */, + name: metadata.name, + style: styleAst, + options: astParams ? { params: astParams } : null + }; + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + visitTransition(metadata, context) { + context.queryCount = 0; + context.depCount = 0; + const /** @type {?} */ animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context); + const /** @type {?} */ matchers = parseTransitionExpr(metadata.expr, context.errors); + return { + type: 1 /* Transition */, + matchers, + animation, + queryCount: context.queryCount, + depCount: context.depCount, + options: normalizeAnimationOptions(metadata.options) + }; + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + visitSequence(metadata, context) { + return { + type: 2 /* Sequence */, + steps: metadata.steps.map(s => visitDslNode(this, s, context)), + options: normalizeAnimationOptions(metadata.options) + }; + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + visitGroup(metadata, context) { + const /** @type {?} */ currentTime = context.currentTime; + let /** @type {?} */ furthestTime = 0; + const /** @type {?} */ steps = metadata.steps.map(step => { + context.currentTime = currentTime; + const /** @type {?} */ innerAst = visitDslNode(this, step, context); + furthestTime = Math.max(furthestTime, context.currentTime); + return innerAst; + }); + context.currentTime = furthestTime; + return { + type: 3 /* Group */, + steps, + options: normalizeAnimationOptions(metadata.options) + }; + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + visitAnimate(metadata, context) { + const /** @type {?} */ timingAst = constructTimingAst(metadata.timings, context.errors); + context.currentAnimateTimings = timingAst; + let /** @type {?} */ styleAst; + let /** @type {?} */ styleMetadata = metadata.styles ? metadata.styles : style({}); + if (styleMetadata.type == 5 /* Keyframes */) { + styleAst = this.visitKeyframes(/** @type {?} */ (styleMetadata), context); + } + else { + let /** @type {?} */ styleMetadata = (metadata.styles); + let /** @type {?} */ isEmpty = false; + if (!styleMetadata) { + isEmpty = true; + const /** @type {?} */ newStyleData = {}; + if (timingAst.easing) { + newStyleData['easing'] = timingAst.easing; + } + styleMetadata = style(newStyleData); + } + context.currentTime += timingAst.duration + timingAst.delay; + const /** @type {?} */ _styleAst = this.visitStyle(styleMetadata, context); + _styleAst.isEmptyStep = isEmpty; + styleAst = _styleAst; + } + context.currentAnimateTimings = null; + return { + type: 4 /* Animate */, + timings: timingAst, + style: styleAst, + options: null + }; + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + visitStyle(metadata, context) { + const /** @type {?} */ ast = this._makeStyleAst(metadata, context); + this._validateStyleAst(ast, context); + return ast; + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + _makeStyleAst(metadata, context) { + const /** @type {?} */ styles = []; + if (Array.isArray(metadata.styles)) { + ((metadata.styles)).forEach(styleTuple => { + if (typeof styleTuple == 'string') { + if (styleTuple == AUTO_STYLE) { + styles.push(/** @type {?} */ (styleTuple)); + } + else { + context.errors.push(`The provided style string value ${styleTuple} is not allowed.`); + } + } + else { + styles.push(/** @type {?} */ (styleTuple)); + } + }); + } + else { + styles.push(metadata.styles); + } + let /** @type {?} */ containsDynamicStyles = false; + let /** @type {?} */ collectedEasing = null; + styles.forEach(styleData => { + if (isObject(styleData)) { + const /** @type {?} */ styleMap = (styleData); + const /** @type {?} */ easing = styleMap['easing']; + if (easing) { + collectedEasing = (easing); + delete styleMap['easing']; + } + if (!containsDynamicStyles) { + for (let /** @type {?} */ prop in styleMap) { + const /** @type {?} */ value = styleMap[prop]; + if (value.toString().indexOf(SUBSTITUTION_EXPR_START) >= 0) { + containsDynamicStyles = true; + break; + } + } + } + } + }); + return { + type: 6 /* Style */, + styles, + easing: collectedEasing, + offset: metadata.offset, containsDynamicStyles, + options: null + }; + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + _validateStyleAst(ast, context) { + const /** @type {?} */ timings = context.currentAnimateTimings; + let /** @type {?} */ endTime = context.currentTime; + let /** @type {?} */ startTime = context.currentTime; + if (timings && startTime > 0) { + startTime -= timings.duration + timings.delay; + } + ast.styles.forEach(tuple => { + if (typeof tuple == 'string') + return; + Object.keys(tuple).forEach(prop => { + const /** @type {?} */ collectedStyles = context.collectedStyles[((context.currentQuerySelector))]; + const /** @type {?} */ collectedEntry = collectedStyles[prop]; + let /** @type {?} */ updateCollectedStyle = true; + if (collectedEntry) { + if (startTime != endTime && startTime >= collectedEntry.startTime && + endTime <= collectedEntry.endTime) { + context.errors.push(`The CSS property "${prop}" that exists between the times of "${collectedEntry.startTime}ms" and "${collectedEntry.endTime}ms" is also being animated in a parallel animation between the times of "${startTime}ms" and "${endTime}ms"`); + updateCollectedStyle = false; + } + // we always choose the smaller start time value since we + // want to have a record of the entire animation window where + // the style property is being animated in between + startTime = collectedEntry.startTime; + } + if (updateCollectedStyle) { + collectedStyles[prop] = { startTime, endTime }; + } + if (context.options) { + validateStyleParams(tuple[prop], context.options, context.errors); + } + }); + }); + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + visitKeyframes(metadata, context) { + const /** @type {?} */ ast = { type: 5 /* Keyframes */, styles: [], options: null }; + if (!context.currentAnimateTimings) { + context.errors.push(`keyframes() must be placed inside of a call to animate()`); + return ast; + } + const /** @type {?} */ MAX_KEYFRAME_OFFSET = 1; + let /** @type {?} */ totalKeyframesWithOffsets = 0; + const /** @type {?} */ offsets = []; + let /** @type {?} */ offsetsOutOfOrder = false; + let /** @type {?} */ keyframesOutOfRange = false; + let /** @type {?} */ previousOffset = 0; + const /** @type {?} */ keyframes = metadata.steps.map(styles => { + const /** @type {?} */ style$$1 = this._makeStyleAst(styles, context); + let /** @type {?} */ offsetVal = style$$1.offset != null ? style$$1.offset : consumeOffset(style$$1.styles); + let /** @type {?} */ offset = 0; + if (offsetVal != null) { + totalKeyframesWithOffsets++; + offset = style$$1.offset = offsetVal; + } + keyframesOutOfRange = keyframesOutOfRange || offset < 0 || offset > 1; + offsetsOutOfOrder = offsetsOutOfOrder || offset < previousOffset; + previousOffset = offset; + offsets.push(offset); + return style$$1; + }); + if (keyframesOutOfRange) { + context.errors.push(`Please ensure that all keyframe offsets are between 0 and 1`); + } + if (offsetsOutOfOrder) { + context.errors.push(`Please ensure that all keyframe offsets are in order`); + } + const /** @type {?} */ length = metadata.steps.length; + let /** @type {?} */ generatedOffset = 0; + if (totalKeyframesWithOffsets > 0 && totalKeyframesWithOffsets < length) { + context.errors.push(`Not all style() steps within the declared keyframes() contain offsets`); + } + else if (totalKeyframesWithOffsets == 0) { + generatedOffset = MAX_KEYFRAME_OFFSET / (length - 1); + } + const /** @type {?} */ limit = length - 1; + const /** @type {?} */ currentTime = context.currentTime; + const /** @type {?} */ currentAnimateTimings = ((context.currentAnimateTimings)); + const /** @type {?} */ animateDuration = currentAnimateTimings.duration; + keyframes.forEach((kf, i) => { + const /** @type {?} */ offset = generatedOffset > 0 ? (i == limit ? 1 : (generatedOffset * i)) : offsets[i]; + const /** @type {?} */ durationUpToThisFrame = offset * animateDuration; + context.currentTime = currentTime + currentAnimateTimings.delay + durationUpToThisFrame; + currentAnimateTimings.duration = durationUpToThisFrame; + this._validateStyleAst(kf, context); + kf.offset = offset; + ast.styles.push(kf); + }); + return ast; + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + visitReference(metadata, context) { + return { + type: 8 /* Reference */, + animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context), + options: normalizeAnimationOptions(metadata.options) + }; + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + visitAnimateChild(metadata, context) { + context.depCount++; + return { + type: 9 /* AnimateChild */, + options: normalizeAnimationOptions(metadata.options) + }; + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + visitAnimateRef(metadata, context) { + return { + type: 10 /* AnimateRef */, + animation: this.visitReference(metadata.animation, context), + options: normalizeAnimationOptions(metadata.options) + }; + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + visitQuery(metadata, context) { + const /** @type {?} */ parentSelector = ((context.currentQuerySelector)); + const /** @type {?} */ options = ((metadata.options || {})); + context.queryCount++; + context.currentQuery = metadata; + const [selector, includeSelf] = normalizeSelector(metadata.selector); + context.currentQuerySelector = + parentSelector.length ? (parentSelector + ' ' + selector) : selector; + getOrSetAsInMap(context.collectedStyles, context.currentQuerySelector, {}); + const /** @type {?} */ animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context); + context.currentQuery = null; + context.currentQuerySelector = parentSelector; + return { + type: 11 /* Query */, + selector, + limit: options.limit || 0, + optional: !!options.optional, includeSelf, animation, + originalSelector: metadata.selector, + options: normalizeAnimationOptions(metadata.options) + }; + } + /** + * @param {?} metadata + * @param {?} context + * @return {?} + */ + visitStagger(metadata, context) { + if (!context.currentQuery) { + context.errors.push(`stagger() can only be used inside of query()`); + } + const /** @type {?} */ timings = metadata.timings === 'full' ? + { duration: 0, delay: 0, easing: 'full' } : + resolveTiming(metadata.timings, context.errors, true); + return { + type: 12 /* Stagger */, + animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context), timings, + options: null + }; + } +} +/** + * @param {?} selector + * @return {?} + */ +function normalizeSelector(selector) { + const /** @type {?} */ hasAmpersand = selector.split(/\s*,\s*/).find(token => token == SELF_TOKEN) ? true : false; + if (hasAmpersand) { + selector = selector.replace(SELF_TOKEN_REGEX, ''); + } + selector = selector.replace(ENTER_TOKEN_REGEX, ENTER_SELECTOR) + .replace(LEAVE_TOKEN_REGEX, LEAVE_SELECTOR) + .replace(/@\*/g, NG_TRIGGER_SELECTOR) + .replace(/@\w+/g, match => NG_TRIGGER_SELECTOR + '-' + match.substr(1)) + .replace(/:animating/g, NG_ANIMATING_SELECTOR); + return [selector, hasAmpersand]; +} +/** + * @param {?} obj + * @return {?} + */ +function normalizeParams(obj) { + return obj ? copyObj(obj) : null; +} +class AnimationAstBuilderContext { + /** + * @param {?} errors + */ + constructor(errors) { + this.errors = errors; + this.queryCount = 0; + this.depCount = 0; + this.currentTransition = null; + this.currentQuery = null; + this.currentQuerySelector = null; + this.currentAnimateTimings = null; + this.currentTime = 0; + this.collectedStyles = {}; + this.options = null; + } +} +/** + * @param {?} styles + * @return {?} + */ +function consumeOffset(styles) { + if (typeof styles == 'string') + return null; + let /** @type {?} */ offset = null; + if (Array.isArray(styles)) { + styles.forEach(styleTuple => { + if (isObject(styleTuple) && styleTuple.hasOwnProperty('offset')) { + const /** @type {?} */ obj = (styleTuple); + offset = parseFloat(/** @type {?} */ (obj['offset'])); + delete obj['offset']; + } + }); + } + else if (isObject(styles) && styles.hasOwnProperty('offset')) { + const /** @type {?} */ obj = (styles); + offset = parseFloat(/** @type {?} */ (obj['offset'])); + delete obj['offset']; + } + return offset; +} +/** + * @param {?} value + * @return {?} + */ +function isObject(value) { + return !Array.isArray(value) && typeof value == 'object'; +} +/** + * @param {?} value + * @param {?} errors + * @return {?} + */ +function constructTimingAst(value, errors) { + let /** @type {?} */ timings = null; + if (value.hasOwnProperty('duration')) { + timings = (value); + } + else if (typeof value == 'number') { + const /** @type {?} */ duration = resolveTiming(/** @type {?} */ (value), errors).duration; + return makeTimingAst(/** @type {?} */ (duration), 0, ''); + } + const /** @type {?} */ strValue = (value); + const /** @type {?} */ isDynamic = strValue.split(/\s+/).some(v => v.charAt(0) == '{' && v.charAt(1) == '{'); + if (isDynamic) { + const /** @type {?} */ ast = (makeTimingAst(0, 0, '')); + ast.dynamic = true; + ast.strValue = strValue; + return (ast); + } + timings = timings || resolveTiming(strValue, errors); + return makeTimingAst(timings.duration, timings.delay, timings.easing); +} +/** + * @param {?} options + * @return {?} + */ +function normalizeAnimationOptions(options) { + if (options) { + options = copyObj(options); + if (options['params']) { + options['params'] = ((normalizeParams(options['params']))); + } + } + else { + options = {}; + } + return options; +} +/** + * @param {?} duration + * @param {?} delay + * @param {?} easing + * @return {?} + */ +function makeTimingAst(duration, delay, easing) { + return { duration, delay, easing }; +} + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +/** + * @param {?} element + * @param {?} keyframes + * @param {?} preStyleProps + * @param {?} postStyleProps + * @param {?} duration + * @param {?} delay + * @param {?=} easing + * @param {?=} subTimeline + * @return {?} + */ +function createTimelineInstruction(element, keyframes, preStyleProps, postStyleProps, duration, delay, easing = null, subTimeline = false) { + return { + type: 1 /* TimelineAnimation */, + element, + keyframes, + preStyleProps, + postStyleProps, + duration, + delay, + totalTime: duration + delay, easing, subTimeline + }; +} + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +class ElementInstructionMap { + constructor() { + this._map = new Map(); + } + /** + * @param {?} element + * @return {?} + */ + consume(element) { + let /** @type {?} */ instructions = this._map.get(element); + if (instructions) { + this._map.delete(element); + } + else { + instructions = []; + } + return instructions; + } + /** + * @param {?} element + * @param {?} instructions + * @return {?} + */ + append(element, instructions) { + let /** @type {?} */ existingInstructions = this._map.get(element); + if (!existingInstructions) { + this._map.set(element, existingInstructions = []); + } + existingInstructions.push(...instructions); + } + /** + * @param {?} element + * @return {?} + */ + has(element) { return this._map.has(element); } + /** + * @return {?} + */ + clear() { this._map.clear(); } +} + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +const ONE_FRAME_IN_MILLISECONDS = 1; +/** + * @param {?} driver + * @param {?} rootElement + * @param {?} ast + * @param {?=} startingStyles + * @param {?=} finalStyles + * @param {?=} options + * @param {?=} subInstructions + * @param {?=} errors + * @return {?} + */ +function buildAnimationTimelines(driver, rootElement, ast, startingStyles = {}, finalStyles = {}, options, subInstructions, errors = []) { + return new AnimationTimelineBuilderVisitor().buildKeyframes(driver, rootElement, ast, startingStyles, finalStyles, options, subInstructions, errors); +} +class AnimationTimelineBuilderVisitor { + /** + * @param {?} driver + * @param {?} rootElement + * @param {?} ast + * @param {?} startingStyles + * @param {?} finalStyles + * @param {?} options + * @param {?=} subInstructions + * @param {?=} errors + * @return {?} + */ + buildKeyframes(driver, rootElement, ast, startingStyles, finalStyles, options, subInstructions, errors = []) { + subInstructions = subInstructions || new ElementInstructionMap(); + const /** @type {?} */ context = new AnimationTimelineContext(driver, rootElement, subInstructions, errors, []); + context.options = options; + context.currentTimeline.setStyles([startingStyles], null, context.errors, options); + visitDslNode(this, ast, context); + // this checks to see if an actual animation happened + const /** @type {?} */ timelines = context.timelines.filter(timeline => timeline.containsAnimation()); + if (timelines.length && Object.keys(finalStyles).length) { + const /** @type {?} */ tl = timelines[timelines.length - 1]; + if (!tl.allowOnlyTimelineStyles()) { + tl.setStyles([finalStyles], null, context.errors, options); + } + } + return timelines.length ? timelines.map(timeline => timeline.buildKeyframes()) : + [createTimelineInstruction(rootElement, [], [], [], 0, 0, '', false)]; + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + visitTrigger(ast, context) { + // these values are not visited in this AST + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + visitState(ast, context) { + // these values are not visited in this AST + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + visitTransition(ast, context) { + // these values are not visited in this AST + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + visitAnimateChild(ast, context) { + const /** @type {?} */ elementInstructions = context.subInstructions.consume(context.element); + if (elementInstructions) { + const /** @type {?} */ innerContext = context.createSubContext(ast.options); + const /** @type {?} */ startTime = context.currentTimeline.currentTime; + const /** @type {?} */ endTime = this._visitSubInstructions(elementInstructions, innerContext, /** @type {?} */ (innerContext.options)); + if (startTime != endTime) { + // we do this on the upper context because we created a sub context for + // the sub child animations + context.transformIntoNewTimeline(endTime); + } + } + context.previousNode = ast; + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + visitAnimateRef(ast, context) { + const /** @type {?} */ innerContext = context.createSubContext(ast.options); + innerContext.transformIntoNewTimeline(); + this.visitReference(ast.animation, innerContext); + context.transformIntoNewTimeline(innerContext.currentTimeline.currentTime); + context.previousNode = ast; + } + /** + * @param {?} instructions + * @param {?} context + * @param {?} options + * @return {?} + */ + _visitSubInstructions(instructions, context, options) { + const /** @type {?} */ startTime = context.currentTimeline.currentTime; + let /** @type {?} */ furthestTime = startTime; + // this is a special-case for when a user wants to skip a sub + // animation from being fired entirely. + const /** @type {?} */ duration = options.duration != null ? resolveTimingValue(options.duration) : null; + const /** @type {?} */ delay = options.delay != null ? resolveTimingValue(options.delay) : null; + if (duration !== 0) { + instructions.forEach(instruction => { + const /** @type {?} */ instructionTimings = context.appendInstructionToTimeline(instruction, duration, delay); + furthestTime = + Math.max(furthestTime, instructionTimings.duration + instructionTimings.delay); + }); + } + return furthestTime; + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + visitReference(ast, context) { + context.updateOptions(ast.options, true); + visitDslNode(this, ast.animation, context); + context.previousNode = ast; + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + visitSequence(ast, context) { + const /** @type {?} */ subContextCount = context.subContextCount; + let /** @type {?} */ ctx = context; + const /** @type {?} */ options = ast.options; + if (options && (options.params || options.delay)) { + ctx = context.createSubContext(options); + ctx.transformIntoNewTimeline(); + if (options.delay != null) { + if (ctx.previousNode.type == 6 /* Style */) { + ctx.currentTimeline.snapshotCurrentStyles(); + ctx.previousNode = DEFAULT_NOOP_PREVIOUS_NODE; + } + const /** @type {?} */ delay = resolveTimingValue(options.delay); + ctx.delayNextStep(delay); + } + } + if (ast.steps.length) { + ast.steps.forEach(s => visitDslNode(this, s, ctx)); + // this is here just incase the inner steps only contain or end with a style() call + ctx.currentTimeline.applyStylesToKeyframe(); + // this means that some animation function within the sequence + // ended up creating a sub timeline (which means the current + // timeline cannot overlap with the contents of the sequence) + if (ctx.subContextCount > subContextCount) { + ctx.transformIntoNewTimeline(); + } + } + context.previousNode = ast; + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + visitGroup(ast, context) { + const /** @type {?} */ innerTimelines = []; + let /** @type {?} */ furthestTime = context.currentTimeline.currentTime; + const /** @type {?} */ delay = ast.options && ast.options.delay ? resolveTimingValue(ast.options.delay) : 0; + ast.steps.forEach(s => { + const /** @type {?} */ innerContext = context.createSubContext(ast.options); + if (delay) { + innerContext.delayNextStep(delay); + } + visitDslNode(this, s, innerContext); + furthestTime = Math.max(furthestTime, innerContext.currentTimeline.currentTime); + innerTimelines.push(innerContext.currentTimeline); + }); + // this operation is run after the AST loop because otherwise + // if the parent timeline's collected styles were updated then + // it would pass in invalid data into the new-to-be forked items + innerTimelines.forEach(timeline => context.currentTimeline.mergeTimelineCollectedStyles(timeline)); + context.transformIntoNewTimeline(furthestTime); + context.previousNode = ast; + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + _visitTiming(ast, context) { + if (((ast)).dynamic) { + const /** @type {?} */ strValue = ((ast)).strValue; + const /** @type {?} */ timingValue = context.params ? interpolateParams(strValue, context.params, context.errors) : strValue; + return resolveTiming(timingValue, context.errors); + } + else { + return { duration: ast.duration, delay: ast.delay, easing: ast.easing }; + } + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + visitAnimate(ast, context) { + const /** @type {?} */ timings = context.currentAnimateTimings = this._visitTiming(ast.timings, context); + const /** @type {?} */ timeline = context.currentTimeline; + if (timings.delay) { + context.incrementTime(timings.delay); + timeline.snapshotCurrentStyles(); + } + const /** @type {?} */ style$$1 = ast.style; + if (style$$1.type == 5 /* Keyframes */) { + this.visitKeyframes(style$$1, context); + } + else { + context.incrementTime(timings.duration); + this.visitStyle(/** @type {?} */ (style$$1), context); + timeline.applyStylesToKeyframe(); + } + context.currentAnimateTimings = null; + context.previousNode = ast; + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + visitStyle(ast, context) { + const /** @type {?} */ timeline = context.currentTimeline; + const /** @type {?} */ timings = ((context.currentAnimateTimings)); + // this is a special case for when a style() call + // directly follows an animate() call (but not inside of an animate() call) + if (!timings && timeline.getCurrentStyleProperties().length) { + timeline.forwardFrame(); + } + const /** @type {?} */ easing = (timings && timings.easing) || ast.easing; + if (ast.isEmptyStep) { + timeline.applyEmptyStep(easing); + } + else { + timeline.setStyles(ast.styles, easing, context.errors, context.options); + } + context.previousNode = ast; + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + visitKeyframes(ast, context) { + const /** @type {?} */ currentAnimateTimings = ((context.currentAnimateTimings)); + const /** @type {?} */ startTime = (((context.currentTimeline))).duration; + const /** @type {?} */ duration = currentAnimateTimings.duration; + const /** @type {?} */ innerContext = context.createSubContext(); + const /** @type {?} */ innerTimeline = innerContext.currentTimeline; + innerTimeline.easing = currentAnimateTimings.easing; + ast.styles.forEach(step => { + const /** @type {?} */ offset = step.offset || 0; + innerTimeline.forwardTime(offset * duration); + innerTimeline.setStyles(step.styles, step.easing, context.errors, context.options); + innerTimeline.applyStylesToKeyframe(); + }); + // this will ensure that the parent timeline gets all the styles from + // the child even if the new timeline below is not used + context.currentTimeline.mergeTimelineCollectedStyles(innerTimeline); + // we do this because the window between this timeline and the sub timeline + // should ensure that the styles within are exactly the same as they were before + context.transformIntoNewTimeline(startTime + duration); + context.previousNode = ast; + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + visitQuery(ast, context) { + // in the event that the first step before this is a style step we need + // to ensure the styles are applied before the children are animated + const /** @type {?} */ startTime = context.currentTimeline.currentTime; + const /** @type {?} */ options = ((ast.options || {})); + const /** @type {?} */ delay = options.delay ? resolveTimingValue(options.delay) : 0; + if (delay && (context.previousNode.type === 6 /* Style */ || + (startTime == 0 && context.currentTimeline.getCurrentStyleProperties().length))) { + context.currentTimeline.snapshotCurrentStyles(); + context.previousNode = DEFAULT_NOOP_PREVIOUS_NODE; + } + let /** @type {?} */ furthestTime = startTime; + const /** @type {?} */ elms = context.invokeQuery(ast.selector, ast.originalSelector, ast.limit, ast.includeSelf, options.optional ? true : false, context.errors); + context.currentQueryTotal = elms.length; + let /** @type {?} */ sameElementTimeline = null; + elms.forEach((element, i) => { + context.currentQueryIndex = i; + const /** @type {?} */ innerContext = context.createSubContext(ast.options, element); + if (delay) { + innerContext.delayNextStep(delay); + } + if (element === context.element) { + sameElementTimeline = innerContext.currentTimeline; + } + visitDslNode(this, ast.animation, innerContext); + // this is here just incase the inner steps only contain or end + // with a style() call (which is here to signal that this is a preparatory + // call to style an element before it is animated again) + innerContext.currentTimeline.applyStylesToKeyframe(); + const /** @type {?} */ endTime = innerContext.currentTimeline.currentTime; + furthestTime = Math.max(furthestTime, endTime); + }); + context.currentQueryIndex = 0; + context.currentQueryTotal = 0; + context.transformIntoNewTimeline(furthestTime); + if (sameElementTimeline) { + context.currentTimeline.mergeTimelineCollectedStyles(sameElementTimeline); + context.currentTimeline.snapshotCurrentStyles(); + } + context.previousNode = ast; + } + /** + * @param {?} ast + * @param {?} context + * @return {?} + */ + visitStagger(ast, context) { + const /** @type {?} */ parentContext = ((context.parentContext)); + const /** @type {?} */ tl = context.currentTimeline; + const /** @type {?} */ timings = ast.timings; + const /** @type {?} */ duration = Math.abs(timings.duration); + const /** @type {?} */ maxTime = duration * (context.currentQueryTotal - 1); + let /** @type {?} */ delay = duration * context.currentQueryIndex; + let /** @type {?} */ staggerTransformer = timings.duration < 0 ? 'reverse' : timings.easing; + switch (staggerTransformer) { + case 'reverse': + delay = maxTime - delay; + break; + case 'full': + delay = parentContext.currentStaggerTime; + break; + } + const /** @type {?} */ timeline = context.currentTimeline; + if (delay) { + timeline.delayNextStep(delay); + } + const /** @type {?} */ startingTime = timeline.currentTime; + visitDslNode(this, ast.animation, context); + context.previousNode = ast; + // time = duration + delay + // the reason why this computation is so complex is because + // the inner timeline may either have a delay value or a stretched + // keyframe depending on if a subtimeline is not used or is used. + parentContext.currentStaggerTime = + (tl.currentTime - startingTime) + (tl.startTime - parentContext.currentTimeline.startTime); + } +} +const DEFAULT_NOOP_PREVIOUS_NODE = ({}); +class AnimationTimelineContext { + /** + * @param {?} _driver + * @param {?} element + * @param {?} subInstructions + * @param {?} errors + * @param {?} timelines + * @param {?=} initialTimeline + */ + constructor(_driver, element, subInstructions, errors, timelines, initialTimeline) { + this._driver = _driver; + this.element = element; + this.subInstructions = subInstructions; + this.errors = errors; + this.timelines = timelines; + this.parentContext = null; + this.currentAnimateTimings = null; + this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE; + this.subContextCount = 0; + this.options = {}; + this.currentQueryIndex = 0; + this.currentQueryTotal = 0; + this.currentStaggerTime = 0; + this.currentTimeline = initialTimeline || new TimelineBuilder(element, 0); + timelines.push(this.currentTimeline); + } + /** + * @return {?} + */ + get params() { return this.options.params; } + /** + * @param {?} options + * @param {?=} skipIfExists + * @return {?} + */ + updateOptions(options, skipIfExists) { + if (!options) + return; + const /** @type {?} */ newOptions = (options); + let /** @type {?} */ optionsToUpdate = this.options; + // NOTE: this will get patched up when other animation methods support duration overrides + if (newOptions.duration != null) { + ((optionsToUpdate)).duration = resolveTimingValue(newOptions.duration); + } + if (newOptions.delay != null) { + optionsToUpdate.delay = resolveTimingValue(newOptions.delay); + } + const /** @type {?} */ newParams = newOptions.params; + if (newParams) { + let /** @type {?} */ paramsToUpdate = ((optionsToUpdate.params)); + if (!paramsToUpdate) { + paramsToUpdate = this.options.params = {}; + } + Object.keys(newParams).forEach(name => { + if (!skipIfExists || !paramsToUpdate.hasOwnProperty(name)) { + paramsToUpdate[name] = interpolateParams(newParams[name], paramsToUpdate, this.errors); + } + }); + } + } + /** + * @return {?} + */ + _copyOptions() { + const /** @type {?} */ options = {}; + if (this.options) { + const /** @type {?} */ oldParams = this.options.params; + if (oldParams) { + const /** @type {?} */ params = options['params'] = {}; + Object.keys(oldParams).forEach(name => { params[name] = oldParams[name]; }); + } + } + return options; + } + /** + * @param {?=} options + * @param {?=} element + * @param {?=} newTime + * @return {?} + */ + createSubContext(options = null, element, newTime) { + const /** @type {?} */ target = element || this.element; + const /** @type {?} */ context = new AnimationTimelineContext(this._driver, target, this.subInstructions, this.errors, this.timelines, this.currentTimeline.fork(target, newTime || 0)); + context.previousNode = this.previousNode; + context.currentAnimateTimings = this.currentAnimateTimings; + context.options = this._copyOptions(); + context.updateOptions(options); + context.currentQueryIndex = this.currentQueryIndex; + context.currentQueryTotal = this.currentQueryTotal; + context.parentContext = this; + this.subContextCount++; + return context; + } + /** + * @param {?=} newTime + * @return {?} + */ + transformIntoNewTimeline(newTime) { + this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE; + this.currentTimeline = this.currentTimeline.fork(this.element, newTime); + this.timelines.push(this.currentTimeline); + return this.currentTimeline; + } + /** + * @param {?} instruction + * @param {?} duration + * @param {?} delay + * @return {?} + */ + appendInstructionToTimeline(instruction, duration, delay) { + const /** @type {?} */ updatedTimings = { + duration: duration != null ? duration : instruction.duration, + delay: this.currentTimeline.currentTime + (delay != null ? delay : 0) + instruction.delay, + easing: '' + }; + const /** @type {?} */ builder = new SubTimelineBuilder(instruction.element, instruction.keyframes, instruction.preStyleProps, instruction.postStyleProps, updatedTimings, instruction.stretchStartingKeyframe); + this.timelines.push(builder); + return updatedTimings; + } + /** + * @param {?} time + * @return {?} + */ + incrementTime(time) { + this.currentTimeline.forwardTime(this.currentTimeline.duration + time); + } + /** + * @param {?} delay + * @return {?} + */ + delayNextStep(delay) { + // negative delays are not yet supported + if (delay > 0) { + this.currentTimeline.delayNextStep(delay); + } + } + /** + * @param {?} selector + * @param {?} originalSelector + * @param {?} limit + * @param {?} includeSelf + * @param {?} optional + * @param {?} errors + * @return {?} + */ + invokeQuery(selector, originalSelector, limit, includeSelf, optional, errors) { + let /** @type {?} */ results = []; + if (includeSelf) { + results.push(this.element); + } + if (selector.length > 0) { + const /** @type {?} */ multi = limit != 1; + let /** @type {?} */ elements = this._driver.query(this.element, selector, multi); + if (limit !== 0) { + elements = elements.slice(0, limit); + } + results.push(...elements); + } + if (!optional && results.length == 0) { + errors.push(`\`query("${originalSelector}")\` returned zero elements. (Use \`query("${originalSelector}", { optional: true })\` if you wish to allow this.)`); + } + return results; + } +} +class TimelineBuilder { + /** + * @param {?} element + * @param {?} startTime + * @param {?=} _elementTimelineStylesLookup + */ + constructor(element, startTime, _elementTimelineStylesLookup) { + this.element = element; + this.startTime = startTime; + this._elementTimelineStylesLookup = _elementTimelineStylesLookup; + this.duration = 0; + this._previousKeyframe = {}; + this._currentKeyframe = {}; + this._keyframes = new Map(); + this._styleSummary = {}; + this._pendingStyles = {}; + this._backFill = {}; + this._currentEmptyStepKeyframe = null; + if (!this._elementTimelineStylesLookup) { + this._elementTimelineStylesLookup = new Map(); + } + this._localTimelineStyles = Object.create(this._backFill, {}); + this._globalTimelineStyles = this._elementTimelineStylesLookup.get(element); + if (!this._globalTimelineStyles) { + this._globalTimelineStyles = this._localTimelineStyles; + this._elementTimelineStylesLookup.set(element, this._localTimelineStyles); + } + this._loadKeyframe(); + } + /** + * @return {?} + */ + containsAnimation() { + switch (this._keyframes.size) { + case 0: + return false; + case 1: + return this.getCurrentStyleProperties().length > 0; + default: + return true; + } + } + /** + * @return {?} + */ + getCurrentStyleProperties() { return Object.keys(this._currentKeyframe); } + /** + * @return {?} + */ + get currentTime() { return this.startTime + this.duration; } + /** + * @param {?} delay + * @return {?} + */ + delayNextStep(delay) { + // in the event that a style() step is placed right before a stagger() + // and that style() step is the very first style() value in the animation + // then we need to make a copy of the keyframe [0, copy, 1] so that the delay + // properly applies the style() values to work with the stagger... + const /** @type {?} */ hasPreStyleStep = this._keyframes.size == 1 && Object.keys(this._pendingStyles).length; + if (this.duration || hasPreStyleStep) { + this.forwardTime(this.currentTime + delay); + if (hasPreStyleStep) { + this.snapshotCurrentStyles(); + } + } + else { + this.startTime += delay; + } + } + /** + * @param {?} element + * @param {?=} currentTime + * @return {?} + */ + fork(element, currentTime) { + this.applyStylesToKeyframe(); + return new TimelineBuilder(element, currentTime || this.currentTime, this._elementTimelineStylesLookup); + } + /** + * @return {?} + */ + _loadKeyframe() { + if (this._currentKeyframe) { + this._previousKeyframe = this._currentKeyframe; + } + this._currentKeyframe = ((this._keyframes.get(this.duration))); + if (!this._currentKeyframe) { + this._currentKeyframe = Object.create(this._backFill, {}); + this._keyframes.set(this.duration, this._currentKeyframe); + } + } + /** + * @return {?} + */ + forwardFrame() { + this.duration += ONE_FRAME_IN_MILLISECONDS; + this._loadKeyframe(); + } + /** + * @param {?} time + * @return {?} + */ + forwardTime(time) { + this.applyStylesToKeyframe(); + this.duration = time; + this._loadKeyframe(); + } + /** + * @param {?} prop + * @param {?} value + * @return {?} + */ + _updateStyle(prop, value) { + this._localTimelineStyles[prop] = value; + this._globalTimelineStyles[prop] = value; + this._styleSummary[prop] = { time: this.currentTime, value }; + } + /** + * @return {?} + */ + allowOnlyTimelineStyles() { return this._currentEmptyStepKeyframe !== this._currentKeyframe; } + /** + * @param {?} easing + * @return {?} + */ + applyEmptyStep(easing) { + if (easing) { + this._previousKeyframe['easing'] = easing; + } + // special case for animate(duration): + // all missing styles are filled with a `*` value then + // if any destination styles are filled in later on the same + // keyframe then they will override the overridden styles + // We use `_globalTimelineStyles` here because there may be + // styles in previous keyframes that are not present in this timeline + Object.keys(this._globalTimelineStyles).forEach(prop => { + this._backFill[prop] = this._globalTimelineStyles[prop] || AUTO_STYLE; + this._currentKeyframe[prop] = AUTO_STYLE; + }); + this._currentEmptyStepKeyframe = this._currentKeyframe; + } + /** + * @param {?} input + * @param {?} easing + * @param {?} errors + * @param {?=} options + * @return {?} + */ + setStyles(input, easing, errors, options) { + if (easing) { + this._previousKeyframe['easing'] = easing; + } + const /** @type {?} */ params = (options && options.params) || {}; + const /** @type {?} */ styles = flattenStyles(input, this._globalTimelineStyles); + Object.keys(styles).forEach(prop => { + const /** @type {?} */ val = interpolateParams(styles[prop], params, errors); + this._pendingStyles[prop] = val; + if (!this._localTimelineStyles.hasOwnProperty(prop)) { + this._backFill[prop] = this._globalTimelineStyles.hasOwnProperty(prop) ? + this._globalTimelineStyles[prop] : + AUTO_STYLE; + } + this._updateStyle(prop, val); + }); + } + /** + * @return {?} + */ + applyStylesToKeyframe() { + const /** @type {?} */ styles = this._pendingStyles; + const /** @type {?} */ props = Object.keys(styles); + if (props.length == 0) + return; + this._pendingStyles = {}; + props.forEach(prop => { + const /** @type {?} */ val = styles[prop]; + this._currentKeyframe[prop] = val; + }); + Object.keys(this._localTimelineStyles).forEach(prop => { + if (!this._currentKeyframe.hasOwnProperty(prop)) { + this._currentKeyframe[prop] = this._localTimelineStyles[prop]; + } + }); + } + /** + * @return {?} + */ + snapshotCurrentStyles() { + Object.keys(this._localTimelineStyles).forEach(prop => { + const /** @type {?} */ val = this._localTimelineStyles[prop]; + this._pendingStyles[prop] = val; + this._updateStyle(prop, val); + }); + } + /** + * @return {?} + */ + getFinalKeyframe() { return this._keyframes.get(this.duration); } + /** + * @return {?} + */ + get properties() { + const /** @type {?} */ properties = []; + for (let /** @type {?} */ prop in this._currentKeyframe) { + properties.push(prop); + } + return properties; + } + /** + * @param {?} timeline + * @return {?} + */ + mergeTimelineCollectedStyles(timeline) { + Object.keys(timeline._styleSummary).forEach(prop => { + const /** @type {?} */ details0 = this._styleSummary[prop]; + const /** @type {?} */ details1 = timeline._styleSummary[prop]; + if (!details0 || details1.time > details0.time) { + this._updateStyle(prop, details1.value); + } + }); + } + /** + * @return {?} + */ + buildKeyframes() { + this.applyStylesToKeyframe(); + const /** @type {?} */ preStyleProps = new Set(); + const /** @type {?} */ postStyleProps = new Set(); + const /** @type {?} */ isEmpty = this._keyframes.size === 1 && this.duration === 0; + let /** @type {?} */ finalKeyframes = []; + this._keyframes.forEach((keyframe, time) => { + const /** @type {?} */ finalKeyframe = copyStyles(keyframe, true); + Object.keys(finalKeyframe).forEach(prop => { + const /** @type {?} */ value = finalKeyframe[prop]; + if (value == ɵPRE_STYLE) { + preStyleProps.add(prop); + } + else if (value == AUTO_STYLE) { + postStyleProps.add(prop); + } + }); + if (!isEmpty) { + finalKeyframe['offset'] = time / this.duration; + } + finalKeyframes.push(finalKeyframe); + }); + const /** @type {?} */ preProps = preStyleProps.size ? iteratorToArray(preStyleProps.values()) : []; + const /** @type {?} */ postProps = postStyleProps.size ? iteratorToArray(postStyleProps.values()) : []; + // special case for a 0-second animation (which is designed just to place styles onscreen) + if (isEmpty) { + const /** @type {?} */ kf0 = finalKeyframes[0]; + const /** @type {?} */ kf1 = copyObj(kf0); + kf0['offset'] = 0; + kf1['offset'] = 1; + finalKeyframes = [kf0, kf1]; + } + return createTimelineInstruction(this.element, finalKeyframes, preProps, postProps, this.duration, this.startTime, this.easing, false); + } +} +class SubTimelineBuilder extends TimelineBuilder { + /** + * @param {?} element + * @param {?} keyframes + * @param {?} preStyleProps + * @param {?} postStyleProps + * @param {?} timings + * @param {?=} _stretchStartingKeyframe + */ + constructor(element, keyframes, preStyleProps, postStyleProps, timings, _stretchStartingKeyframe = false) { + super(element, timings.delay); + this.element = element; + this.keyframes = keyframes; + this.preStyleProps = preStyleProps; + this.postStyleProps = postStyleProps; + this._stretchStartingKeyframe = _stretchStartingKeyframe; + this.timings = { duration: timings.duration, delay: timings.delay, easing: timings.easing }; + } + /** + * @return {?} + */ + containsAnimation() { return this.keyframes.length > 1; } + /** + * @return {?} + */ + buildKeyframes() { + let /** @type {?} */ keyframes = this.keyframes; + let { delay, duration, easing } = this.timings; + if (this._stretchStartingKeyframe && delay) { + const /** @type {?} */ newKeyframes = []; + const /** @type {?} */ totalTime = duration + delay; + const /** @type {?} */ startingGap = delay / totalTime; + // the original starting keyframe now starts once the delay is done + const /** @type {?} */ newFirstKeyframe = copyStyles(keyframes[0], false); + newFirstKeyframe['offset'] = 0; + newKeyframes.push(newFirstKeyframe); + const /** @type {?} */ oldFirstKeyframe = copyStyles(keyframes[0], false); + oldFirstKeyframe['offset'] = roundOffset(startingGap); + newKeyframes.push(oldFirstKeyframe); + /* + When the keyframe is stretched then it means that the delay before the animation + starts is gone. Instead the first keyframe is placed at the start of the animation + and it is then copied to where it starts when the original delay is over. This basically + means nothing animates during that delay, but the styles are still renderered. For this + to work the original offset values that exist in the original keyframes must be "warped" + so that they can take the new keyframe + delay into account. + + delay=1000, duration=1000, keyframes = 0 .5 1 + + turns into + + delay=0, duration=2000, keyframes = 0 .33 .66 1 + */ + // offsets between 1 ... n -1 are all warped by the keyframe stretch + const /** @type {?} */ limit = keyframes.length - 1; + for (let /** @type {?} */ i = 1; i <= limit; i++) { + let /** @type {?} */ kf = copyStyles(keyframes[i], false); + const /** @type {?} */ oldOffset = (kf['offset']); + const /** @type {?} */ timeAtKeyframe = delay + oldOffset * duration; + kf['offset'] = roundOffset(timeAtKeyframe / totalTime); + newKeyframes.push(kf); + } + // the new starting keyframe should be added at the start + duration = totalTime; + delay = 0; + easing = ''; + keyframes = newKeyframes; + } + return createTimelineInstruction(this.element, keyframes, this.preStyleProps, this.postStyleProps, duration, delay, easing, true); + } +} +/** + * @param {?} offset + * @param {?=} decimalPoints + * @return {?} + */ +function roundOffset(offset, decimalPoints = 3) { + const /** @type {?} */ mult = Math.pow(10, decimalPoints - 1); + return Math.round(offset * mult) / mult; +} +/** + * @param {?} input + * @param {?} allStyles + * @return {?} + */ +function flattenStyles(input, allStyles) { + const /** @type {?} */ styles = {}; + let /** @type {?} */ allProperties; + input.forEach(token => { + if (token === '*') { + allProperties = allProperties || Object.keys(allStyles); + allProperties.forEach(prop => { styles[prop] = AUTO_STYLE; }); + } + else { + copyStyles(/** @type {?} */ (token), false, styles); + } + }); + return styles; +} + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +class Animation { + /** + * @param {?} _driver + * @param {?} input + */ + constructor(_driver, input) { + this._driver = _driver; + const errors = []; + const ast = buildAnimationAst(input, errors); + if (errors.length) { + const errorMessage = `animation validation failed:\n${errors.join("\n")}`; + throw new Error(errorMessage); + } + this._animationAst = ast; + } + /** + * @param {?} element + * @param {?} startingStyles + * @param {?} destinationStyles + * @param {?} options + * @param {?=} subInstructions + * @return {?} + */ + buildTimelines(element, startingStyles, destinationStyles, options, subInstructions) { + const /** @type {?} */ start = Array.isArray(startingStyles) ? normalizeStyles(startingStyles) : (startingStyles); + const /** @type {?} */ dest = Array.isArray(destinationStyles) ? normalizeStyles(destinationStyles) : (destinationStyles); + const /** @type {?} */ errors = []; + subInstructions = subInstructions || new ElementInstructionMap(); + const /** @type {?} */ result = buildAnimationTimelines(this._driver, element, this._animationAst, start, dest, options, subInstructions, errors); + if (errors.length) { + const /** @type {?} */ errorMessage = `animation building failed:\n${errors.join("\n")}`; + throw new Error(errorMessage); + } + return result; + } +} + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +/** + * @experimental Animation support is experimental. + */ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ class AnimationStyleNormalizer { +} +/** + * @experimental Animation support is experimental. + */ +class NoopAnimationStyleNormalizer { + normalizePropertyName(propertyName, errors) { return propertyName; } + normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) { + return value; + } +} + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer { + /** + * @param {?} propertyName + * @param {?} errors + * @return {?} + */ + normalizePropertyName(propertyName, errors) { + return dashCaseToCamelCase(propertyName); + } + /** + * @param {?} userProvidedProperty + * @param {?} normalizedProperty + * @param {?} value + * @param {?} errors + * @return {?} + */ + normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) { + let /** @type {?} */ unit = ''; + const /** @type {?} */ strVal = value.toString().trim(); + if (DIMENSIONAL_PROP_MAP[normalizedProperty] && value !== 0 && value !== '0') { + if (typeof value === 'number') { + unit = 'px'; + } + else { + const /** @type {?} */ valAndSuffixMatch = value.match(/^[+-]?[\d\.]+([a-z]*)$/); + if (valAndSuffixMatch && valAndSuffixMatch[1].length == 0) { + errors.push(`Please provide a CSS unit value for ${userProvidedProperty}:${value}`); + } + } + } + return strVal + unit; + } +} +const DIMENSIONAL_PROP_MAP = makeBooleanMap('width,height,minWidth,minHeight,maxWidth,maxHeight,left,top,bottom,right,fontSize,outlineWidth,outlineOffset,paddingTop,paddingLeft,paddingBottom,paddingRight,marginTop,marginLeft,marginBottom,marginRight,borderRadius,borderWidth,borderTopWidth,borderLeftWidth,borderRightWidth,borderBottomWidth,textIndent,perspective' + .split(',')); +/** + * @param {?} keys + * @return {?} + */ +function makeBooleanMap(keys) { + const /** @type {?} */ map = {}; + keys.forEach(key => map[key] = true); + return map; +} + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +/** + * @param {?} element + * @param {?} triggerName + * @param {?} fromState + * @param {?} toState + * @param {?} isRemovalTransition + * @param {?} fromStyles + * @param {?} toStyles + * @param {?} timelines + * @param {?} queriedElements + * @param {?} preStyleProps + * @param {?} postStyleProps + * @param {?=} errors + * @return {?} + */ +function createTransitionInstruction(element, triggerName, fromState, toState, isRemovalTransition, fromStyles, toStyles, timelines, queriedElements, preStyleProps, postStyleProps, errors) { + return { + type: 0 /* TransitionAnimation */, + element, + triggerName, + isRemovalTransition, + fromState, + fromStyles, + toState, + toStyles, + timelines, + queriedElements, + preStyleProps, + postStyleProps, + errors + }; +} + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +const EMPTY_OBJECT = {}; +class AnimationTransitionFactory { + /** + * @param {?} _triggerName + * @param {?} ast + * @param {?} _stateStyles + */ + constructor(_triggerName, ast, _stateStyles) { + this._triggerName = _triggerName; + this.ast = ast; + this._stateStyles = _stateStyles; + } + /** + * @param {?} currentState + * @param {?} nextState + * @return {?} + */ + match(currentState, nextState) { + return oneOrMoreTransitionsMatch(this.ast.matchers, currentState, nextState); + } + /** + * @param {?} stateName + * @param {?} params + * @param {?} errors + * @return {?} + */ + buildStyles(stateName, params, errors) { + const /** @type {?} */ backupStateStyler = this._stateStyles['*']; + const /** @type {?} */ stateStyler = this._stateStyles[stateName]; + const /** @type {?} */ backupStyles = backupStateStyler ? backupStateStyler.buildStyles(params, errors) : {}; + return stateStyler ? stateStyler.buildStyles(params, errors) : backupStyles; + } + /** + * @param {?} driver + * @param {?} element + * @param {?} currentState + * @param {?} nextState + * @param {?=} currentOptions + * @param {?=} nextOptions + * @param {?=} subInstructions + * @return {?} + */ + build(driver, element, currentState, nextState, currentOptions, nextOptions, subInstructions) { + const /** @type {?} */ errors = []; + const /** @type {?} */ transitionAnimationParams = this.ast.options && this.ast.options.params || EMPTY_OBJECT; + const /** @type {?} */ currentAnimationParams = currentOptions && currentOptions.params || EMPTY_OBJECT; + const /** @type {?} */ currentStateStyles = this.buildStyles(currentState, currentAnimationParams, errors); + const /** @type {?} */ nextAnimationParams = nextOptions && nextOptions.params || EMPTY_OBJECT; + const /** @type {?} */ nextStateStyles = this.buildStyles(nextState, nextAnimationParams, errors); + const /** @type {?} */ queriedElements = new Set(); + const /** @type {?} */ preStyleMap = new Map(); + const /** @type {?} */ postStyleMap = new Map(); + const /** @type {?} */ isRemoval = nextState === 'void'; + const /** @type {?} */ animationOptions = { params: Object.assign({}, transitionAnimationParams, nextAnimationParams) }; + const /** @type {?} */ timelines = buildAnimationTimelines(driver, element, this.ast.animation, currentStateStyles, nextStateStyles, animationOptions, subInstructions, errors); + if (errors.length) { + return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, [], [], preStyleMap, postStyleMap, errors); + } + timelines.forEach(tl => { + const /** @type {?} */ elm = tl.element; + const /** @type {?} */ preProps = getOrSetAsInMap(preStyleMap, elm, {}); + tl.preStyleProps.forEach(prop => preProps[prop] = true); + const /** @type {?} */ postProps = getOrSetAsInMap(postStyleMap, elm, {}); + tl.postStyleProps.forEach(prop => postProps[prop] = true); + if (elm !== element) { + queriedElements.add(elm); + } + }); + const /** @type {?} */ queriedElementsList = iteratorToArray(queriedElements.values()); + return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, timelines, queriedElementsList, preStyleMap, postStyleMap); + } +} +/** + * @param {?} matchFns + * @param {?} currentState + * @param {?} nextState + * @return {?} + */ +function oneOrMoreTransitionsMatch(matchFns, currentState, nextState) { + return matchFns.some(fn => fn(currentState, nextState)); +} +class AnimationStateStyles { + /** + * @param {?} styles + * @param {?} defaultParams + */ + constructor(styles, defaultParams) { + this.styles = styles; + this.defaultParams = defaultParams; + } + /** + * @param {?} params + * @param {?} errors + * @return {?} + */ + buildStyles(params, errors) { + const /** @type {?} */ finalStyles = {}; + const /** @type {?} */ combinedParams = copyObj(this.defaultParams); + Object.keys(params).forEach(key => { + const /** @type {?} */ value = params[key]; + if (value != null) { + combinedParams[key] = value; + } + }); + this.styles.styles.forEach(value => { + if (typeof value !== 'string') { + const /** @type {?} */ styleObj = (value); + Object.keys(styleObj).forEach(prop => { + let /** @type {?} */ val = styleObj[prop]; + if (val.length > 1) { + val = interpolateParams(val, combinedParams, errors); + } + finalStyles[prop] = val; + }); + } + }); + return finalStyles; + } +} + +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ +/** + * \@experimental Animation support is experimental. + * @param {?} name + * @param {?} ast + * @return {?} + */ +function buildTrigger(name, ast) { + return new AnimationTrigger(name, ast); +} +/** + * \@experimental Animation support is experimental. + */ +class AnimationTrigger { + /** + * @param {?} name + * @param {?} ast + */ + constructor(name, ast) { + this.name = name; + this.ast = ast; + this.transitionFactories = []; + this.states = {}; + ast.states.forEach(ast => { + const defaultParams = (ast.options && ast.options.params) || {}; + this.states[ast.name] = new AnimationStateStyles(ast.style, defaultParams); + }); + balanceProperties(this.states, 'true', '1'); + balanceProperties(this.states, 'false', '0'); + ast.transitions.forEach(ast => { + this.transitio
<TRUNCATED>
