Show:
                            /**
                             * The Scrollspy Component
                             *
                             * @module aui-scrollspy
                             */
                            
                            var getClassName = A.getClassName,
                                Lang = A.Lang,
                            
                                ACTIVATE_EVENT = 'activate';
                            
                            /**
                             * A base class for Scrollspy.
                             *
                             * Check the [live demo](http://alloyui.com/examples/scrollspy/).
                             *
                             * @class A.Scrollspy
                             * @extends Base
                             * @param {Object} config Object literal specifying scrollspy configuration
                             *     properties.
                             * @constructor
                             * @example
                            ```
                            <div id="myNavbar" class="navbar navbar-default">
                              <ul class="nav navbar-nav">
                                <li><a href="#first">First</a></li>
                                <li><a href="#second">Second</a></li>
                                <li><a href="#third">Third</a></li>
                              </ul>
                            </div>
                            
                            <div id="myScrollNode" style="overflow-y: scroll; height: 300px">
                              <h4 id="first">First</h4>
                              <p>Etiam nulla eruditi eu quo, facer postulant an mea. Eos at legimus deseruisse adipiscing. Amet iriure torquatos ex mei. Sumo purto propriae nam ne, eam ferri diceret deseruisse ea, cum ubique constituam suscipiantur an. Alii brute legendos ut pri, epicuri voluptaria contentiones an eos. Pri ut feugiat ornatus consequuntur, ubique euismod patrioque id duo. Etiam nulla eruditi eu quo, facer postulant an mea. Eos at legimus deseruisse adipiscing. Amet iriure torquatos ex mei. Sumo purto propriae nam ne, eam ferri diceret deseruisse ea, cum ubique constituam suscipiantur an. Alii brute legendos ut pri, epicuri voluptaria contentiones an eos. Pri ut feugiat ornatus consequuntur, ubique euismod patrioque id duo. Etiam nulla eruditi eu quo, facer postulant an mea. Eos at legimus deseruisse adipiscing. Amet iriure torquatos ex mei. Sumo purto propriae nam ne, eam ferri diceret deseruisse ea, cum ubique constituam suscipiantur an. Alii brute legendos ut pri, epicuri voluptaria contentiones an eos. Pri ut feugiat ornatus consequuntur, ubique euismod patrioque id duo.</p>
                            
                              <h4 id="second">Second</h4>
                              <p>Pri ea diam persius dissentias, simul assentior ut sed. An illum hendrerit ius, pri aeterno nominati delicata at. Usu fugit facer et, nec in vivendo appellantur interpretaris. Petentium euripidis te vim, ex minimum appareat eam. Etiam nulla eruditi eu quo, facer postulant an mea. Eos at legimus deseruisse adipiscing. Amet iriure torquatos ex mei. Sumo purto propriae nam ne, eam ferri diceret deseruisse ea, cum ubique constituam suscipiantur an. Alii brute legendos ut pri, epicuri voluptaria contentiones an eos. Pri ut feugiat ornatus consequuntur, ubique euismod patrioque id duo. Etiam nulla eruditi eu quo, facer postulant an mea. Eos at legimus deseruisse adipiscing. Amet iriure torquatos ex mei. Sumo purto propriae nam ne, eam ferri diceret deseruisse ea, cum ubique constituam suscipiantur an. Alii brute legendos ut pri, epicuri voluptaria contentiones an eos. Pri ut feugiat ornatus consequuntur, ubique euismod patrioque id duo.</p>
                            
                              <h4 id="third">Third</h4>
                              <p>Etiam nulla eruditi eu quo, facer postulant an mea. Eos at legimus deseruisse adipiscing. Amet iriure torquatos ex mei. Sumo purto propriae nam ne, eam ferri diceret deseruisse ea, cum ubique constituam suscipiantur an. Alii brute legendos ut pri, epicuri voluptaria contentiones an eos. Pri ut feugiat ornatus consequuntur, ubique euismod patrioque id duo. Etiam nulla eruditi eu quo, facer postulant an mea. Eos at legimus deseruisse adipiscing. Amet iriure torquatos ex mei. Sumo purto propriae nam ne, eam ferri diceret deseruisse ea, cum ubique constituam suscipiantur an. Alii brute legendos ut pri, epicuri voluptaria contentiones an eos. Pri ut feugiat ornatus consequuntur, ubique euismod patrioque id duo. Etiam nulla eruditi eu quo, facer postulant an mea. Eos at legimus deseruisse adipiscing. Amet iriure torquatos ex mei. Sumo purto propriae nam ne, eam ferri diceret deseruisse ea, cum ubique constituam suscipiantur an. Alii brute legendos ut pri, epicuri voluptaria contentiones an eos. Pri ut feugiat ornatus consequuntur, ubique euismod patrioque id duo. Pri ea diam persius dissentias, simul assentior ut sed. An illum hendrerit ius, pri aeterno nominati delicata at. Usu fugit facer et, nec in vivendo appellantur interpretaris. Petentium euripidis te vim, ex minimum appareat eam. Etiam nulla eruditi eu quo, facer postulant an mea.</p>
                            </div>
                            ```
                             * @example
                            ```
                            YUI().use(
                              'aui-scrollspy',
                              function(Y) {
                                new Y.Scrollspy(
                                  {
                                    scrollNode: '#myScrollNode',
                                    target: '#myNavbar'
                                  }
                                );
                              }
                            );
                            ```
                             */
                            A.Scrollspy = A.Base.create('scrollspy', A.Base, [], {
                            
                                /**
                                 * Holds the active link node reference.
                                 *
                                 * @property activeLink
                                 * @type {Node}
                                 * @protected
                                 */
                                activeLink: null,
                            
                                /**
                                 * Holds a cache of the valid links.
                                 *
                                 * @property cachedLinks
                                 * @type {NodeList}
                                 * @protected
                                 */
                                cachedLinks: null,
                            
                                /**
                                 * Construction logic executed during Scrollspy instantiation. Lifecycle.
                                 *
                                 * @method initializer
                                 * @protected
                                 */
                                initializer: function() {
                                    var scrollNode = this.get('scrollNode');
                            
                                    /**
                                     * Fired when any target's link changes.
                                     *
                                     * @event activate
                                     * @param {EventFacade} event That activate link change event.
                                     */
                                    this.publish(ACTIVATE_EVENT, {
                                        defaultFn: this._defActivateEventFn
                                    });
                            
                                    scrollNode.on('scroll', A.bind(this._onScroll, this));
                                    this.refresh();
                                },
                            
                                /**
                                 * Cleans the cached links.
                                 *
                                 * @method clearCachedLinks
                                 */
                                clearCachedLinks: function() {
                                    this.cachedLinks = null;
                                },
                            
                                /**
                                 * Recalculates the current active node in the list and resets the active
                                 * CSS class names.
                                 *
                                 * @method refresh
                                 **/
                                refresh: function() {
                                    var link = this._findLinkBestMatch();
                            
                                    // Early return to avoid fire activate event when not necessary.
                                    // Event should be fired only when link is different from activeLink.
                                    if (link === this.activeLink || (!link && !this.activeLink)) {
                                        return;
                                    }
                            
                                    this.fire(ACTIVATE_EVENT, {
                                        newVal: link,
                                        prevVal: this.activeLink
                                    });
                                },
                            
                                /**
                                 * Handler function for scrollNode's scroll event.
                                 *
                                 * @method _defActivateEventFn
                                 * @param {EventFacade} event
                                 * @protected
                                 **/
                                _defActivateEventFn: function(event) {
                                    this._uiSetLink(event.newVal, event.prevVal);
                                },
                            
                                /**
                                 * Finds the node whose target should be activated.
                                 *
                                 * @method _findLinkBestMatch
                                 * @return {Node} Best link match that attends the viewport criteria.
                                 * @protected
                                 **/
                                _findLinkBestMatch: function() {
                                    var links = this._getValidLinks();
                            
                                    return links.filter(A.bind(this._isLinkInViewport, this)).pop();
                                },
                            
                                /**
                                 * Gets target ids from target links.
                                 *
                                 * @method _getValidLinks
                                 * @return {NodeList} Filtered cached links.
                                 * @protected
                                 **/
                                _getValidLinks: function() {
                                    if (!this.cachedLinks) {
                                        this.cachedLinks = this.get('target').all('a');
                                    }
                            
                                    this.cachedLinks = this.cachedLinks.filter(function(link) {
                                        return link.hash && (link.hash.length > 1);
                                    });
                            
                                    return this.cachedLinks;
                                },
                            
                                /**
                                 * Checks if there's a link corresponding to an anchor in the viewport.
                                 *
                                 * @method _isLinkInViewport
                                 * @param {Node} link
                                 * @return {Boolean} Whether link is in viewport.
                                 * @protected
                                 **/
                                _isLinkInViewport: function(link) {
                                    var offset = this.get('offset'),
                                        scrollNode = this.get('scrollNode'),
                                        scrollNodeY,
                                        anchor = A.one(link.hash);
                            
                                    if (scrollNode.compareTo(A.config.win) || scrollNode.compareTo(A.config.doc)) {
                                        scrollNodeY = scrollNode.get('scrollTop');
                                    }
                                    else {
                                        scrollNodeY = scrollNode.getY();
                                    }
                                    return (anchor && (scrollNodeY >= (anchor.getY() - offset)));
                                },
                            
                                /**
                                 * Call refresh on scroll event from scrollNode.
                                 *
                                 * @method _onScroll
                                 * @protected
                                 **/
                                _onScroll: function() {
                                    this.refresh();
                                },
                            
                                /**
                                 * Sets correct class to active node.
                                 *
                                 * @method _uiSetLink
                                 * @param {Node} val
                                 * @param {Node} prevVal
                                 * @protected
                                 **/
                                _uiSetLink: function(val, prevVal) {
                                    var activeGroup = this.get('activeGroup');
                                    var activeClass = this.get('activeClass');
                            
                                    // For the first time it gets here make sure to clean the previous active
                                    if (!prevVal) {
                                      this._getValidLinks().filter(function(link) {
                                        return A.one(link).ancestors(activeGroup).removeClass(activeClass);
                                      });
                                    }
                            
                                    if (prevVal) {
                                        prevVal.ancestors(activeGroup).removeClass(activeClass);
                                        this.activeLink = null;
                                    }
                            
                                    if (val) {
                                        val.ancestors(activeGroup).addClass(activeClass);
                                        this.activeLink = val;
                                    }
                                }
                            }, {
                                /**
                                 * Static property used to define the default attribute
                                 * configuration for the Scrollspy.
                                 *
                                 * @property ATTRS
                                 * @type Object
                                 * @static
                                 */
                                ATTRS: {
                                    /**
                                     * Ancestors which should be added the .active class.
                                     *
                                     * @attribute activeGroup
                                     * @type {String}
                                     */
                                    activeGroup: {
                                        validator: Lang.isString,
                                        value: 'li, .dropdown'
                                    },
                            
                                    /**
                                     * Class to be used as active class.
                                     *
                                     * @attribute activeClass
                                     * @type {String}
                                     */
                                    activeClass: {
                                      validator: Lang.isString,
                                      value: getClassName('active')
                                    },
                            
                                    /**
                                     * Pixels to offset from top when calculating position of scroll.
                                     *
                                     * @attribute offset
                                     * @type {Number}
                                     */
                                    offset: {
                                        validator: Lang.isNumber,
                                        value: 10
                                    },
                            
                                    /**
                                     * Container that maps target links.
                                     *
                                     * @attribute scrollNode
                                     * @type {Node | String}
                                     * @initOnly
                                     */
                                    scrollNode: {
                                        setter: A.one,
                                        value: A.config.win,
                                        writeOnce: 'initOnly'
                                    },
                            
                                    /**
                                     * Target list. Usually a nav bar element with anchors.
                                     *
                                     * @attribute target
                                     * @type {Node | String}
                                     * @initOnly
                                     */
                                    target: {
                                        setter: A.one,
                                        writeOnce: 'initOnly'
                                    }
                                }
                            });