(function (e) {
    e.fn.jTweetsAnywhere = function (a) {
        a = e.extend({
            username: "naughty_dog",
            list: null,
            searchParams: null,
            count: 0,
            tweetProfileImagePresent: null,
            tweetFilter: defaultTweetFilter,
            showTweetFeed: true,
            showFollowButton: false,
            showConnectButton: false,
            showLoginInfo: false,
            showTweetBox: false,
            mainDecorator: defaultMainDecorator,
            tweetFeedDecorator: defaultTweetFeedDecorator,
            tweetDecorator: defaultTweetDecorator,
            tweetProfileImageDecorator: defaultTweetProfileImageDecorator,
            tweetBodyDecorator: defaultTweetBodyDecorator,
            tweetUsernameDecorator: defaultTweetUsernameDecorator,
            tweetTextDecorator: defaultTweetTextDecorator,
            tweetAttributesDecorator: defaultTweetAttributesDecorator,
            tweetTimestampDecorator: defaultTweetTimestampDecorator,
            tweetSourceDecorator: defaultTweetSourceDecorator,
            tweetGeoLocationDecorator: defaultTweetGeoLocationDecorator,
            tweetInReplyToDecorator: defaultTweetInReplyToDecorator,
            tweetRetweeterDecorator: defaultTweetRetweeterDecorator,
            tweetFeedControlsDecorator: defaultTweetFeedControlsDecorator,
            tweetFeedControlsMoreBtnDecorator: defaultTweetFeedControlsMoreBtnDecorator,
            tweetFeedControlsPrevBtnDecorator: defaultTweetFeedControlsPrevBtnDecorator,
            tweetFeedControlsNextBtnDecorator: defaultTweetFeedControlsNextBtnDecorator,
            tweetFeedAutorefreshTriggerDecorator: defaultTweetFeedAutorefreshTriggerDecorator,
            tweetFeedAutorefreshTriggerContentDecorator: defaultTweetFeedAutorefreshTriggerContentDecorator,
            connectButtonDecorator: defaultConnectButtonDecorator,
            loginInfoDecorator: defaultLoginInfoDecorator,
            loginInfoContentDecorator: defaultLoginInfoContentDecorator,
            followButtonDecorator: defaultFollowButtonDecorator,
            tweetBoxDecorator: defaultTweetBoxDecorator,
            linkDecorator: defaultLinkDecorator,
            usernameDecorator: defaultUsernameDecorator,
            hashtagDecorator: defaultHashtagDecorator,
            loadingDecorator: defaultLoadingDecorator,
            errorDecorator: defaultErrorDecorator,
            noDataDecorator: defaultNoDataDecorator,
            tweetTimestampFormatter: defaultTweetTimestampFormatter,
            tweetTimestampTooltipFormatter: defaultTweetTimestampTooltipFormatter,
            tweetVisualizer: defaultTweetVisualizer,
            loadingIndicatorVisualizer: defaultLoadingIndicatorVisualizer,
            autorefreshTriggerVisualizer: defaultAutorefreshTriggerVisualizer,
            onDataRequestHandler: defaultOnDataRequestHandler,
            onRateLimitDataHandler: defaultOnRateLimitDataHandler,
            _tweetFeedConfig: {
                expandHovercards: false,
                showTimestamp: {
                    refreshInterval: 120
                },
                showSource: false,
                showGeoLocation: true,
                showInReplyTo: true,
                showProfileImages: null,
                showUserScreenNames: null,
                showUserFullNames: false,
                includeRetweets: true,
                paging: {
                    mode: "none",
                    _limit: 0,
                    _offset: 0
                },
                autorefresh: {
                    mode: "none",
                    interval: 60,
                    duration: 3600,
                    _startTime: null,
                    _triggerElement: null
                },
                _pageParam: 0,
                _maxId: null,
                _recLevel: 0,
                _noData: false,
                _clearBeforePopulate: false
            },
            _tweetBoxConfig: {
                counter: true,
                width: 515,
                height: 65,
                label: "What's happening?",
                defaultContent: "",
                onTweet: function () {}
            },
            _connectButtonConfig: {
                size: "medium"
            },
            _baseSelector: null,
            _baseElement: null,
            _tweetFeedElement: null,
            _tweetFeedControlsElement: null,
            _followButtonElement: null,
            _loginInfoElement: null,
            _connectButtonElement: null,
            _tweetBoxElement: null,
            _loadingIndicatorElement: null,
            _noDataElement: null,
            _tweetsCache: [],
            _autorefreshTweetsCache: [],
            _stats: {
                dataRequestCount: 0,
                rateLimitPreventionCount: 0,
                rateLimit: {
                    remaining_hits: 350,
                    hourly_limit: 350
                }
            }
        }, a);
        if (a.mainDecorator) {
            a._baseSelector = this.selector;
            if (typeof a.username != "string") {
                if (!a.searchParams) a.searchParams = ["q=from:" + a.username.join(" OR from:")];
                a.username = a.username[0]
            }
            typeof a.showTweetFeed == "object" && e.extend(true, a._tweetFeedConfig, a.showTweetFeed);
            if (typeof a.showTweetBox == "object") {
                a._tweetBoxConfig = a.showTweetBox;
                a.showTweetBox = true
            }
            if (typeof a.showConnectButton == "object") {
                a._connectButtonConfig = a.showConnectButton;
                a.showConnectButton = true
            }
            if (a._tweetFeedConfig.showProfileImages == null) a._tweetFeedConfig.showProfileImages = a.tweetProfileImagePresent;
            if (a._tweetFeedConfig.showProfileImages == null) a._tweetFeedConfig.showProfileImages = (a.list || a.searchParams) && a.tweetProfileImageDecorator;
            if (a._tweetFeedConfig.showUserScreenNames == null) {
                if (a.list || a.searchParams) a._tweetFeedConfig.showUserScreenNames = true;
                if (!a.tweetUsernameDecorator) a._tweetFeedConfig.showUserScreenNames = false
            }
            if (a._tweetFeedConfig.showUserFullNames == null) {
                if (a.list || a.searchParams) a._tweetFeedConfig.showUserFullNames = true;
                if (!a.tweetUsernameDecorator) a._tweetFeedConfig.showUserFullNames = false
            }
            a.count = validateRange(a.count, 0, a.searchParams ? 100 : 20);
            a._tweetFeedConfig.autorefresh.interval = Math.max(30, a._tweetFeedConfig.autorefresh.interval);
            a._tweetFeedConfig.paging._offset = 0;
            a._tweetFeedConfig.paging._limit = a.count;
            if (a.count == 0 || !a.showTweetFeed) {
                a.tweetFeedDecorator = null;
                a.tweetFeedControlsDecorator = null
            }
            if (a._tweetFeedConfig.paging.mode == "none") a.tweetFeedControlsDecorator = null;
            if (!a.showFollowButton) a.followButtonDecorator = null;
            if (!a.showTweetBox) a.tweetBoxDecorator = null;
            if (!a.showConnectButton) a.connectButtonDecorator = null;
            if (!a.showLoginInfo) a.loginInfoDecorator = null;
            if (!a._tweetFeedConfig.showTimestamp) a.tweetTimestampDecorator = null;
            if (!a._tweetFeedConfig.showSource) a.tweetSourceDecorator = null;
            if (!a._tweetFeedConfig.showGeoLocation) a.tweetGeoLocationDecorator = null;
            if (!a._tweetFeedConfig.showInReplyTo) a.tweetInReplyToDecorator = null;
            e.ajaxSetup({
                cache: true
            });
            return this.each(function () {
                a._baseElement = e(this);
                a._tweetFeedElement = a.tweetFeedDecorator ? e(a.tweetFeedDecorator(a)) : null;
                a._tweetFeedControlsElement = a.tweetFeedControlsDecorator ? e(a.tweetFeedControlsDecorator(a)) : null;
                a._followButtonElement = a.followButtonDecorator ? e(a.followButtonDecorator(a)) : null;
                a._tweetBoxElement = a.tweetBoxDecorator ? e(a.tweetBoxDecorator(a)) : null;
                a._connectButtonElement = a.connectButtonDecorator ? e(a.connectButtonDecorator(a)) : null;
                a._loginInfoElement = a.loginInfoDecorator ? e(a.loginInfoDecorator(a)) : null;
                a.mainDecorator(a);
                populateTweetFeed(a);
                populateAnywhereControls(a);
                bindEventHandlers(a);
                a._tweetFeedConfig.autorefresh._startTime = (new Date).getTime();
                startAutorefresh(a);
                startTimestampRefresh(a)
            })
        }
    };
    defaultMainDecorator = function (a) {
        a._tweetFeedElement && a._baseElement.append(a._tweetFeedElement);
        a._tweetFeedControlsElement && a._baseElement.append(a._tweetFeedControlsElement);
        a._connectButtonElement && a._baseElement.append(a._connectButtonElement);
        a._loginInfoElement && a._baseElement.append(a._loginInfoElement);
        a._followButtonElement && a._baseElement.append(a._followButtonElement);
        a._tweetBoxElement && a._baseElement.append(a._tweetBoxElement)
    };
    defaultTweetFeedControlsDecorator = function (a) {
        var b = "";
        if (a._tweetFeedConfig.paging.mode == "prev-next") {
            if (a.tweetFeedControlsPrevBtnDecorator) b += a.tweetFeedControlsPrevBtnDecorator(a);
            if (a.tweetFeedControlsNextBtnDecorator) b += a.tweetFeedControlsNextBtnDecorator(a)
        } else if (a._tweetFeedConfig.paging.mode != "endless-scroll") if (a.tweetFeedControlsMoreBtnDecorator) b += a.tweetFeedControlsMoreBtnDecorator(a);
        return '<div class="jta-tweet-list-controls">' + b + "</div>"
    };
    defaultTweetFeedControlsMoreBtnDecorator = function () {
        return '<span class="jta-tweet-list-controls-button jta-tweet-list-controls-button-more">More</span>'
    };
    defaultTweetFeedControlsPrevBtnDecorator = function () {
        return '<span class="jta-tweet-list-controls-button jta-tweet-list-controls-button-prev">Prev</span>'
    };
    defaultTweetFeedControlsNextBtnDecorator = function () {
        return '<span class="jta-tweet-list-controls-button jta-tweet-list-controls-button-next">Next</span>'
    };
    defaultTweetFeedAutorefreshTriggerDecorator = function (a, b) {
        var c = "";
        if (b.tweetFeedAutorefreshTriggerContentDecorator) c = b.tweetFeedAutorefreshTriggerContentDecorator(a, b);
        return '<li class="jta-tweet-list-autorefresh-trigger">' + c + "</li>"
    };
    defaultTweetFeedAutorefreshTriggerContentDecorator = function (a) {
        return '<span class="jta-tweet-list-autorefresh-trigger-content">' + ("" + a + " new " + (a > 1 ? " tweets" : " tweet")) + "</span>"
    };
    defaultTweetFeedDecorator = function () {
        return '<ul class="jta-tweet-list"></ul>'
    };
    defaultTweetDecorator = function (a, b) {
        var c = "";
        if (b._tweetFeedConfig.showProfileImages) c += b.tweetProfileImageDecorator(a, b);
        if (b.tweetBodyDecorator) c += b.tweetBodyDecorator(a, b);
        c += '<div class="jta-clear">&nbsp;</div>';
        return '<li class="twitter_item">' + c + "</li>"
    };
    defaultTweetProfileImageDecorator = function (a) {
        a = a.retweeted_status || a;
        var b = a.user ? a.user.screen_name : a.from_user;
        return '<div class="twitter_item_left">' + ('<a class="twitter_item_left-link" href="http://twitter.com/' + b + '" target="_blank"><img src="' + (a.user ? a.user.profile_image_url : a.profile_image_url) + '" alt="' + b + '"' + (isAnywherePresent() ? "" : ' title="' + b + '"') + "/></a>") + "</div>"
    };
    defaultTweetBodyDecorator = function (a, b) {
        var c = "";
        if (b.tweetTextDecorator) c += b.tweetTextDecorator(a, b);
        if (b.tweetAttributesDecorator) c += b.tweetAttributesDecorator(a, b);
        return '<div class="jta-tweet-body ' + (b._tweetFeedConfig.showProfileImages ? "jta-tweet-body-list-profile-image-present" : "") + '">' + c + "</div>"
    };
    defaultTweetTextDecorator = function (a, b) {
        var c = a.text;
        if (a.retweeted_status && (b._tweetFeedConfig.showUserScreenNames || b._tweetFeedConfig.showUserScreenNames == null || b._tweetFeedConfig.showUserFullNames || b._tweetFeedConfig.showUserFullNames == null)) c = a.retweeted_status.text;
        if (b.linkDecorator) c = b.linkDecorator(c, b);
        if (b.usernameDecorator) c = b.usernameDecorator(c, b);
        if (b.hashtagDecorator) c = b.hashtagDecorator(c, b);
        if (b._tweetFeedConfig.showUserScreenNames || b._tweetFeedConfig.showUserFullNames || a.retweeted_status && (b._tweetFeedConfig.showUserScreenNames == null || b._tweetFeedConfig.showUserFullNames == null)) c = b.tweetUsernameDecorator(a, b) + " " + c;
        return '<span class="jta-tweet-text">' + c + "</span>"
    };
    defaultTweetUsernameDecorator = function (a, b) {
        var c = a.retweeted_status || a,
            d = c.user ? c.user.screen_name : c.from_user;
        c = c.user ? c.user.name : null;
        var f;
        if (d && (b._tweetFeedConfig.showUserScreenNames || b._tweetFeedConfig.showUserScreenNames == null && a.retweeted_status)) f = '<span class="jta-tweet-user-screen-name"><a class="jta-tweet-user-screen-name-link" href="http://twitter.com/' + d + '" target="_blank">' + d + "</a></span>";
        var g;
        if (c && (b._tweetFeedConfig.showUserFullNames || b._tweetFeedConfig.showUserFullNames == null && a.retweeted_status)) g = '<span class="jta-tweet-user-full-name">' + (f ? " (" : "") + '<a class="jta-tweet-user-full-name-link" href="http://twitter.com/' + d + '" name="' + d + '" target="_blank">' + c + "</a>" + (f ? ")" : "") + "</span>";
        d = "";
        if (f) d += f;
        if (g) {
            if (f) d += " ";
            d += g
        }
        if (f || g) d = '<span class="jta-tweet-user-name">' + (a.retweeted_status ? "RT " : "") + d + "</span>";
        return d
    };
    defaultTweetAttributesDecorator = function (a, b) {
        var c = "";
        if (b.tweetTimestampDecorator || b.tweetSourceDecorator || b.tweetGeoLocationDecorator || b.tweetInReplyToDecorator || a.retweeted_status && b.tweetRetweeterDecorator) {
            c += '<span class="jta-tweet-attributes">';
            if (b.tweetTimestampDecorator) c += b.tweetTimestampDecorator(a, b);
            if (b.tweetSourceDecorator) c += b.tweetSourceDecorator(a, b);
            if (b.tweetGeoLocationDecorator) c += b.tweetGeoLocationDecorator(a, b);
            if (b.tweetInReplyToDecorator) c += b.tweetInReplyToDecorator(a, b);
            if (a.retweeted_status && b.tweetRetweeterDecorator) c += b.tweetRetweeterDecorator(a, b);
            c += "</span>"
        }
        return c
    };
    defaultTweetTimestampDecorator = function (a, b) {
        var c = a.retweeted_status || a,
            d = formatDate(c.created_at),
            f = b.tweetTimestampFormatter(d),
            g = b.tweetTimestampTooltipFormatter(d);
        return '<span class="jta-tweet-timestamp"><a class="jta-tweet-timestamp-link" data-timestamp="' + d + '" href="http://twitter.com/' + (c.user ? c.user.screen_name : c.from_user) + "/status/" + c.id + '" target="_blank" title="' + g + '">' + f + "</a></span>"
    };
    defaultTweetTimestampTooltipFormatter = function (a) {
        return (new Date(a)).toLocaleString()
    };
    defaultTweetTimestampFormatter = function (a) {
        var b = new Date,
            c = parseInt((b.getTime() - Date.parse(a)) / 1E3),
            d = "";
        if (c < 60) d += c + " second" + (c == 1 ? "" : "s") + " ago";
        else if (c < 3600) {
            b = parseInt((c + 30) / 60);
            d += b + " minute" + (b == 1 ? "" : "s") + " ago"
        } else if (c < 86400) {
            b = parseInt((c + 1800) / 3600);
            d += b + " hour" + (b == 1 ? "" : "s") + " ago"
        } else {
            a = new Date(a);
            a.getHours();
            a.getMinutes();
            d += ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][a.getMonth()] + " " + a.getDate();
            if (a.getFullYear() < b.getFullYear()) d += ", " + a.getFullYear();
            b = parseInt((c + 43200) / 86400);
            d += " (" + b + " day" + (b == 1 ? "" : "s") + " ago)"
        }
        return d
    };
    exTimestampFormatter = function (a) {
        var b = parseInt(((new Date).getTime() - Date.parse(a)) / 1E3),
            c = "";
        if (b < 60) c += "less than a minute ago";
        else if (b < 3600) {
            b = parseInt((b + 30) / 60);
            c += b + " minute" + (b == 1 ? "" : "s") + " ago"
        } else if (b < 86400) {
            b = parseInt((b + 1800) / 3600);
            c += "about " + b + " hour" + (b == 1 ? "" : "s") + " ago"
        } else {
            b = parseInt((b + 43200) / 86400);
            c += "about " + b + " day" + (b == 1 ? "" : "s") + " ago";
            a = new Date(a);
            b = "AM";
            var d = a.getHours();
            if (d > 12) {
                d -= 12;
                b = "PM"
            }
            var f = a.getMinutes();
            c += " (" + d + ":" + ((f < 10 ? "0" : "") + f) + " " + b + " " + (a.getMonth() + 1) + "/" + a.getDate() + "/" + a.getFullYear() + ")"
        }
        return c
    };
    defaultTweetSourceDecorator = function (a) {
        return '<span class="jta-tweet-source"> via <span class="jta-tweet-source-link">' + (a.retweeted_status || a).source.replace(/\&lt\;/gi, "<").replace(/\&gt\;/gi, ">").replace(/\&quot\;/gi, '"') + "</span></span>"
    };
    defaultTweetGeoLocationDecorator = function (a) {
        var b = "";
        a = a.retweeted_status || a;
        var c;
        if (a.geo && a.geo.coordinates) c = a.geo.coordinates.join();
        else if (a.place && a.place.full_name) c = a.place.full_name;
        if (c) {
            b = "here";
            if (a.place && a.place.full_name) b = a.place.full_name;
            b = '<span class="jta-tweet-location"> from <a class="jta-tweet-location-link" href="' + ("http://maps.google.com/maps?q=" + c) + '" target="_blank">' + b + "</a></span>"
        }
        return b
    };
    defaultTweetInReplyToDecorator = function (a) {
        a = a.retweeted_status || a;
        var b = "";
        if (a.in_reply_to_status_id && a.in_reply_to_screen_name) b = '<span class="jta-tweet-inreplyto"> <a class="jta-tweet-inreplyto-link" href="http://twitter.com/' + a.in_reply_to_screen_name + "/status/" + a.in_reply_to_status_id + '" target="_blank">in reply to ' + a.in_reply_to_screen_name + "</a></span>";
        return b
    };
    defaultTweetRetweeterDecorator = function (a) {
        var b = "";
        if (a.retweeted_status) {
            b = a.user ? a.user.screen_name : a.from_user;
            a = (a.retweeted_status.retweet_count || 0) - 1;
            var c = " and " + a + (a > 1 ? " others" : " other");
            b = '<br/><span class="jta-tweet-retweeter">Retweeted by ' + ('<a class="jta-tweet-retweeter-link" href="http://twitter.com/' + b + '" target="_blank">' + b + "</a>") + (a > 0 ? c : "") + "</span>"
        }
        return b
    };
    defaultConnectButtonDecorator = function () {
        return '<div class="jta-connect-button"></div>'
    };
    defaultLoginInfoDecorator = function () {
        return '<div class="jta-login-info"></div>'
    };
    defaultLoginInfoContentDecorator = function (a, b) {
        var c = "";
        if (b.isConnected()) {
            c = b.currentUser.data("screen_name");
            var d = b.currentUser.data("profile_image_url");
            c = '<div class="jta-login-info-profile-image"><a href="http://twitter.com/' + c + '" target="_blank"><img src="' + d + '" alt="' + c + '" title="' + c + '"/></a></div><div class="jta-login-info-block"><div class="jta-login-info-screen-name"><a href="http://twitter.com/' + c + '" target="_blank">' + c + '</a></div><div class="jta-login-info-sign-out">Sign out</div></div><div class="jta-clear">&nbsp;</div>'
        }
        return c
    };
    defaultFollowButtonDecorator = function () {
        return '<div class="jta-follow-button"></div>'
    };
    defaultTweetBoxDecorator = function () {
        return '<div class="jta-tweet-box"></div>'
    };
    defaultLinkDecorator = function (a) {
        return a.replace(/((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi, '<a href="$1" class="jta-tweet-a jta-tweet-link" target="_blank" rel="nofollow">$1</a>')
    };
    defaultUsernameDecorator = function (a) {
        return isAnywherePresent() ? a : a.replace(/@([a-zA-Z0-9_]+)/gi, '@<a href="http://twitter.com/$1" class="jta-tweet-a twitter-anywhere-user" target="_blank" rel="nofollow">$1</a>')
    };
    defaultHashtagDecorator = function (a) {
        return a.replace(/#([a-zA-Z0-9_]+)/gi, '<a href="http://search.twitter.com/search?q=%23$1" class="jta-tweet-a jta-tweet-hashtag" title="#$1" target="_blank" rel="nofollow">#$1</a>')
    };
    defaultLoadingDecorator = function () {
        return '<li class="jta-loading">loading ...</li>'
    };
    defaultErrorDecorator = function (a) {
        return '<li class="jta-error">ERROR: ' + a + "</li>"
    };
    defaultNoDataDecorator = function () {
        return '<li class="jta-nodata">No more data</li>'
    };
    defaultTweetFilter = function () {
        return true
    };
    defaultTweetVisualizer = function (a, b, c) {
        a[c](b)
    };
    defaultLoadingIndicatorVisualizer = function (a, b, c, d) {
        defaultVisualizer(a, b, "append", "fadeIn", 600, "fadeOut", 200, d)
    };
    defaultAutorefreshTriggerVisualizer = function (a, b, c, d) {
        defaultVisualizer(a, b, "prepend", "slideDown", 600, "fadeOut", 200, d)
    };
    defaultVisualizer = function (a, b, c, d, f, g, k, h) {
        var j = function () {
                h && h()
            };
        if (a) {
            b.hide();
            a[c](b);
            b[d](f, j)
        } else b[g](k, function () {
            b.remove();
            j()
        })
    };
    defaultOnDataRequestHandler = function () {
        return true
    };
    defaultOnRateLimitDataHandler = function () {};
    updateLoginInfoElement = function (a, b) {
        if (a._loginInfoElement && a.loginInfoContentDecorator) {
            a._loginInfoElement.children().remove();
            a._loginInfoElement.append(a.loginInfoContentDecorator(a, b));
            e(a._baseSelector + " .jta-login-info-sign-out").bind("click", function () {
                twttr.anywhere.signOut()
            })
        }
    };
    getFeedUrl = function (a, b) {
        var c = "https:" == document.location.protocol ? "https:" : "http:";
        if (a.searchParams) c += "//search.twitter.com/search.json?" + (a.searchParams instanceof Array ? a.searchParams.join("&") : a.searchParams) + "&rpp=100";
        else if (a.list) c += "//api.twitter.com/1/" + a.username + "/lists/" + a.list + "/statuses.json?per_page=20";
        else {
            c += "//api.twitter.com/1/statuses/user_timeline.json?screen_name=" + a.username + "&count=20";
            if (a._tweetFeedConfig.includeRetweets) c += "&include_rts=true"
        }
        if (b) c += (a._tweetFeedConfig._maxId ? "&max_id=" + a._tweetFeedConfig._maxId : "") + "&page=" + a._tweetFeedConfig._pageParam;
        c += "&callback=?";
        return c
    };
    isAnywherePresent = function () {
        return typeof twttr != "undefined"
    };
    clearTweetFeed = function (a) {
        a._tweetFeedElement && a._tweetFeedElement.empty()
    };
    populateTweetFeed = function (a) {
        a.tweetDecorator && a._tweetFeedElement && getPagedTweets(a, function (b, c) {
            c._tweetFeedConfig._clearBeforePopulate && clearTweetFeed(c);
            hideLoadingIndicator(c, function () {
                e.each(b, function (d, f) {
                    c.tweetVisualizer(c._tweetFeedElement, e(c.tweetDecorator(f, c)), "append", c)
                });
                if (c._tweetFeedConfig._noData && c.noDataDecorator && !c._tweetFeedConfig._noDataElement) {
                    c._tweetFeedConfig._noDataElement = e(c.noDataDecorator(c));
                    c._tweetFeedElement.append(c._tweetFeedConfig._noDataElement)
                }
                c._tweetFeedConfig._clearBeforePopulate && c._tweetFeedElement.scrollTop(0);
                addHovercards(c)
            })
        })
    };
    populateTweetFeed2 = function (a) {
        if (a._tweetFeedElement && a._autorefreshTweetsCache.length > 0) if (a._tweetFeedConfig.autorefresh.mode == "trigger-insert") if (a._tweetFeedConfig.autorefresh._triggerElement) a.tweetFeedAutorefreshTriggerContentDecorator && a._tweetFeedConfig.autorefresh._triggerElement.html(a.tweetFeedAutorefreshTriggerContentDecorator(a._autorefreshTweetsCache.length, a));
        else {
            if (a.tweetFeedAutorefreshTriggerDecorator) {
                a._tweetFeedConfig.autorefresh._triggerElement = e(a.tweetFeedAutorefreshTriggerDecorator(a._autorefreshTweetsCache.length, a));
                a._tweetFeedConfig.autorefresh._triggerElement.bind("click", function () {
                    a.autorefreshTriggerVisualizer(null, a._tweetFeedConfig.autorefresh._triggerElement, a, function () {
                        insertTriggerTweets(a)
                    });
                    a._tweetFeedConfig.autorefresh._triggerElement = null
                });
                a.autorefreshTriggerVisualizer(a._tweetFeedElement, a._tweetFeedConfig.autorefresh._triggerElement, a)
            }
        } else insertTriggerTweets(a)
    };
    insertTriggerTweets = function (a) {
        if (a.tweetDecorator && a._autorefreshTweetsCache.length > 0) {
            for (; a._autorefreshTweetsCache.length > 0;) {
                var b = a._autorefreshTweetsCache.pop();
                a._tweetsCache.unshift(b);
                a._tweetFeedConfig.paging._offset++;
                a.tweetVisualizer(a._tweetFeedElement, e(a.tweetDecorator(b, a)), "prepend", a)
            }
            addHovercards(a)
        }
    };
    addHovercards = function (a) {
        isAnywherePresent() && twttr.anywhere(function (b) {
            b(a._baseSelector + " .jta-tweet-list").hovercards({
                expanded: a._tweetFeedConfig.expandHovercards
            });
            b(a._baseSelector + " .twitter_item_left img").hovercards({
                expanded: a._tweetFeedConfig.expandHovercards,
                username: function (c) {
                    return c.alt
                }
            });
            b(a._baseSelector + " .jta-tweet-retweeter-link").hovercards({
                expanded: a._tweetFeedConfig.expandHovercards,
                username: function (c) {
                    return c.text
                }
            });
            b(a._baseSelector + " .jta-tweet-user-screen-name-link").hovercards({
                expanded: a._tweetFeedConfig.expandHovercards,
                username: function (c) {
                    return c.text
                }
            });
            b(a._baseSelector + " .jta-tweet-user-full-name-link").hovercards({
                expanded: a._tweetFeedConfig.expandHovercards,
                username: function (c) {
                    return c.name
                }
            })
        })
    };
    populateAnywhereControls = function (a) {
        isAnywherePresent() && twttr.anywhere(function (b) {
            a.tweetBoxDecorator && b(a._baseSelector + " .jta-tweet-box").tweetBox(a._tweetBoxConfig);
            a.followButtonDecorator && b(a._baseSelector + " .jta-follow-button").followButton(a.username);
            if (a.connectButtonDecorator) {
                var c = e.extend({
                    authComplete: function () {
                        updateLoginInfoElement(a, b)
                    },
                    signOut: function () {
                        updateLoginInfoElement(a, b)
                    }
                }, a._connectButtonConfig);
                b(a._baseSelector + " .jta-connect-button").connectButton(c);
                updateLoginInfoElement(a, b)
            }
        })
    };
    bindEventHandlers = function (a) {
        if (a.tweetFeedControlsDecorator) if (a._tweetFeedConfig.paging.mode == "prev-next") {
            e(a._baseSelector + " .jta-tweet-list-controls-button-prev").bind("click", function () {
                !isLoading(a) && a._tweetFeedConfig.paging._offset > 0 && prevPage(a, true)
            });
            e(a._baseSelector + " .jta-tweet-list-controls-button-next").bind("click", function () {
                isLoading(a) || nextPage(a, true)
            })
        } else a._tweetFeedConfig.paging.mode == "endless-scroll" ? a._tweetFeedElement.bind("scroll", function () {
            !isLoading(a) && e(this)[0].scrollHeight - e(this).scrollTop() == e(this).outerHeight() && nextPage(a, false)
        }) : e(a._baseSelector + " .jta-tweet-list-controls-button-more").bind("click", function () {
            isLoading(a) || nextPage(a, false)
        })
    };
    nextPage = function (a, b) {
        doPage(a, b, Math.min(a._tweetFeedConfig.paging._offset + a._tweetFeedConfig.paging._limit, a._tweetsCache.length))
    };
    prevPage = function (a, b) {
        doPage(a, b, Math.max(0, a._tweetFeedConfig.paging._offset - a._tweetFeedConfig.paging._limit))
    };
    doPage = function (a, b, c) {
        a._tweetFeedConfig.paging._offset = c;
        a._tweetFeedConfig._clearBeforePopulate = b;
        populateTweetFeed(a)
    };
    startAutorefresh = function (a) {
        if (a._tweetFeedConfig.autorefresh.mode != "none" && a._tweetFeedConfig.paging.mode != "prev-next" && a._tweetFeedConfig.autorefresh.duration != 0 && (a._tweetFeedConfig.autorefresh.duration < 0 || (new Date).getTime() - a._tweetFeedConfig.autorefresh._startTime <= a._tweetFeedConfig.autorefresh.duration * 1E3)) window.setTimeout(function () {
            processAutorefresh(a)
        }, a._tweetFeedConfig.autorefresh.interval * 1E3)
    };
    stopAutorefresh = function (a) {
        a._tweetFeedConfig.autorefresh.duration = 0
    };
    processAutorefresh = function (a) {
        if (a._tweetFeedConfig.autorefresh.duration != 0) {
            getRateLimitedData(a, true, getFeedUrl(a, false), function (b, c) {
                var d = (b.results || b).slice(0);
                d.reverse();
                e.each(d, function (f, g) {
                    isTweetInCache(g, c) || c.tweetFilter(g, c) && c._autorefreshTweetsCache.unshift(g)
                });
                populateTweetFeed2(c)
            });
            startAutorefresh(a)
        }
    };
    startTimestampRefresh = function (a) {
        a.tweetTimestampDecorator && typeof a._tweetFeedConfig.showTimestamp == "object" && a._tweetFeedConfig.showTimestamp.refreshInterval > 0 && window.setTimeout(function () {
            processTimestampRefresh(a)
        }, a._tweetFeedConfig.showTimestamp.refreshInterval * 1E3)
    };
    processTimestampRefresh = function (a) {
        e.each(a._tweetFeedElement.find(".jta-tweet-timestamp-link"), function (b, c) {
            var d = e(c).attr("data-timestamp");
            e(c).html(a.tweetTimestampFormatter(d))
        });
        startTimestampRefresh(a)
    };
    isTweetInCache = function (a, b) {
        for (var c = b._tweetsCache.length, d = 0; d < c; d++) if (a.id == b._tweetsCache[d].id) return true;
        return false
    };
    showLoadingIndicator = function (a) {
        if (a._tweetFeedElement && a.loadingDecorator && !a._loadingIndicatorElement) {
            a._loadingIndicatorElement = e(a.loadingDecorator(a));
            a.loadingIndicatorVisualizer(a._tweetFeedElement, a._loadingIndicatorElement, a, null);
            a._tweetFeedElement.scrollTop(1E6)
        }
    };
    hideLoadingIndicator = function (a, b) {
        if (a._loadingIndicatorElement) {
            a.loadingIndicatorVisualizer(null, a._loadingIndicatorElement, a, b);
            a._loadingIndicatorElement = null
        } else b && b()
    };
    isLoading = function (a) {
        return a._loadingIndicatorElement != null
    };
    formatDate = function (a) {
        return a.replace(/^([a-z]{3})( [a-z]{3} \d\d?)(.*)( \d{4})$/i, "$1,$2$4$3")
    };
    validateRange = function (a, b, c) {
        if (a < b) a = b;
        if (a > c) a = c;
        return a
    };
    showError = function (a, b) {
        a.errorDecorator && a._tweetFeedElement && a._tweetFeedElement.append(a.errorDecorator(b, a))
    };
    getPagedTweets = function (a, b) {
        a._tweetFeedConfig._recLevel = 0;
        getRecPagedTweets(a, a._tweetFeedConfig.paging._offset, a._tweetFeedConfig.paging._limit, b)
    };
    getRecPagedTweets = function (a, b, c, d) {
        ++a._tweetFeedConfig._recLevel;
        if (b + c <= a._tweetsCache.length || a._tweetFeedConfig._recLevel > 3 || a._tweetFeedConfig._noData) {
            if (b + c > a._tweetsCache.length) c = Math.max(0, a._tweetsCache.length - b);
            for (var f = [], g = 0; g < c; g++) f[g] = a._tweetsCache[b + g];
            d(f, a)
        } else {
            ++a._tweetFeedConfig._pageParam;
            getRateLimitedData(a, false, getFeedUrl(a, true), function (k, h) {
                var j = k.results || k;
                if (j.length == 0) h._tweetFeedConfig._noData = true;
                else e.each(j, function (l, i) {
                    if (i.id_str) i.id = i.id_str;
                    if (i.in_reply_to_status_id_str) i.in_reply_to_status_id = i.in_reply_to_status_id_str;
                    if (!h._tweetFeedConfig._maxId) h._tweetFeedConfig._maxId = i.id;
                    h.tweetFilter(i, h) && h._tweetsCache.push(i)
                });
                getRecPagedTweets(h, b, c, d)
            })
        }
    };
    getRateLimitedData = function (a, b, c, d) {
        getRateLimit(a, function (f) {
            if (f && f.remaining_hits <= 0) {
                a._stats.rateLimitPreventionCount++;
                hideLoadingIndicator(a, null)
            } else getData(a, b, c, d)
        })
    };
    getData = function (a, b, c, d) {
        a._stats.dataRequestCount++;
        if (a.onDataRequestHandler(a._stats, a)) {
            b || showLoadingIndicator(a);
            e.getJSON(c, function (f) {
                f.error ? showError(a, f.error) : d(f, a)
            })
        } else hideLoadingIndicator(a, null)
    };
    getRateLimit = function (a, b) {
        e.getJSON("http://api.twitter.com/1/account/rate_limit_status.json?callback=?", function (c) {
            a._stats.rateLimit = c;
            a.onRateLimitDataHandler(a._stats, a);
            b(c)
        })
    }
})(jQuery);
