text: /**
     * `Polymer.NeonAnimatableBehavior` is implemented by elements containing animations for use with
     * elements implementing `Polymer.NeonAnimationRunnerBehavior`.
     * @polymerBehavior
     */
    Polymer.NeonAnimatableBehavior = {
  
      properties: {
  
        /**
         * Animation configuration. See README for more info.
         */
        animationConfig: {
          type: Object
        },
  
        /**
         * Convenience property for setting an 'entry' animation. Do not set `animationConfig.entry`
         * manually if using this. The animated node is set to `this` if using this property.
         */
        entryAnimation: {
          observer: '_entryAnimationChanged',
          type: String
        },
  
        /**
         * Convenience property for setting an 'exit' animation. Do not set `animationConfig.exit`
         * manually if using this. The animated node is set to `this` if using this property.
         */
        exitAnimation: {
          observer: '_exitAnimationChanged',
          type: String
        }
  
      },
  
      _entryAnimationChanged: function() {
        this.animationConfig = this.animationConfig || {};
        this.animationConfig['entry'] = [{
          name: this.entryAnimation,
          node: this
        }];
      },
  
      _exitAnimationChanged: function() {
        this.animationConfig = this.animationConfig || {};
        this.animationConfig['exit'] = [{
          name: this.exitAnimation,
          node: this
        }];
      },
  
      _copyProperties: function(config1, config2) {
        // shallowly copy properties from config2 to config1
        for (var property in config2) {
          config1[property] = config2[property];
        }
      },
  
      _cloneConfig: function(config) {
        var clone = {
          isClone: true
        };
        this._copyProperties(clone, config);
        return clone;
      },
  
      _getAnimationConfigRecursive: function(type, map, allConfigs) {
        if (!this.animationConfig) {
          return;
        }
  
        if(this.animationConfig.value && typeof this.animationConfig.value === 'function') {
        	this._warn(this._logf('playAnimation', "Please put 'animationConfig' inside of your components 'properties' object instead of outside of it."));
        	return;
        }
  
        // type is optional
        var thisConfig;
        if (type) {
          thisConfig = this.animationConfig[type];
        } else {
          thisConfig = this.animationConfig;
        }
  
        if (!Array.isArray(thisConfig)) {
          thisConfig = [thisConfig];
        }
  
        // iterate animations and recurse to process configurations from child nodes
        if (thisConfig) {
          for (var config, index = 0; config = thisConfig[index]; index++) {
            if (config.animatable) {
              config.animatable._getAnimationConfigRecursive(config.type || type, map, allConfigs);
            } else {
              if (config.id) {
                var cachedConfig = map[config.id];
                if (cachedConfig) {
                  // merge configurations with the same id, making a clone lazily
                  if (!cachedConfig.isClone) {
                    map[config.id] = this._cloneConfig(cachedConfig)
                    cachedConfig = map[config.id];
                  }
                  this._copyProperties(cachedConfig, config);
                } else {
                  // put any configs with an id into a map
                  map[config.id] = config;
                }
              } else {
                allConfigs.push(config);
              }
            }
          }
        }
      },
  
      /**
       * An element implementing `Polymer.NeonAnimationRunnerBehavior` calls this method to configure
       * an animation with an optional type. Elements implementing `Polymer.NeonAnimatableBehavior`
       * should define the property `animationConfig`, which is either a configuration object
       * or a map of animation type to array of configuration objects.
       */
      getAnimationConfig: function(type) {
        var map = {};
        var allConfigs = [];
        this._getAnimationConfigRecursive(type, map, allConfigs);
        // append the configurations saved in the map to the array
        for (var key in map) {
          allConfigs.push(map[key]);
        }
        return allConfigs;
      }
  
    };