Show:
                            /**
                             * The Affix Component
                             *
                             * @module aui-affix
                             */
                            
                            var win = A.config.win;
                            
                            /**
                             * A base class for Affix.
                             *
                             * Check the [live demo](http://alloyui.com/examples/affix/).
                             *
                             * @class A.Affix
                             * @extends Base
                             * @param {Object} config Object literal specifying scrollspy configuration
                             *     properties.
                             * @constructor
                             * @example
                            ```
                            <style>
                            .navbar.affix {
                              top: 60px;
                              width: 675px;
                              z-index: 200;
                            }
                            </style>
                            
                            <div id="myAffix" class="navbar navbar-default">
                              <ul class="nav navbar-nav">
                                <li><a href="#">Item 1</a></li>
                                <li><a href="#">Item 2</a></li>
                                <li><a href="#">Item 3</a></li>
                              </ul>
                            </div>
                            
                            <article>
                              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tenetur labore dicta quas ab nesciunt dolorum non ipsum facilis cum, nam qui autem ducimus cupiditate quibusdam sunt excepturi accusantium doloribus, libero esse quam. Quidem harum dolorum vero nulla, eius, officiis saepe voluptate similique corporis vel id perferendis? Dicta deserunt, voluptatum repellendus voluptates, aut, asperiores fugiat laudantium dolorem consectetur sunt mollitia. Veritatis quisquam placeat harum, perferendis soluta eius nihil veniam totam sint. Suscipit, voluptates, possimus! Accusamus modi eaque, eius nisi saepe iusto repellat qui ipsam molestiae sunt impedit reiciendis velit nostrum sint odio omnis repellendus culpa voluptatum quam eveniet numquam quod placeat.</p>
                              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tenetur labore dicta quas ab nesciunt dolorum non ipsum facilis cum, nam qui autem ducimus cupiditate quibusdam sunt excepturi accusantium doloribus, libero esse quam. Quidem harum dolorum vero nulla, eius, officiis saepe voluptate similique corporis vel id perferendis? Dicta deserunt, voluptatum repellendus voluptates, aut, asperiores fugiat laudantium dolorem consectetur sunt mollitia. Veritatis quisquam placeat harum, perferendis soluta eius nihil veniam totam sint. Suscipit, voluptates, possimus! Accusamus modi eaque, eius nisi saepe iusto repellat qui ipsam molestiae sunt impedit reiciendis velit nostrum sint odio omnis repellendus culpa voluptatum quam eveniet numquam quod placeat.</p>
                              <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tenetur labore dicta quas ab nesciunt dolorum non ipsum facilis cum, nam qui autem ducimus cupiditate quibusdam sunt excepturi accusantium doloribus, libero esse quam. Quidem harum dolorum vero nulla, eius, officiis saepe voluptate similique corporis vel id perferendis? Dicta deserunt, voluptatum repellendus voluptates, aut, asperiores fugiat laudantium dolorem consectetur sunt mollitia. Veritatis quisquam placeat harum, perferendis soluta eius nihil veniam totam sint. Suscipit, voluptates, possimus! Accusamus modi eaque, eius nisi saepe iusto repellat qui ipsam molestiae sunt impedit reiciendis velit nostrum sint odio omnis repellendus culpa voluptatum quam eveniet numquam quod placeat.</p>
                            </article>
                            ```
                             * @example
                            ```
                            YUI().use(
                              'aui-affix',
                              function(Y) {
                                new Y.Affix(
                                  {
                                    target: '#myAffix',
                                    offsetTop: 250
                                  }
                                );
                              }
                            );
                            ```
                             */
                            A.Affix = A.Base.create('affix', A.Base, [], {
                                /**
                                 * Holds the scroll event handle.
                                 *
                                 * @type {Node}
                                 * @private
                                 */
                                _eventHandle: null,
                            
                                /**
                                 * Holds the last event (bottom, default, top).
                                 * @type {String}
                                 * @private
                                 */
                                _lastPosition: null,
                            
                                /**
                                 * Constructor for the Affix component.
                                 *
                                 * @method initializer
                                 * @protected
                                 */
                                initializer: function() {
                                    this.publish({
                                        bottom: {
                                            defaultFn: this._defAffixBottomFn
                                        },
                                        'default': {
                                            defaultFn: this._defAffixFn
                                        },
                                        top: {
                                            defaultFn: this._defAffixTopFn
                                        }
                                    });
                            
                                    this.after({
                                        offsetBottomChange: this._afterOffsetChange,
                                        offsetTopChange: this._afterOffsetChange
                                    });
                            
                                    this.refresh();
                                    this._eventHandle = A.one(win).on('scroll', this._onScroll, this);
                                },
                            
                                /**
                                 * Destructor for the Affix component
                                 * @method destructor
                                 * @private
                                 */
                                destructor: function() {
                                    this._eventHandle.detach();
                                },
                            
                                /**
                                 * Refreshes the affix component to its current state.
                                 *
                                 * @method refresh
                                 */
                                refresh: function() {
                                    var scrollY = A.DOM.docScrollY(),
                                        offsetBottom = this.get('offsetBottom'),
                                        offsetTop = this.get('offsetTop'),
                                        targetRegion;
                            
                                    if ((offsetTop >= 0) && (offsetTop >= scrollY)) {
                                        this._handleAffixEvent(A.Affix.EVENTS.TOP);
                                        return;
                                    }
                            
                                    targetRegion = this.get('target').get('region');
                            
                                    if ((offsetBottom >= 0) && ((A.DOM.docHeight() - A.DOM.winHeight() - offsetBottom) <= targetRegion.bottom)) {
                                        this._handleAffixEvent(A.Affix.EVENTS.BOTTOM);
                                        return;
                                    }
                            
                                    this._handleAffixEvent(A.Affix.EVENTS.DEFAULT);
                                },
                            
                                /**
                                 * Call the refresh method after changing the offset
                                 *
                                 * @method  _afterOffsetChange
                                 * @private
                                 */
                                _afterOffsetChange: function() {
                                    this.refresh();
                                },
                            
                                /**
                                 * Affix bottom position syncing callback function.
                                 *
                                 * @method _defAffixBottomFn
                                 * @private
                                 */
                                _defAffixBottomFn: function() {
                                    this._syncClassesUI(A.Affix.EVENTS.BOTTOM);
                                },
                            
                                /**
                                 * Affix default position syncing callback function.
                                 *
                                 * @method _defAffixFn
                                 * @private
                                 */
                                _defAffixFn: function() {
                                    this._syncClassesUI(A.Affix.EVENTS.DEFAULT);
                                },
                            
                                /**
                                 * Affix top position syncing callback function.
                                 *
                                 * @method _defAffixTopFn
                                 * @private
                                 */
                                _defAffixTopFn: function() {
                                    this._syncClassesUI(A.Affix.EVENTS.TOP);
                                },
                            
                                /**
                                 * Get the `offset` attribute.
                                 *
                                 * @method _getOffset
                                 * @param {Number | Number.NEGATIVE_INFINITY} val
                                 * @protected
                                 */
                                _getOffset: function(val) {
                                    if (A.Lang.isFunction(val)) {
                                        val = val.call(this);
                                    }
                                    return val;
                                },
                            
                                /**
                                 * Safeguard function for firing the affix change event only when necessary.
                                 *
                                 * @method _handleAffixEvent
                                 * @param {String} Position value, could be 'bottom', 'default' or 'top'.
                                 * @private
                                 */
                                _handleAffixEvent: function(position) {
                                    if (position !== this._lastPosition) {
                                        this.fire(position);
                                    }
                                },
                            
                                /**
                                 * Scroll event listener function.
                                 *
                                 * @method _onScroll
                                 * @private
                                 */
                                _onScroll: function() {
                                    this.refresh();
                                },
                            
                                /**
                                 * Sync the target element class based on the affix positioning.
                                 *
                                 * @method _syncClassesUI
                                 * @param {String} Position value, could be 'bottom', 'default' or 'top'.
                                 * @private
                                 */
                                _syncClassesUI: function(position) {
                                    var target = this.get('target');
                                    target.toggleClass(A.Affix.CSS_CLASSES.BOTTOM, position === A.Affix.EVENTS.BOTTOM);
                                    target.toggleClass(A.Affix.CSS_CLASSES.DEFAULT, position === A.Affix.EVENTS.DEFAULT);
                                    target.toggleClass(A.Affix.CSS_CLASSES.TOP, position === A.Affix.EVENTS.TOP);
                                    this._lastPosition = position;
                                },
                            
                                /**
                                 * Validate the offset type.
                                 *
                                 * @method _validateOffset
                                 * @param  {Function | Number | Number.NEGATIVE_INFINITY} val
                                 */
                                _validateOffset: function(val) {
                                    if (A.Lang.isFunction(val)) {
                                        val = val.call(this);
                                    }
                            
                                    return A.Lang.isNumber(val) ||
                                        A.Lang.isFunction(val) ||
                                        (val === Number.NEGATIVE_INFINITY);
                                }
                            }, {
                                ATTRS: {
                                    /**
                                     * Defines the bottom offset.
                                     *
                                     * @attribute offsetBottom
                                     * @type {Function | Number}
                                     */
                                    offsetBottom: {
                                        getter: '_getOffset',
                                        validator: '_validateOffset',
                                        value: Number.NEGATIVE_INFINITY
                                    },
                            
                                    /**
                                     * Defines the top offset.
                                     *
                                     * @attribute offsetTop
                                     * @type {Function | Number}
                                     */
                                    offsetTop: {
                                        getter: '_getOffset',
                                        validator: '_validateOffset',
                                        value: Number.NEGATIVE_INFINITY
                                    },
                            
                                    /**
                                     * Defines the target element.
                                     *
                                     * @attribute target
                                     * @type {Node | String}
                                     */
                                    target: {
                                        setter: A.one
                                    }
                                },
                                /**
                                 * Map of events containing `BOTTOM`, `DEFAULT` or `TOP` keys.
                                 *
                                 * @type {Object}
                                 */
                                EVENTS: {
                                    BOTTOM: 'bottom',
                                    DEFAULT: 'default',
                                    TOP: 'top'
                                },
                                /**
                                 * Map of class names containing `BOTTOM`, `DEFAULT` or `TOP` keys.
                                 *
                                 * @type {Object}
                                 */
                                CSS_CLASSES: {
                                    BOTTOM: A.getClassName('affix', 'bottom'),
                                    DEFAULT: A.getClassName('affix'),
                                    TOP: A.getClassName('affix', 'top')
                                }
                            });