Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add repoting copied tweets form

  • Loading branch information...
commit 61dde16fd55babd2ccf5ff6a9c8be1f600868d9b 1 parent 1b49426
@rhenium rhenium authored
Showing with 432 additions and 115 deletions.
  1. +1 −1  Gemfile
  2. +10 −8 Gemfile.lock
  3. +1 −0  app/assets/javascripts/application.js
  4. +2 −1  app/assets/javascripts/tweets.js
  5. +40 −0 app/assets/javascripts/twitter_widgets.js
  6. +14 −0 app/assets/stylesheets/_tweets.css.sass
  7. +12 −5 app/controllers/application_controller.rb
  8. +5 −13 app/controllers/i_controller.rb
  9. +69 −0 app/controllers/report_controller.rb
  10. +2 −2 app/controllers/search_controller.rb
  11. +12 −9 app/controllers/users_controller.rb
  12. +6 −1 app/helpers/application_helper.rb
  13. +0 −2  app/helpers/search_helper.rb
  14. +10 −0 app/models/issue.rb
  15. +14 −0 app/models/stolen_tweet.rb
  16. +12 −2 app/models/tweet.rb
  17. +3 −1 app/views/layouts/_base.html.haml
  18. +38 −4 app/views/main/about.html.haml
  19. +17 −49 app/views/main/index.html.haml
  20. +17 −0 app/views/report/index.html.haml
  21. +2 −0  app/views/report/issue.html.haml
  22. +2 −0  app/views/report/spam.html.haml
  23. +2 −0  app/views/report/tweet.html.haml
  24. +12 −10 app/views/shared/_tweet.html.haml
  25. +4 −3 app/views/shared/tweets.html.haml
  26. +5 −2 config/routes.rb
  27. +11 −0 db/migrate/20130403114115_create_stolen_tweets.rb
  28. +14 −0 db/migrate/20130403160821_create_issues.rb
  29. +20 −1 db/schema.rb
  30. +12 −0 lib/aclog/constants.rb
  31. +3 −1 lib/receiver/worker.rb
  32. +24 −0 test/controllers/report_controller_test.rb
  33. +9 −0 test/fixtures/issues.yml
  34. +9 −0 test/fixtures/stolen_tweets.yml
  35. +4 −0 test/helpers/report_helper_test.rb
  36. +7 −0 test/models/issue_test.rb
  37. +7 −0 test/models/stolen_tweet_test.rb
View
2  Gemfile
@@ -30,4 +30,4 @@ gem 'msgpack'
gem 'omniauth-twitter', :github => "re4k/omniauth-twitter"
gem 'em-twitter'
gem 'twitter'
-
+gem 'yajl-ruby', :require => "yajl"
View
18 Gemfile.lock
@@ -36,7 +36,7 @@ GEM
after_commit_action (0.1.3)
activerecord (>= 3.0.0)
arel (4.0.0.beta2)
- atomic (1.0.1)
+ atomic (1.0.2)
bootstrap-sass (2.3.1.0)
sass (~> 3.2)
builder (3.1.4)
@@ -47,12 +47,12 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.6.2)
- counter_culture (0.1.10)
+ counter_culture (0.1.11)
after_commit_action (~> 0.1.3)
daemon-spawn (0.4.2)
daemons (1.1.9)
dalli (2.6.2)
- em-twitter (0.2.1)
+ em-twitter (0.2.2)
eventmachine (~> 1.0)
http_parser.rb (~> 0.5)
simple_oauth (~> 0.1)
@@ -62,7 +62,7 @@ GEM
eventmachine (1.0.3)
execjs (1.4.0)
multi_json (~> 1.0)
- faraday (0.8.6)
+ faraday (0.8.7)
multipart-post (~> 1.1)
haml (4.0.1)
tilt
@@ -75,7 +75,7 @@ GEM
hike (1.2.1)
http_parser.rb (0.5.3)
i18n (0.6.4)
- jbuilder (1.0.2)
+ jbuilder (1.2.0)
activesupport (>= 3.0.0)
jquery-rails (2.2.1)
railties (>= 3.0, < 5.0)
@@ -89,7 +89,7 @@ GEM
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
- mime-types (1.21)
+ mime-types (1.22)
minitest (4.7.0)
msgpack (0.5.4)
multi_json (1.7.2)
@@ -123,7 +123,7 @@ GEM
rdoc (~> 3.4)
thor (>= 0.17.0, < 2.0)
raindrops (0.10.0)
- rake (10.0.3)
+ rake (10.0.4)
rdoc (3.12.2)
json (~> 1.4)
sass (3.2.7)
@@ -146,7 +146,7 @@ GEM
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
- thor (0.17.0)
+ thor (0.18.1)
thread_safe (0.1.0)
atomic
tilt (1.3.6)
@@ -165,6 +165,7 @@ GEM
kgio (~> 2.6)
rack
raindrops (~> 0.7)
+ yajl-ruby (1.1.0)
PLATFORMS
ruby
@@ -191,3 +192,4 @@ DEPENDENCIES
twitter
uglifier (>= 1.0.3)
unicorn
+ yajl-ruby
View
1  app/assets/javascripts/application.js
@@ -1,3 +1,4 @@
//= require jquery
//= require jquery_ujs
+//= require twitter_widgets
//= require_tree .
View
3  app/assets/javascripts/tweets.js
@@ -1,5 +1,6 @@
//= require jquery.autopager-1.0.0-mod
$(function() {
+ $(".pagination").hide();
$.autopager({
autoLoad: true,
content: ".items",
@@ -10,7 +11,7 @@ $(function() {
$(".loading").hide();
}
});
- $("a[rel=next]").hide().click(function() {
+ $("a[rel=next]").click(function() {
$.autopager("load");
return false;
});
View
40 app/assets/javascripts/twitter_widgets.js
@@ -0,0 +1,40 @@
+if(!window.__twttrlr){(function(a,b){function s(a){for(var b=1,c;c=arguments[b];b++)for(var d in c)a[d]=c[d];return a}function t(a){return Array.prototype.slice.call(a)}function v(a,b){for(var c=0,d;d=a[c];c++)if(b==d)return c;return-1}function w(){var a=t(arguments),b=[];for(var c=0,d=a.length;c<d;c++)a[c].length>0&&b.push(a[c].replace(/\/$/,""));return b.join("/")}function x(a,b,c){var d=b.split("/"),e=a;while(d.length>1){var f=d.shift();e=e[f]=e[f]||{}}e[d[0]]=c}function y(){}function z(a,b){this.id=this.path=a,this.force=!!b}function A(a,b){this.id=a,this.body=b,typeof b=="undefined"&&(this.path=this.resolvePath(a))}function B(a,b){this.deps=a,this.collectResults=b,this.deps.length==0&&this.complete()}function C(a,b){this.deps=a,this.collectResults=b}function D(){for(var a in d)if(d[a].readyState=="interactive")return l[d[a].id]}function E(a,b){var d;return!a&&c&&(d=k||D()),d?(delete l[d.scriptId],d.body=b,d.execute()):(j=d=new A(a,b),i[d.id]=d),d}function F(){var a=t(arguments),b,c;return typeof a[0]=="string"&&(b=a.shift()),c=a.shift(),E(b,c)}function G(a,b){var c=b.id||"",d=c.split("/");d.pop();var e=d.join("/");return a.replace(/^\./,e)}function H(a,b){function d(a){return A.exports[G(a,b)]}var c=[];for(var e=0,f=a.length;e<f;e++){if(a[e]=="require"){c.push(d);continue}if(a[e]=="exports"){b.exports=b.exports||{},c.push(b.exports);continue}c.push(d(a[e]))}return c}function I(){var a=t(arguments),b=[],c,d;return typeof a[0]=="string"&&(c=a.shift()),u(a[0])&&(b=a.shift()),d=a.shift(),E(c,function(a){function f(){var e=H(t(b),c),f;typeof d=="function"?f=d.apply(c,e):f=d,typeof f=="undefined"&&(f=c.exports),a(f)}var c=this,e=[];for(var g=0,h=b.length;g<h;g++){var i=b[g];v(["require","exports"],i)==-1&&e.push(G(i,c))}e.length>0?J.apply(this,e.concat(f)):f()})}function J(){var a=t(arguments),b,c;typeof a[a.length-1]=="function"&&(b=a.pop()),typeof a[a.length-1]=="boolean"&&(c=a.pop());var d=new B(K(a,c),c);return b&&d.then(b),d}function K(a,b){var c=[];for(var d=0,e;e=a[d];d++)typeof e=="string"&&(e=L(e)),u(e)&&(e=new C(K(e,b),b)),c.push(e);return c}function L(a){var b,c;for(var d=0,e;e=J.matchers[d];d++){var f=e[0],g=e[1];if(b=a.match(f))return g(a)}throw new Error(a+" was not recognised by loader")}function N(){return a.using=m,a.provide=n,a.define=o,a.loadrunner=p,M}function O(a){for(var b=0;b<J.bundles.length;b++)for(var c in J.bundles[b])if(c!=a&&v(J.bundles[b][c],a)>-1)return c}var c=a.attachEvent&&!a.opera,d=b.getElementsByTagName("script"),e=0,f,g=b.createElement("script"),h={},i={},j,k,l={},m=a.using,n=a.provide,o=a.define,p=a.loadrunner;for(var q=0,r;r=d[q];q++)if(r.src.match(/loadrunner\.js(\?|#|$)/)){f=r;break}var u=Array.isArray||function(a){return a.constructor==Array};y.prototype.then=function(b){var c=this;return this.started||(this.started=!0,this.start()),this.completed?b.apply(a,this.results):(this.callbacks=this.callbacks||[],this.callbacks.push(b)),this},y.prototype.start=function(){},y.prototype.complete=function(){if(!this.completed){this.results=t(arguments),this.completed=!0;if(this.callbacks)for(var b=0,c;c=this.callbacks[b];b++)c.apply(a,this.results)}},z.loaded=[],z.prototype=new y,z.prototype.start=function(){var a=this,b,c,d;return(d=i[this.id])?(d.then(function(){a.complete()}),this):((b=h[this.id])?b.then(function(){a.loaded()}):!this.force&&v(z.loaded,this.id)>-1?this.loaded():(c=O(this.id))?J(c,function(){a.loaded()}):this.load(),this)},z.prototype.load=function(){var b=this;h[this.id]=b;var c=g.cloneNode(!1);this.scriptId=c.id="LR"+ ++e,c.type="text/javascript",c.async=!0,c.onerror=function(){throw new Error(b.path+" not loaded")},c.onreadystatechange=c.onload=function(c){c=a.event||c;if(c.type=="load"||v(["loaded","complete"],this.readyState)>-1)this.onreadystatechange=null,b.loaded()},c.src=this.path,k=this,d[0].parentNode.insertBefore(c,d[0]),k=null,l[c.id]=this},z.prototype.loaded=function(){this.complete()},z.prototype.complete=function(){v(z.loaded,this.id)==-1&&z.loaded.push(this.id),delete h[this.id],y.prototype.complete.apply(this,arguments)},A.exports={},A.prototype=new z,A.prototype.resolvePath=function(a){return w(J.path,a+".js")},A.prototype.start=function(){var a,b,c=this,d;this.body?this.execute():(a=A.exports[this.id])?this.exp(a):(b=i[this.id])?b.then(function(a){c.exp(a)}):(bundle=O(this.id))?J(bundle,function(){c.start()}):(i[this.id]=this,this.load())},A.prototype.loaded=function(){var a,b,d=this;c?(b=A.exports[this.id])?this.exp(b):(a=i[this.id])&&a.then(function(a){d.exp(a)}):(a=j,j=null,a.id=a.id||this.id,a.then(function(a){d.exp(a)}))},A.prototype.complete=function(){delete i[this.id],z.prototype.complete.apply(this,arguments)},A.prototype.execute=function(){var a=this;typeof this.body=="object"?this.exp(this.body):typeof this.body=="function"&&this.body.apply(window,[function(b){a.exp(b)}])},A.prototype.exp=function(a){this.complete(this.exports=A.exports[this.id]=a||{})},B.prototype=new y,B.prototype.start=function(){function b(){var b=[];a.collectResults&&(b[0]={});for(var c=0,d;d=a.deps[c];c++){if(!d.completed)return;d.results.length>0&&(a.collectResults?d instanceof C?s(b[0],d.results[0]):x(b[0],d.id,d.results[0]):b=b.concat(d.results))}a.complete.apply(a,b)}var a=this;for(var c=0,d;d=this.deps[c];c++)d.then(b);return this},C.prototype=new y,C.prototype.start=function(){var a=this,b=0,c=[];return a.collectResults&&(c[0]={}),function d(){var e=a.deps[b++];e?e.then(function(b){e.results.length>0&&(a.collectResults?e instanceof C?s(c[0],e.results[0]):x(c[0],e.id,e.results[0]):c.push(e.results[0])),d()}):a.complete.apply(a,c)}(),this},I.amd={};var M=function(a){return a(J,F,M,define)};M.Script=z,M.Module=A,M.Collection=B,M.Sequence=C,M.Dependency=y,M.noConflict=N,a.loadrunner=M,a.using=J,a.provide=F,a.define=I,J.path="",J.matchers=[],J.matchers.add=function(a,b){this.unshift([a,b])},J.matchers.add(/(^script!|\.js$)/,function(a){var b=new z(a.replace(/^\$/,J.path.replace(/\/$/,"")+"/").replace(/^script!/,""),!1);return b.id=a,b}),J.matchers.add(/^[a-zA-Z0-9_\-\/]+$/,function(a){return new A(a)}),J.bundles=[],f&&(J.path=f.getAttribute("data-path")||f.src.split(/loadrunner\.js/)[0]||"",(main=f.getAttribute("data-main"))&&J.apply(a,main.split(/\s*,\s*/)).then(function(){}))})(this,document);(window.__twttrlr = loadrunner.noConflict());}__twttrlr(function(using, provide, loadrunner, define) {provide("util/util",function(a){function b(a){var b=1,c,d;for(;c=arguments[b];b++)for(d in c)if(!c.hasOwnProperty||c.hasOwnProperty(d))a[d]=c[d];return a}function c(a){for(var b in a)a.hasOwnProperty(b)&&!a[b]&&a[b]!==!1&&a[b]!==0&&delete a[b]}function d(a,b){var c=0,d;for(;d=a[c];c++)if(b==d)return c;return-1}function e(a,b){if(!a)return null;if(a.filter)return a.filter.apply(a,[b]);if(!b)return a;var c=[],d=0,e;for(;e=a[d];d++)b(e)&&c.push(e);return c}function f(a,b){if(!a)return null;if(a.map)return a.map.apply(a,[b]);if(!b)return a;var c=[],d=0,e;for(;e=a[d];d++)c.push(b(e));return c}function g(a){return a&&a.replace(/(^\s+|\s+$)/g,"")}function h(a){return{}.toString.call(a).match(/\s([a-zA-Z]+)/)[1].toLowerCase()}function i(a){return a&&String(a).toLowerCase().indexOf("[native code]")>-1}function j(a,b){if(a.contains)return a.contains(b);var c=b.parentNode;while(c){if(c===a)return!0;c=c.parentNode}return!1}function k(a){return a===Object(a)}a({aug:b,compact:c,containsElement:j,filter:e,map:f,trim:g,indexOf:d,isNative:i,isObject:k,toType:h})});
+provide("util/events",function(a){using("util/util",function(b){function d(){this.completed=!1,this.callbacks=[]}var c={bind:function(a,b){return this._handlers=this._handlers||{},this._handlers[a]=this._handlers[a]||[],this._handlers[a].push(b)},unbind:function(a,c){if(!this._handlers[a])return;if(c){var d=b.indexOf(this._handlers[a],c);d>=0&&this._handlers[a].splice(d,1)}else this._handlers[a]=[]},trigger:function(a,b){var c=this._handlers&&this._handlers[a];b.type=a;if(c)for(var d=0,e;e=c[d];d++)e.call(this,b)}};d.prototype.addCallback=function(a){this.completed?a.apply(this,this.results):this.callbacks.push(a)},d.prototype.complete=function(){this.results=makeArray(arguments),this.completed=!0;for(var a=0,b;b=this.callbacks[a];a++)b.apply(this,this.results)},a({Emitter:c,Promise:d})})});
+provide("tfw/util/globals",function(a){function c(){var a=document.getElementsByTagName("meta"),c,d,e=0;for(;c=a[e];e++){if(!/^twitter:/.test(c.name))continue;d=c.name.replace(/^twitter:/,""),b[d]=c.content}}function d(a){return b[a]}var b={};a({init:c,val:d})});
+provide("util/querystring",function(a){function b(a){return encodeURIComponent(a).replace(/\+/g,"%2B")}function c(a){return decodeURIComponent(a)}function d(a){var c=[],d;for(d in a)a[d]!==null&&typeof a[d]!="undefined"&&c.push(b(d)+"="+b(a[d]));return c.sort().join("&")}function e(a){var b={},d,e,f,g;if(a){d=a.split("&");for(g=0;f=d[g];g++)e=f.split("="),e.length==2&&(b[c(e[0])]=c(e[1]))}return b}function f(a,b){var c=d(b);return c.length>0?a.indexOf("?")>=0?a+"&"+d(b):a+"?"+d(b):a}function g(a){var b=a&&a.split("?");return b.length==2?e(b[1]):{}}a({url:f,decodeURL:g,decode:e,encode:d,encodePart:b,decodePart:c})});
+provide("util/twitter",function(a){using("util/querystring",function(b){function f(a){return typeof a=="string"&&c.test(a)&&RegExp.$1.length<=20}function g(a){return f(a)&&RegExp.$1}function h(a){var c=b.decodeURL(a);c.screen_name=g(a);if(c.screen_name)return b.url("https://twitter.com/intent/user",c)}function i(a){return typeof a=="string"&&!/\W/.test(a)}function j(a){return i(a)?"#"+a:""}function k(a){return typeof a=="string"&&d.test(a)}function l(a){return k(a)&&RegExp.$1}function m(a){return e.test(a)}var c=/(?:^|(?:https?\:)?\/\/(?:www\.)?twitter\.com(?:\:\d+)?(?:\/intent\/(?:follow|user)\/?\?screen_name=|(?:\/#!)?\/))@?([\w]+)(?:\?|&|$)/i,d=/(?:^|(?:https?\:)?\/\/(?:www\.)?twitter\.com(?:\:\d+)?\/(?:#!\/)?[\w_]+\/status(?:es)?\/)(\d+)/i,e=/^http(s?):\/\/((www\.)?)twitter.com\//;a({isHashTag:i,hashTag:j,isScreenName:f,screenName:g,isStatus:k,status:l,intentForProfileURL:h,isTwitterURL:m,regexen:{profile:c}})})});
+provide("util/uri",function(a){using("util/querystring","util/util","util/twitter",function(b,c,d){function e(a){var b;return a.match(/^https?:\/\//)?a:(b=location.host,location.port.length>0&&(b+=":"+location.port),[location.protocol,"//",b,a].join(""))}function f(){var a=document.getElementsByTagName("link");for(var b=0,c;c=a[b];b++)if(c.rel=="canonical")return e(c.href);return null}function g(){var a=document.getElementsByTagName("a"),b=document.getElementsByTagName("link"),c=[a,b],e,f,g=0,h=0,i=/\bme\b/,j;for(;e=c[g];g++)for(h=0;f=e[h];h++)if(i.test(f.rel)&&(j=d.screenName(f.href)))return j}a({absolutize:e,getCanonicalURL:f,getScreenNameFromPage:g})})});
+provide("util/iframe",function(a){a(function(a){var b=(a.replace&&a.replace.ownerDocument||document).createElement("div"),c,d,e;b.innerHTML="<iframe allowtransparency='true' frameborder='0' scrolling='no'></iframe>",c=b.firstChild,c.src=a.url,c.className=a.className||"";if(a.css)for(d in a.css)a.css.hasOwnProperty(d)&&(c.style[d]=a.css[d]);if(a.attributes)for(e in a.attributes)a.attributes.hasOwnProperty(e)&&c.setAttribute(e,a.attributes[e]);return a.replace?a.replace.parentNode.replaceChild(c,a.replace):a.insertTarget&&a.insertTarget.appendChild(c),c})});
+provide("dom/get",function(a){using("util/util",function(b){function c(a,c,d,e){var f,g,h=[],i,j,k,l,m,n;c=c||document;if(b.isNative(c.getElementsByClassName))return h=b.filter(c.getElementsByClassName(a),function(a){return!d||a.tagName.toLowerCase()==d.toLowerCase()}),[].slice.call(h,0,e||h.length);i=a.split(" "),l=i.length,f=c.getElementsByTagName(d||"*"),n=f.length;for(k=0;k<l&&n>0;k++){h=[],j=i[k];for(m=0;m<n;m++){g=f[m],~b.indexOf(g.className.split(" "),j)&&h.push(g);if(k+1==l&&h.length===e)break}f=h,n=f.length}return h}function d(a,b,d){return c(a,b,d,1)[0]}function e(a,c,d){var f=c&&c.parentNode,g;if(!f||f===d)return;return f.tagName==a?f:(g=f.className.split(" "),0===a.indexOf(".")&&~b.indexOf(g,a.slice(1))?f:e(a,f,d))}a({all:c,one:d,ancestor:e})})});
+provide("util/domready",function(a){function k(){b=1;for(var a=0,d=c.length;a<d;a++)c[a]()}var b=0,c=[],d,e,f=!1,g=document.createElement("a"),h="DOMContentLoaded",i="addEventListener",j="onreadystatechange";/^loade|c/.test(document.readyState)&&(b=1),document[i]&&document[i](h,e=function(){document.removeEventListener(h,e,f),k()},f),g.doScroll&&document.attachEvent(j,d=function(){/^c/.test(document.readyState)&&(document.detachEvent(j,d),k())});var l=g.doScroll?function(a){self!=top?b?a():c.push(a):!function(){try{g.doScroll("left")}catch(b){return setTimeout(function(){l(a)},50)}a()}()}:function(a){b?a():c.push(a)};a(l)});
+provide("tfw/widget/base",function(a){using("util/util","util/domready","dom/get","util/querystring","util/iframe",function(b,c,d,e,f){function m(a){var b;if(!a)return;a.ownerDocument?(this.srcEl=a,this.classAttr=a.className.split(" ")):(this.srcOb=a,this.classAttr=[]),b=this.params(),this.id=o(),this.setLanguage(),this.related=b.related||this.dataAttr("related"),this.partner=b.partner||this.dataAttr("partner"),this.dnt=b.dnt||this.dataAttr("dnt")||"",this.styleAttr=[],this.targetEl=a.targetEl}function n(){var a=0,b;for(;b=k[a];a++)b.call()}function o(){return this.srcEl&&this.srcEl.id||"twitter-widget-"+g++}function p(a){if(!a)return;return a.lang?a.lang:p(a.parentNode)}var g=0,h,i,j={list:[],byId:{}},k=[],l={ar:{"%{followers_count} followers":"عدد المتابعين %{followers_count}","100K+":"+100 ألف","10k unit":"10 آلاف وحدة",Follow:"تابِع","Follow %{screen_name}":"تابِع %{screen_name}",K:"ألف",M:"مليون",Tweet:"غرِّد","Tweet %{hashtag}":"غرِّد %{hashtag}","Tweet to %{name}":"غرِّد لـ %{name}","Twitter Stream":"خطّ تويتر الزمنيّ"},da:{"%{followers_count} followers":"%{followers_count} følgere","100K+":"100K+","10k unit":"10k enhed",Follow:"Følg","Follow %{screen_name}":"Følg %{screen_name}",K:"K",M:"M",Tweet:"Tweet","Tweet %{hashtag}":"Tweet %{hashtag}","Tweet to %{name}":"Tweet til %{name}","Twitter Stream":"Twitter-strøm"},de:{"%{followers_count} followers":"%{followers_count} Follower","100K+":"100Tsd+","10k unit":"10tsd-Einheit",Follow:"Folgen","Follow %{screen_name}":"%{screen_name} folgen",K:"Tsd",M:"M",Tweet:"Twittern","Tweet %{hashtag}":"Tweet %{hashtag}","Tweet to %{name}":"Tweet an %{name}","Twitter Stream":"Twitter Stream"},es:{"%{followers_count} followers":"%{followers_count} seguidores","100K+":"100K+","10k unit":"10k unidad",Follow:"Seguir","Follow %{screen_name}":"Seguir a %{screen_name}",K:"K",M:"M",Tweet:"Twittear","Tweet %{hashtag}":"Twittear %{hashtag}","Tweet to %{name}":"Twittear a %{name}","Twitter Stream":"Cronología de Twitter"},fa:{"%{followers_count} followers":"%{followers_count} دنبال‌کننده","100K+":">۱۰۰هزار","10k unit":"۱۰هزار واحد",Follow:"دنبال کردن","Follow %{screen_name}":"دنبال کردن %{screen_name}",K:"هزار",M:"میلیون",Tweet:"توییت","Tweet %{hashtag}":"توییت کردن %{hashtag}","Tweet to %{name}":"به %{name} توییت کنید","Twitter Stream":"جریان توییت‌ها"},fi:{"%{followers_count} followers":"%{followers_count} seuraajaa","100K+":"100 000+","10k unit":"10 000 yksikköä",Follow:"Seuraa","Follow %{screen_name}":"Seuraa käyttäjää %{screen_name}",K:"tuhatta",M:"milj.",Tweet:"Twiittaa","Tweet %{hashtag}":"Twiittaa %{hashtag}","Tweet to %{name}":"Twiittaa käyttäjälle %{name}","Twitter Stream":"Twitter-virta"},fil:{"%{followers_count} followers":"%{followers_count} mga tagasunod","100K+":"100K+","10k unit":"10k yunit",Follow:"Sundan","Follow %{screen_name}":"Sundan si %{screen_name}",K:"K",M:"M",Tweet:"I-tweet","Tweet %{hashtag}":"I-tweet ang %{hashtag}","Tweet to %{name}":"Mag-Tweet kay %{name}","Twitter Stream":"Stream ng Twitter"},fr:{"%{followers_count} followers":"%{followers_count} abonnés","100K+":"100K+","10k unit":"unité de 10k",Follow:"Suivre","Follow %{screen_name}":"Suivre %{screen_name}",K:"K",M:"M",Tweet:"Tweeter","Tweet %{hashtag}":"Tweeter %{hashtag}","Tweet to %{name}":"Tweeter à %{name}","Twitter Stream":"Flux Twitter"},he:{"%{followers_count} followers":"%{followers_count} עוקבים","100K+":"מאות אלפים","10k unit":"עשרות אלפים",Follow:"מעקב","Follow %{screen_name}":"לעקוב אחר %{screen_name}",K:"אלף",M:"מיליון",Tweet:"ציוץ","Tweet %{hashtag}":"צייצו %{hashtag}","Tweet to %{name}":"ציוץ אל %{name}","Twitter Stream":"התזרים של טוויטר"},hi:{"%{followers_count} followers":"%{followers_count} फ़ॉलोअर्स","100K+":"1 लाख+","10k unit":"10 हजार इकाईयां",Follow:"फ़ॉलो","Follow %{screen_name}":"%{screen_name} को फ़ॉलो करें",K:"हजार",M:"मिलियन",Tweet:"ट्वीट","Tweet %{hashtag}":"ट्वीट %{hashtag}","Tweet to %{name}":"%{name} को ट्वीट करें","Twitter Stream":"ट्विटर स्ट्रीम"},hu:{"%{followers_count} followers":"%{followers_count} követő","100K+":"100E+","10k unit":"10E+",Follow:"Követés","Follow %{screen_name}":"%{screen_name} követése",K:"E",M:"M",Tweet:"Tweet","Tweet %{hashtag}":"%{hashtag} tweetelése","Tweet to %{name}":"Tweet küldése neki: %{name}","Twitter Stream":"Twitter Hírfolyam"},id:{"%{followers_count} followers":"%{followers_count} pengikut","100K+":"100 ribu+","10k unit":"10 ribu unit",Follow:"Ikuti","Follow %{screen_name}":"Ikuti %{screen_name}",K:"&nbsp;ribu",M:"&nbsp;juta",Tweet:"Tweet","Tweet %{hashtag}":"Tweet %{hashtag}","Tweet to %{name}":"Tweet ke %{name}","Twitter Stream":"Aliran Twitter"},it:{"%{followers_count} followers":"%{followers_count} follower","100K+":"100K+","10k unit":"10k unità",Follow:"Segui","Follow %{screen_name}":"Segui %{screen_name}",K:"K",M:"M",Tweet:"Tweet","Tweet %{hashtag}":"Twitta %{hashtag}","Tweet to %{name}":"Twitta a %{name}","Twitter Stream":"Twitter Stream"},ja:{"%{followers_count} followers":"%{followers_count}人のフォロワー","100K+":"100K以上","10k unit":"万",Follow:"フォローする","Follow %{screen_name}":"%{screen_name}さんをフォロー",K:"K",M:"M",Tweet:"ツイート","Tweet %{hashtag}":"%{hashtag} をツイートする","Tweet to %{name}":"%{name}さんへツイートする","Twitter Stream":"Twitterストリーム"},ko:{"%{followers_count} followers":"%{followers_count}명의 팔로워","100K+":"100만 이상","10k unit":"만 단위",Follow:"팔로우","Follow %{screen_name}":"%{screen_name} 팔로우하기",K:"천",M:"백만",Tweet:"트윗","Tweet %{hashtag}":"%{hashtag} 관련 트윗하기","Tweet to %{name}":"%{name}님에게 트윗하기","Twitter Stream":"트위터 스트림"},msa:{"%{followers_count} followers":"%{followers_count} pengikut","100K+":"100 ribu+","10k unit":"10 ribu unit",Follow:"Ikut","Follow %{screen_name}":"Ikut %{screen_name}",K:"ribu",M:"juta",Tweet:"Tweet","Tweet %{hashtag}":"Tweet %{hashtag}","Tweet to %{name}":"Tweet kepada %{name}","Twitter Stream":"Strim Twitter"},nl:{"%{followers_count} followers":"%{followers_count} volgers","100K+":"100k+","10k unit":"10k-eenheid",Follow:"Volgen","Follow %{screen_name}":"%{screen_name} volgen",K:"k",M:" mln.",Tweet:"Tweeten","Tweet %{hashtag}":"%{hashtag} tweeten","Tweet to %{name}":"Tweeten naar %{name}","Twitter Stream":"Twitter Stream"},no:{"%{followers_count} followers":"%{followers_count} følgere","100K+":"100K+","10k unit":"10k ",Follow:"Følg","Follow %{screen_name}":"Følg %{screen_name}",K:"K",M:"M",Tweet:"Tweet","Tweet %{hashtag}":"Tweet %{hashtag}","Tweet to %{name}":"Send tweet til %{name}","Twitter Stream":"Twitter-strøm"},pl:{"%{followers_count} followers":"%{followers_count} obserwujących","100K+":"100 tys.+","10k unit":"10 tys.",Follow:"Obserwuj","Follow %{screen_name}":"Obserwuj %{screen_name}",K:"tys.",M:"mln",Tweet:"Tweetnij","Tweet %{hashtag}":"Tweetnij %{hashtag}","Tweet to %{name}":"Tweetnij do %{name}","Twitter Stream":"Strumień Twittera"},pt:{"%{followers_count} followers":"%{followers_count} seguidores","100K+":"+100 mil","10k unit":"10 mil unidades",Follow:"Seguir","Follow %{screen_name}":"Seguir %{screen_name}",K:"Mil",M:"M",Tweet:"Tweetar","Tweet %{hashtag}":"Tweetar %{hashtag}","Tweet to %{name}":"Tweetar para %{name}","Twitter Stream":"Transmissões do Twitter"},ru:{"%{followers_count} followers":"Читатели: %{followers_count} ","100K+":"100 тыс.+","10k unit":"блок 10k",Follow:"Читать","Follow %{screen_name}":"Читать %{screen_name}",K:"тыс.",M:"млн.",Tweet:"Твитнуть","Tweet %{hashtag}":"Твитнуть %{hashtag}","Tweet to %{name}":"Твитнуть %{name}","Twitter Stream":"Поток в Твиттере"},sv:{"%{followers_count} followers":"%{followers_count} följare","100K+":"100K+","10k unit":"10k",Follow:"Följ","Follow %{screen_name}":"Följ %{screen_name}",K:"K",M:"M",Tweet:"Tweeta","Tweet %{hashtag}":"Tweeta %{hashtag}","Tweet to %{name}":"Tweeta till %{name}","Twitter Stream":"Twitterflöde"},th:{"%{followers_count} followers":"%{followers_count} ผู้ติดตาม","100K+":"100พัน+","10k unit":"หน่วย 10พัน",Follow:"ติดตาม","Follow %{screen_name}":"ติดตาม %{screen_name}",K:"พัน",M:"ล้าน",Tweet:"ทวีต","Tweet %{hashtag}":"ทวีต %{hashtag}","Tweet to %{name}":"ทวีตถึง %{name}","Twitter Stream":"ทวิตเตอร์สตรีม"},tr:{"%{followers_count} followers":"%{followers_count} takipçi","100K+":"+100 bin","10k unit":"10 bin birim",Follow:"Takip et","Follow %{screen_name}":"Takip et: %{screen_name}",K:"bin",M:"milyon",Tweet:"Tweetle","Tweet %{hashtag}":"Tweetle: %{hashtag}","Tweet to %{name}":"Tweetle: %{name}","Twitter Stream":"Twitter Akışı"},ur:{"%{followers_count} followers":"%{followers_count} فالورز","100K+":"1 لاکھ+","10k unit":"دس ہزار یونٹ",Follow:"فالو کریں","Follow %{screen_name}":"%{screen_name} کو فالو کریں",K:"ہزار",M:"ملین",Tweet:"ٹویٹ کریں","Tweet %{hashtag}":"ٹویٹ کریں %{hashtag}","Tweet to %{name}":"%{name} کو ٹویٹ کریں","Twitter Stream":"ٹوئٹر سٹریم"},"zh-cn":{"%{followers_count} followers":"%{followers_count} 关注者","100K+":"10万+","10k unit":"1万单元",Follow:"关注","Follow %{screen_name}":"关注 %{screen_name}",K:"千",M:"百万",Tweet:"发推","Tweet %{hashtag}":"以 %{hashtag} 发推","Tweet to %{name}":"发推给 %{name}","Twitter Stream":"Twitter 信息流"},"zh-tw":{"%{followers_count} followers":"%{followers_count} 位跟隨者","100K+":"超過十萬","10k unit":"1萬 單位",Follow:"跟隨","Follow %{screen_name}":"跟隨 %{screen_name}",K:"千",M:"百萬",Tweet:"推文","Tweet %{hashtag}":"推文%{hashtag}","Tweet to %{name}":"推文給%{name}"}};b.aug(m.prototype,{setLanguage:function(a){var b;a||(a=this.params().lang||this.dataAttr("lang")||p(this.srcEl)),a=a&&a.toLowerCase();if(!a)return this.lang="en";if(l[a])return this.lang=a;b=a.replace(/[\-_].*/,"");if(l[b])return this.lang=b;this.lang="en"},_:function(a,b){var c=this.lang;b=b||{};if(!c||!l.hasOwnProperty(c))c=this.lang="en";return a=l[c]&&l[c][a]||a,this.ringo(a,b,/%\{([\w_]+)\}/g)},ringo:function(a,b,c){return c=c||/\{\{([\w_]+)\}\}/g,a.replace(c,function(a,c){return b[c]!==undefined?b[c]:a})},add:function(a){j.list.push(this),j.byId[this.id]=a},create:function(a,b,c){return c["data-twttr-rendered"]=!0,f({url:a,css:b,className:this.classAttr.join(" "),id:this.id,attributes:c,replace:this.srcEl,insertTarget:this.targetEl})},params:function(){var a,b;return this.srcOb?b=this.srcOb:(a=this.srcEl&&this.srcEl.href&&this.srcEl.href.split("?")[1],b=a?e.decode(a):{}),this.params=function(){return b},b},dataAttr:function(a){return this.srcEl&&this.srcEl.getAttribute("data-"+a)},attr:function(a){return this.srcEl&&this.srcEl.getAttribute(a)},styles:{base:[["font","normal normal normal 11px/18px 'Helvetica Neue', Arial, sans-serif"],["margin","0"],["padding","0"],["whiteSpace","nowrap"]],button:[["fontWeight","bold"],["textShadow","0 1px 0 rgba(255,255,255,.5)"]],large:[["fontSize","13px"],["lineHeight","26px"]],vbubble:[["fontSize","16px"]]},width:function(){throw new Error(name+" not implemented")},height:function(){return this.size=="m"?20:28},minWidth:function(){},maxWidth:function(){},minHeight:function(){},maxHeight:function(){},dimensions:function(){function a(a){switch(typeof a){case"string":return a;case"undefined":return;default:return a+"px"}}var b,c={width:this.width(),height:this.height()};this.minWidth()&&(c["min-width"]=this.minWidth()),this.maxWidth()&&(c["max-width"]=this.maxWidth()),this.minHeight()&&(c["min-height"]=this.minHeight()),this.maxHeight()&&(c["max-height"]=this.maxHeight());for(b in c)c[b]=a(c[b]);return c},generateId:o}),m.afterLoad=function(a){k.push(a)},m.init=function(a){i=a},m.find=function(a){return a&&j.byId[a]?j.byId[a].element:null},m.embed=function(a){var b=i.widgets,c,e,f,g,h,k;a=a||document;for(f in b){f.match(/\./)?(g=f.split("."),c=d.all(g[1],a,g[0])):c=a.getElementsByTagName(f);for(h=0;k=c[h];h++){if(k.getAttribute("data-twttr-rendered"))continue;k.setAttribute("data-twttr-rendered","true"),e=new b[f](k),j.list.push(e),j.byId[e.id]=e,e.render(i)}}n()},a(m)})});
+provide("tfw/widget/intent",function(a){using("tfw/widget/base","util/util","util/querystring","util/uri",function(b,c,d,e){function m(a){var b=Math.round(k/2-h/2),c=0;j>i&&(c=Math.round(j/2-i/2)),window.open(a,undefined,[g,"width="+h,"height="+i,"left="+b,"top="+c].join(","))}function n(a,b){using("tfw/hub/client",function(c){c.openIntent(a,b)})}function o(a){var b="original_referer="+location.href;return[a,b].join(a.indexOf("?")==-1?"?":"&")}function p(a){a=a||window.event;var b=a.target||a.srcElement,c,d,e;while(b&&b.nodeName.toLowerCase()!=="a")b=b.parentNode;b&&b.nodeName.toLowerCase()==="a"&&b.href&&(c=b.href.match(f),c&&(e=o(b.href),e=e.replace(/^http[:]/,"https:"),e=e.replace(/^\/\//,"https://"),q(e,b),a.returnValue=!1,a.preventDefault&&a.preventDefault()))}function q(a,b){if(twttr.events.hub&&b){var c=new r(l.generateId(),b);l.add(c),n(a,b),twttr.events.trigger("click",{target:b,region:"intent",type:"click",data:{}})}else m(a)}function r(a,b){this.id=a,this.element=this.srcEl=b}function s(a){this.srcEl=[],this.element=a}var f=/twitter\.com(\:\d{2,4})?\/intent\/(\w+)/,g="scrollbars=yes,resizable=yes,toolbar=no,location=yes",h=550,i=520,j=screen.height,k=screen.width,l;s.prototype=new b,c.aug(s.prototype,{render:function(a){l=this,window.__twitterIntentHandler||(document.addEventListener?document.addEventListener("click",p,!1):document.attachEvent&&document.attachEvent("onclick",p),window.__twitterIntentHandler=!0)}}),s.open=q,a(s)})});
+provide("dom/classname",function(a){function b(a,b){a.classList?a.classList.add(b):f(b).test(a.className)||(a.className+=" "+b)}function c(a,b){a.classList?a.classList.remove(b):a.className=a.className.replace(f(b)," ")}function d(a,d,g){a.classList&&e(a,d)?(c(a,d),b(a,g)):a.className=a.className.replace(f(d),g)}function e(a,b){return a.classList?a.classList.contains(b):f(b).test(a.className)}function f(a){return new RegExp("\\b"+a+"\\b","g")}a({add:b,remove:c,replace:d,present:e})});
+provide("util/env",function(a){var b=window.navigator.userAgent;a({retina:function(){return(window.devicePixelRatio||1)>1},anyIE:function(){return/MSIE \d/.test(b)},ie6:function(){return/MSIE 6/.test(b)},ie7:function(){return/MSIE 7/.test(b)},cspEnabledIE:function(){return/MSIE 1\d/.test(b)},touch:function(){return"ontouchstart"in window||/Opera Mini/.test(b)||navigator.msMaxTouchPoints>0},cssTransitions:function(){var a=document.body.style;return a.transition!==undefined||a.webkitTransition!==undefined||a.mozTransition!==undefined||a.oTransition!==undefined||a.msTransition!==undefined}})});
+provide("dom/delegate",function(a){using("util/env",function(b){function e(a){var b=a.getAttribute("data-twitter-event-id");return b?b:(a.setAttribute("data-twitter-event-id",++d),d)}function f(a,b,c){var d=0,e=a&&a.length||0;for(d=0;d<e;d++)a[d].call(b,c)}function g(a,b,c){var d=c||a.target||a.srcElement,e=d.className.split(" "),h=0,i,j=e.length;for(;h<j;h++)f(b["."+e[h]],d,a);f(b[d.tagName],d,a);if(a.cease)return;d!==this&&g.call(this,a,b,d.parentElement||d.parentNode)}function h(a,b,c){if(a.addEventListener){a.addEventListener(b,function(d){g.call(a,d,c[b])},!1);return}a.attachEvent&&a.attachEvent("on"+b,function(){g.call(a,a.ownerDocument.parentWindow.event,c[b])})}function i(a,b,d,f){var g=e(a);c[g]=c[g]||{},c[g][b]||(c[g][b]={},h(a,b,c[g])),c[g][b][d]=c[g][b][d]||[],c[g][b][d].push(f)}function j(a,b,d){var f=e(b),h=c[f]&&c[f];g.call(b,{target:d},h[a])}function k(a){return m(a),l(a),!1}function l(a){a&&a.preventDefault?a.preventDefault():a.returnValue=!1}function m(a){a&&(a.cease=!0)&&a.stopPropagation?a.stopPropagation():a.cancelBubble=!0}var c={},d=-1;a({stop:k,stopPropagation:m,preventDefault:l,delegate:i,simulate:j})})});
+provide("util/throttle",function(a){function b(a,b,c){function g(){var c=+(new Date);window.clearTimeout(f);if(c-e>b){e=c,a.call(d);return}f=window.setTimeout(g,b)}var d=c||this,e=0,f;return g}a(b)});
+provide("util/insert",function(a){a(function(a,b){if(b){if(!b.parentNode)return b;b.parentNode.replaceChild(a,b),delete b}else document.body.insertBefore(a,document.body.firstChild);return a})});
+provide("util/datetime",function(a){using("util/util",function(b){function n(a){var e=a||"",h=e.toString(),i,j;return i=function(){var a;if(f.test(h))return parseInt(h,10);if(a=h.match(d))return Date.UTC(a[7],b.indexOf(g,a[1]),a[2],a[3],a[4],a[5]);if(a=h.match(c))return Date.UTC(a[1],a[2]-1,a[3],a[4],a[5],a[6])}(),i?(j=new Date(i),!isNaN(j.getTime())&&j):!1}function o(a,b){function q(a,b){return p&&p[a]&&(a=p[a]),a.replace(/%\{([\w_]+)\}/g,function(a,c){return b[c]!==undefined?b[c]:a})}var c=n(a),d=+(new Date),e=d-c,f,l=b&&b.months||g,o=b&&b.formats||{abbr:"%{number}%{symbol}",shortdate:"%{day} %{month}",longdate:"%{day} %{month} %{year}"},p=b&&b.phrases;return c?isNaN(e)||e<h*2?q("now"):e<i?(f=Math.floor(e/h),q(o.abbr,{number:f,symbol:q(m,{abbr:q("s"),expanded:f>1?q("seconds"):q("second")})})):e<j?(f=Math.floor(e/i),q(o.abbr,{number:f,symbol:q(m,{abbr:q("m"),expanded:f>1?q("minutes"):q("minute")})})):e<k?(f=Math.floor(e/j),q(o.abbr,{number:f,symbol:q(m,{abbr:q("h"),expanded:f>1?q("hours"):q("hour")})})):e<k*365?q(o.shortdate,{day:c.getDate(),month:q(l[c.getMonth()])}):q(o.longtime,{day:c.getDate(),month:q(l[c.getMonth()]),year:c.getFullYear().toString().slice(2)}):""}var c=/(\d{4})-?(\d{2})-?(\d{2})T(\d{2}):?(\d{2}):?(\d{2})(Z|[\+\-]\d{2}:?\d{2})/,d=/[a-z]{3,4} ([a-z]{3}) (\d{1,2}) (\d{1,2}):(\d{2}):(\d{2}) ([\+\-]\d{2}:?\d{2}) (\d{4})/i,e=/[a-z]{3,4}, (\d{1,2}) ([a-z]{3}) (\d{4}) (\d{1,2}):(\d{2}):(\d{2}) ([\+\-]\d{2}:?\d{2})/i,f=/^\d+$/,g=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],h=1e3,i=h*60,j=i*60,k=j*24,l=k*7,m='<abbr title="%{expanded}">%{abbr}</abbr>';a({parse:n,timeAgo:o})})});
+provide("util/css",function(a){using("util/util",function(b){a({sanitize:function(a,c,d){var e=/^[\w ,%\/"'\-_#]+$/,f=a&&b.map(a.split(";"),function(a){return b.map(a.split(":").slice(0,2),function(a){return b.trim(a)})}),g=0,h,i=[],j=d?"!important":"";c=c||/^(font|text\-|letter\-|color|line\-)[\w\-]*$/;for(;f&&(h=f[g]);g++)h[0].match(c)&&h[1].match(e)&&i.push(h.join(":")+j);return i.join(";")}})})});
+provide("tfw/util/params",function(a){using("util/querystring","util/twitter",function(b,c){a(function(a,d){return function(e){var f,g="data-tw-params",h,i=e.innerHTML;if(!e)return;if(!c.isTwitterURL(e.href))return;if(e.getAttribute(g))return;e.setAttribute(g,!0);if(typeof d=="function"){f=d.call(this,e);for(h in f)f.hasOwnProperty(h)&&(a[h]=f[h])}e.href=b.url(e.href,a),e.innerHTML=i}})})});
+provide("$xd/json2.js", function(exports) {window.JSON||(window.JSON={}),function(){function f(a){return a<10?"0"+a:a}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return typeof b=="string"?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c<f;c+=1)h[c]=str(c,i)||"null";return e=h.length===0?"[]":gap?"[\n"+gap+h.join(",\n"+gap)+"\n"+g+"]":"["+h.join(",")+"]",gap=g,e}if(rep&&typeof rep=="object"){f=rep.length;for(c=0;c<f;c+=1)d=rep[c],typeof d=="string"&&(e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e))}else for(d in i)Object.hasOwnProperty.call(i,d)&&(e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e));return e=h.length===0?"{}":gap?"{\n"+gap+h.join(",\n"+gap)+"\n"+g+"}":"{"+h.join(",")+"}",gap=g,e}}typeof Date.prototype.toJSON!="function"&&(Date.prototype.toJSON=function(a){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(a){return this.valueOf()});var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;typeof JSON.stringify!="function"&&(JSON.stringify=function(a,b,c){var d;gap="",indent="";if(typeof c=="number")for(d=0;d<c;d+=1)indent+=" ";else typeof c=="string"&&(indent=c);rep=b;if(!b||typeof b=="function"||typeof b=="object"&&typeof b.length=="number")return str("",{"":a});throw new Error("JSON.stringify")}),typeof JSON.parse!="function"&&(JSON.parse=function(text,reviver){function walk(a,b){var c,d,e=a[b];if(e&&typeof e=="object")for(c in e)Object.hasOwnProperty.call(e,c)&&(d=walk(e,c),d!==undefined?e[c]=d:delete e[c]);return reviver.call(a,b,e)}var j;cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),typeof reviver=="function"?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}();exports();loadrunner.Script.loaded.push("$xd/json2.js")});
+provide("util/params",function(a){using("util/querystring",function(b){var c=function(a){var c=a.search.substr(1);return b.decode(c)},d=function(a){var c=a.href,d=c.indexOf("#"),e=d<0?"":c.substring(d+1);return b.decode(e)},e=function(a){var b={},e=c(a),f=d(a);for(var g in e)e.hasOwnProperty(g)&&(b[g]=e[g]);for(var g in f)f.hasOwnProperty(g)&&(b[g]=f[g]);return b};a({combined:e,fromQuery:c,fromFragment:d})})});
+provide("tfw/util/env",function(a){using("util/params",function(b){function d(){var a=36e5,d=b.combined(document.location)._;return c!==undefined?c:(c=!1,d&&/^\d+$/.test(d)&&(c=+(new Date)-parseInt(d)<a),c)}var c;a({isDynamicWidget:d})})});
+provide("util/decider",function(a){function c(a){var c=b[a]||!1;if(!c)return!1;if(c===!0||c===100)return!0;var d=Math.random()*100,e=c>=d;return b[a]=e,e}var b={force_new_cookie:100,rufous_pixel:100,decider_fixture:12.34};a({isAvailable:c})});
+provide("dom/cookie",function(a){using("util/util",function(b){a(function(a,c,d){var e=b.aug({},d);if(arguments.length>1&&String(c)!=="[object Object]"){if(c===null||c===undefined)e.expires=-1;if(typeof e.expires=="number"){var f=e.expires,g=new Date((new Date).getTime()+f*60*1e3);e.expires=g}return c=String(c),document.cookie=[encodeURIComponent(a),"=",e.raw?c:encodeURIComponent(c),e.expires?"; expires="+e.expires.toUTCString():"",e.path?"; path="+e.path:"",e.domain?"; domain="+e.domain:"",e.secure?"; secure":""].join("")}e=c||{};var h,i=e.raw?function(a){return a}:decodeURIComponent;return(h=(new RegExp("(?:^|; )"+encodeURIComponent(a)+"=([^;]*)")).exec(document.cookie))?i(h[1]):null})})});
+provide("util/donottrack",function(a){using("dom/cookie",function(b){a(function(a){var c=/\.(gov|mil)(:\d+)?$/i,d=/https?:\/\/([^\/]+).*/i;return a=a||document.referrer,a=d.test(a)&&d.exec(a)[1],b("dnt")?!0:c.test(document.location.host)?!0:a&&c.test(a)?!0:document.navigator?document.navigator["doNotTrack"]==1:navigator?navigator["doNotTrack"]==1||navigator["msDoNotTrack"]==1:!1})})});
+provide("tfw/util/guest_cookie",function(a){using("dom/cookie","util/donottrack","util/decider",function(b,c,d){function f(){var a=b(e)||!1;if(!a)return;a.match(/^v3\:/)||g()}function g(){b(e)&&b(e,null,{domain:".twitter.com",path:"/"})}function h(){c()&&g()}var e="pid";a({set:h,destroy:g,forceNewCookie:f,guest_id_cookie:e})})});
+provide("dom/sandbox",function(a){using("util/domready","util/env",function(b,c){function e(a,b){var c,d,e;if(a.name){try{e=document.createElement('<iframe name="'+a.name+'"></iframe>')}catch(f){e=document.createElement("iframe"),e.name=a.name}delete a.name}else e=document.createElement("iframe");a.id&&(e.id=a.id,delete a.id);for(c in a)a.hasOwnProperty(c)&&e.setAttribute(c,a[c]);e.allowtransparency="true",e.scrolling="no",e.setAttribute("frameborder",0),e.setAttribute("allowtransparency",!0);for(d in b||{})b.hasOwnProperty(d)&&(e.style[d]=b[d]);return e}function f(a,b,c,d){var f;this.attrs=b||{},this.styles=c||{},this.appender=d,this.onReady=a,this.sandbox={},f=e(this.attrs,this.styles),f.onreadystatechange=f.onload=this.getCallback(this.onLoad),this.sandbox.frame=f,d?d(f):document.body.appendChild(f)}function g(a,c,d,e){b(function(){new f(a,c,d,e)})}var d=0;window.twttr||(window.twttr={}),window.twttr.sandbox||(window.twttr.sandbox={}),f.prototype.getCallback=function(a){var b=this,c=!1;return function(){c||(c=!0,a.call(b))}},f.prototype.registerCallback=function(a){var b="cb"+d++;return window.twttr.sandbox[b]=a,b},f.prototype.onLoad=function(){try{this.sandbox.frame.contentWindow.document}catch(a){this.setDocDomain();return}this.sandbox.win=this.sandbox.frame.contentWindow,this.sandbox.doc=this.sandbox.frame.contentWindow.document,this.writeStandardsDoc(),this.sandbox.body=this.sandbox.frame.contentWindow.document.body,this.onReady(this.sandbox)},f.prototype.setDocDomain=function(){var a,b=this.registerCallback(this.getCallback(this.onLoad));a=["javascript:",'document.write("");',"try { window.parent.document; }","catch (e) {",'document.domain="'+document.domain+'";',"}",'window.parent.twttr.sandbox["'+b+'"]();'].join(""),this.sandbox.frame.parentNode.removeChild(this.sandbox.frame),this.sandbox.frame=null,this.sandbox.frame=e(this.attrs,this.styles),this.sandbox.frame.src=a,this.appender?this.appender(this.sandbox.frame):document.body.appendChild(this.sandbox.frame)},f.prototype.writeStandardsDoc=function(){if(!c.anyIE()||c.cspEnabledIE())return;var a=["<!DOCTYPE html>","<html>","<head>","<scr","ipt>","try { window.parent.document; }",'catch (e) {document.domain="'+document.domain+'";}',"</scr","ipt>","</head>","<body></body>","</html>"].join("");this.sandbox.doc.write(a),this.sandbox.doc.close()},a(g)})});
+provide("tfw/util/tracking",function(a){using("dom/cookie","dom/sandbox","util/donottrack","tfw/util/guest_cookie","tfw/util/env","util/util","$xd/json2.js",function(b,c,d,e,f,g,h){function u(){function a(a){s=a.frame,r=a.doc,q=a.doc.body,m=F(),n=G();while(o[0])z.apply(this,o.shift());p&&A()}s=document.getElementById("rufous-sandbox"),s?(r=s.contentWindow.document,q=r.body):c(a,{id:"rufous-sandbox"},{display:"none"})}function v(a,b,c,d){var e=!g.isObject(a),f=b?!g.isObject(b):!1,h,i;if(e||f)return;if(/Firefox/.test(navigator.userAgent))return;h=C(a),i=D(b,!!c,!!d),y(h,i,!0)}function w(a,c,h,i){var k=j[c],l,m,n=e.guest_id_cookie;if(!k)return;a=a||{},i=!!i,h=!!h,m=a.original_redirect_referrer||document.referrer,i=i||d(m),l=g.aug({},a),h||(x(l,"referrer",m),x(l,"widget",+f.isDynamicWidget()),x(l,"hask",+!!b("k")),x(l,"li",+!!b("twid")),x(l,n,b(n)||"")),i&&(x(l,"dnt",1),I(l)),H(k+"?"+E(l))}function x(a,b,c){var d=i+b;if(!a)return;return a[d]=c,a}function y(a,b,c){var d,e,f,h,i,j="https://r.twimg.com/jot?";if(!g.isObject(a)||!g.isObject(b))return;if(Math.random()>t)return;f=g.aug({},b,{event_namespace:a}),c?(j+=E({l:J(f)}),H(j)):(d=m.firstChild,d.value=+d.value||+f.dnt,h=J(f),e=r.createElement("input"),e.type="hidden",e.name="l",e.value=h,m.appendChild(e))}function z(a,b,c,d){var e=!g.isObject(a),f=b?!g.isObject(b):!1,h,i;if(e||f)return;if(!q||!m){o.push([a,b,c,d]);return}h=C(a),i=D(b,!!c,!!d),y(h,i)}function A(){if(!m){p=!0;return}if(m.children.length<=1)return;q.appendChild(m),q.appendChild(n),m.submit(),window.setTimeout(B(m,n),6e4),m=F(),n=G()}function B(a,b){return function(){var c=a.parentNode;c.removeChild(a),c.removeChild(b)}}function C(a){var b={client:"tfw"},c,d;return c=g.aug(b,a||{}),c}function D(a,b,c){var e={_category_:"tfw_client_event"},f,h,i;return b=!!b,c=!!c,f=g.aug(e,a||{}),h=f.widget_origin||document.referrer,f.format_version=1,f.dnt=c=c||d(h),f.triggered_on=f.triggered_on||+(new Date),b||(f.widget_origin=h),c&&I(f),f}function E(a){var b=[],c,d,e;for(c in a)a.hasOwnProperty(c)&&(d=encodeURIComponent(c),e=encodeURIComponent(a[c]),e=e.replace(/'/g,"%27"),b.push(d+"="+e));return b.join("&")}function F(){var a=r.createElement("form"),b=r.createElement("input");return l++,a.action="https://r.twimg.com/jot",a.method="POST",a.target="rufous-frame-"+l,a.id="rufous-form-"+l,b.type="hidden",b.name="dnt",b.value=0,a.appendChild(b),a}function G(){var a,b="rufous-frame-"+l,c=0;try{a=r.createElement("<iframe name="+b+">")}catch(d){a=r.createElement("iframe"),a.name=b}return a.id=b,a.style.display="none",a.width=0,a.height=0,a.border=0,a}function H(a){var b=document.createElement("img");b.src=a,b.alt="",b.style.position="absolute",b.style.height="1px",b.style.width="1px",b.style.top="-9999px",b.style.left="-9999px",document.body.appendChild(b)}function I(a){var b;for(b in a)~g.indexOf(k,b)&&delete a[b]}function J(a){var b=Array.prototype.toJSON,c;return delete Array.prototype.toJSON,c=JSON.stringify(a),b&&(Array.prototype.toJSON=b),c}var i="twttr_",j={tweetbutton:"//p.twitter.com/t.gif",followbutton:"//p.twitter.com/f.gif",tweetembed:"//p.twitter.com/e.gif"},k=["hask","li","logged_in","pid","user_id",e.guest_id_cookie,i+"hask",i+"li",i+e.guest_id_cookie],l=0,m,n,o=[],p,q,r,s,t=1;e.forceNewCookie(),a({enqueue:z,flush:A,initPostLogging:u,addPixel:v,addLegacyPixel:w,addVar:x})})});
+provide("util/logger",function(a){function c(a){window[b]&&window[b].log&&window[b].log(a)}function d(a){window[b]&&window[b].warn&&window[b].warn(a)}function e(a){window[b]&&window[b].error&&window[b].error(a)}var b=["con","sole"].join("");a({info:c,warn:d,error:e})});
+provide("tfw/util/data",function(a){using("util/logger","util/util","util/querystring",function(b,c,d){function l(a,b){return a=={}.toString.call(b).match(/\s([a-zA-Z]+)/)[1].toLowerCase()}function m(a){return function(c){c.error?a.error&&a.error(c):c.headers&&c.headers.status!=200?(a.error&&a.error(c),b.warn(c.headers.message)):a.success&&a.success(c),a.complete&&a.complete(c),n(a)}}function n(a){var b=a.script;b&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),a.script=undefined,b=undefined),a.callbackName&&twttr.tfw.callbacks[a.callbackName]&&delete twttr.tfw.callbacks[a.callbackName]}function o(a){var b={};return a.success&&l("function",a.success)&&(b.success=a.success),a.error&&l("function",a.error)&&(b.error=a.error),a.complete&&l("function",a.complete)&&(b.complete=a.complete),b}function p(a,b,c){var d=a.length,e=[],f={},g=0;return function(e){var h,i=[],j=[],k=[],l,m;h=c(e),f[h]=e;if(++g===d){for(l=0;l<d;l++)m=f[a[l]],i.push(m),m.error?k.push(m):j.push(m);b.error&&k.length>0&&b.error(k),b.success&&j.length>0&&b.success(j),b.complete&&b.complete(i)}}}twttr=twttr||{},twttr.tfw=twttr.tfw||{},twttr.tfw.callbacks=twttr.tfw.callbacks||{};var e="twttr.tfw.callbacks",f=twttr.tfw.callbacks,g="cb",h=0,i=!1,j={},k={userLookup:"//api.twitter.com/1/users/lookup.json",userShow:"//cdn.api.twitter.com/1/users/show.json",status:"//cdn.api.twitter.com/1/statuses/show.json",tweets:"//syndication.twimg.com/tweets.json",count:"//cdn.api.twitter.com/1/urls/count.json",friendship:"//cdn.api.twitter.com/1/friendships/exists.json",timeline:"//cdn.syndication.twimg.com/widgets/timelines/",timelinePoll:"//syndication.twimg.com/widgets/timelines/paged/",timelinePreview:"//syndication.twimg.com/widgets/timelines/preview/"};twttr.widgets&&twttr.widgets.endpoints&&c.aug(k,twttr.widgets.endpoints),j.jsonp=function(a,b,c){var j=c||g+h,k=e+"."+j,l=document.createElement("script"),n={callback:k,suppress_response_codes:!0};f[j]=m(b);if(i||!/^https?\:$/.test(window.location.protocol))a=a.replace(/^\/\//,"https://");l.src=d.url(a,n),l.async="async",document.body.appendChild(l),b.script=l,b.callbackName=j,c||h++},j.config=function(a){if(a.forceSSL===!0||a.forceSSL===!1)i=a.forceSSL},j.user=function(){var a,b={},c,e,f;arguments.length===1?(a=arguments[0].screenName,b=o(arguments[0])):(a=arguments[0],b.success=arguments[1]),c=l("array",a)?k.userLookup:k.userShow,a=l("array",a)?a.join(","):a,e={screen_name:a},f=d.url(c,e),this.jsonp(f,b)},j.userById=function(a){var b,c={},e,f,g;arguments.length===1?(b=arguments[0].ids,c=o(arguments[0])):(b=arguments[0],c.success=arguments[1]),e=l("array",b)?k.userLookup:k.userShow,b=l("array",b)?b.join(","):b,f={user_id:b},g=d.url(e,f),this.jsonp(g,c)},j.status=function(){var a,b={},c,e,f,g;arguments.length===1?(a=arguments[0].id,b=o(arguments[0])):(a=arguments[0],b.success=arguments[1]);if(!l("array",a))c={id:a,include_entities:!0},e=d.url(k.status,c),this.jsonp(e,b);else{f=p(a,b,function(a){return a.error?a.request.split("id=")[1].split("&")[0]:a.id_str});for(g=0;g<a.length;g++)c={id:a[g],include_entities:!0},e=d.url(k.status,c),this.jsonp(e,{success:f,error:f})}},j.tweets=function(a){var b=arguments[0],c=o(b),e={ids:a.ids.join(","),lang:a.lang},f=d.url(k.tweets,e);this.jsonp(f,c)},j.count=function(){var a="",b,c,e={};arguments.length===1?(a=arguments[0].url,e=o(arguments[0])):arguments.length===2&&(a=arguments[0],e.success=arguments[1]),c={url:a},b=d.url(k.count,c),this.jsonp(b,e)},j.friendshipExists=function(a){var b=arguments[0],c=o(arguments[0]),e={screen_name_a:a.screenNameA,screen_name_b:a.screenNameB},f=d.url(k.friendship,e);this.jsonp(f,c)},j.timeline=function(a){var b=arguments[0],c=o(b),e,f=9e5,g=Math.floor(+(new Date)/f),h={lang:a.lang,t:g,domain:window.location.host};a.dnt&&(h.dnt=a.dnt),a.screenName&&(h.screen_name=a.screenName),a.userId&&(h.user_id=a.userId),a.withReplies&&(h.with_replies=a.withReplies),e=d.url(k.timeline+a.id,h),this.jsonp(e,c,"tl_"+a.id)},j.timelinePoll=function(a){var b=arguments[0],c=o(b),e={lang:a.lang,since_id:a.sinceId,max_id:a.maxId,domain:window.location.host},f;a.dnt&&(e.dnt=a.dnt),a.screenName&&(e.screen_name=a.screenName),a.userId&&(e.user_id=a.userId),a.withReplies&&(e.with_replies=a.withReplies),f=d.url(k.timelinePoll+a.id,e),this.jsonp(f,c,"tlPoll_"+a.id+"_"+(a.sinceId||a.maxId))},j.timelinePreview=function(a){var b=arguments[0],c=o(b),e=a.params,f=d.url(k.timelinePreview,e);this.jsonp(f,c)},a(j)})});
+provide("anim/transition",function(a){function b(a,b){var c;return b=b||window,c=b.requestAnimationFrame||b.webkitRequestAnimationFrame||b.mozRequestAnimationFrame||b.msRequestAnimationFrame||b.oRequestAnimationFrame||function(c){b.setTimeout(function(){a(+(new Date))},1e3/60)},c(a)}function c(a,b){return Math.sin(Math.PI/2*b)*a}function d(a,c,d,e,f){function i(h){var j=h-g,k=Math.min(j/d,1),l=e?e(c,k):c*k;a(l);if(k==1)return;b(i,f)}var g=+(new Date),h;b(i)}a({animate:d,requestAnimationFrame:b,easeOut:c})});
+provide("tfw/util/assets",function(a){using("util/env",function(b){function d(a,d){var e=c[a],f;return b.retina()?f="2x":b.ie6()||b.ie7()?f="gif":f="default",d&&(f+=".rtl"),e[f]}var c={"embed/timeline.css":{"default":"embed/timeline.996256af577d2c3d78784b9bf8b648c6.default.css","2x":"embed/timeline.996256af577d2c3d78784b9bf8b648c6.2x.css",gif:"embed/timeline.996256af577d2c3d78784b9bf8b648c6.gif.css","default.rtl":"embed/timeline.996256af577d2c3d78784b9bf8b648c6.default.rtl.css","2x.rtl":"embed/timeline.996256af577d2c3d78784b9bf8b648c6.2x.rtl.css","gif.rtl":"embed/timeline.996256af577d2c3d78784b9bf8b648c6.gif.rtl.css"},"embed/embed.6c27ff0b627db7ce46be4331ae68cf0a.css":{"default":"embed/embed.default.css","2x":"embed/embed.2x.css",gif:"embed/embed.gif.css","default.rtl":"embed/embed.default.rtl.css","2x.rtl":"embed/embed.2x.rtl.css","gif.rtl":"embed/embed.gif.rtl.css"}};a(d)})});
+provide("tfw/widget/syndicatedbase",function(a){using("tfw/widget/base","tfw/widget/intent","tfw/util/assets","tfw/util/globals","dom/classname","dom/delegate","dom/sandbox","util/env","util/twitter","util/util",function(b,c,d,e,f,g,h,i,j,k){function q(){var a=e.val("widgets:link-color");o=t.VALID_COLOR.test(a)&&RegExp.$1,p=e.val("widgets:theme")}function r(a,b,c){var d;c=c||document;if(c.getElementById(a))return;d=c.createElement("link"),d.id=a,d.rel="stylesheet",d.type="text/css",d.href=twttr.widgets.config.assetUrl()+"/"+b,c.getElementsByTagName("head")[0].appendChild(d)}function s(a){var b=f.present(document.documentElement,"twitter-dev")?"components/syndication-templates/lib/css/index.css":d("embed/timeline.css");r("twitter-widget-css",b,a)}function t(a){if(!a)return;var c,d,e=this;this.sandboxReadyCallbacks=[],b.apply(this,[a]),c=this.params(),this.targetEl=this.srcEl&&this.srcEl.parentNode||c.targetEl||document.body,this.containerWidth=this.targetEl&&this.targetEl.offsetWidth,d=c.width||this.attr("width")||this.containerWidth||this.dimensions.DEFAULT_WIDTH,this.height=t.VALID_UNIT.test(c.height||this.attr("height"))&&RegExp.$1,this.width=Math.max(this.dimensions.MIN_WIDTH,Math.min(t.VALID_UNIT.test(d)?RegExp.$1:this.dimensions.DEFAULT_WIDTH,this.dimensions.DEFAULT_WIDTH)),this.narrow=c.narrow||this.width<=this.dimensions.NARROW_WIDTH,this.narrow&&this.classAttr.push("var-narrow"),t.VALID_COLOR.test(c.linkColor||this.dataAttr("link-color"))?this.linkColor=RegExp.$1:this.linkColor=o,this.theme=c.theme||this.attr("data-theme")||p,this.theme=/(dark|light)/.test(this.theme)?this.theme:"",this.classAttr.push(i.touch()?"is-touch":"not-touch"),h(function(a){e.sandboxReady=!0,e.setupSandbox.call(e,a)},{"class":this.renderedClassNames,id:this.id},{width:"1px",height:"1px",border:"none",position:"absolute"},function(a){e.srcEl?e.targetEl.insertBefore(a,e.srcEl):e.targetEl.appendChild(a)})}var l=[".customisable",".customisable:link",".customisable:visited",".customisable:hover",".customisable:active",".customisable-highlight:hover","a:hover .customisable-highlight","a:focus .customisable-highlight"],m=["a:hover .ic-mask","a:focus .ic-mask"],n=[".timeline-header h1.summary",".timeline-header h1.summary a:link",".timeline-header h1.summary a:visited"],o,p;t.prototype=new b,k.aug(t.prototype,{setupSandbox:function(a){var b=a.doc,c=b.createElement("base"),d=b.createElement("style"),f=b.getElementsByTagName("head")[0],g="body{display:none}",h=this,i;this.sandbox=a,a.frame.title=this.a11yTitle,s(a.doc),c.target="_blank",f.appendChild(c),e.val("widgets:csp")!="on"&&(d.type="text/css",d.styleSheet?d.styleSheet.cssText=g:d.appendChild(b.createTextNode(g)),f.appendChild(d)),this.handleResize&&window.addEventListener?window.addEventListener("resize",function(){h.handleResize()},!0):document.body.attachEvent("onresize",function(){h.handleResize()}),a.win.onresize=function(a){h.handleResize&&h.handleResize()},this.frameIsReady=!0;for(;i=this.sandboxReadyCallbacks.shift();)i.fn.apply(i.context,i.args)},callsWhenSandboxReady:function(a){var b=this;return function(){var c=[],d=arguments.length,e=0;for(;e<d;e++)c.push(arguments[e]);b.callIfSandboxReady(a,b,c)}},callIfSandboxReady:function(a,b,c){c=c||[],b.frameIsReady?a.apply(b,[!1].concat(c)):b.sandboxReadyCallbacks.push({fn:a,context:b,args:[!0].concat(c)})},contentWidth:function(){return this.width-(this.narrow?this.dimensions.NARROW_MEDIA_PADDING:this.dimensions.WIDE_MEDIA_PADDING)},addSiteStyles:function(){var a=this,b=this.sandbox.doc,c=this.id+"-styles",d,f=0,g=function(b){return(a.theme=="dark"?".thm-dark ":"")+b},h="",i="",j="";if(e.val("widgets:csp")=="on")return;if(b.getElementById(c))return;this.headingStyle&&(j=k.map(n,g).join(",")+"{"+this.headingStyle+"}"),this.linkColor&&(h=k.map(l,g).join(",")+"{color:"+this.linkColor+"}",i=k.map(m,g).join(",")+"{background-color:"+this.linkColor+"}");if(!h&&!i&&!j)return;d=b.createElement("style"),d.id=c,d.type="text/css",d.styleSheet?d.styleSheet.cssText=h+i+j:(d.appendChild(b.createTextNode(h)),d.appendChild(b.createTextNode(i)),d.appendChild(b.createTextNode(j))),b.getElementsByTagName("head")[0].appendChild(d)},bindIntentHandlers:function(){var a=this,b=this.element;g.delegate(b,"click",".profile",function(b){var d;a.addUrlParams(this),d=j.intentForProfileURL(this.href),d&&(c.open(d),g.preventDefault(b))}),g.delegate(b,"click",".web-intent",function(b){a.addUrlParams(this),c.open(this.href),g.preventDefault(b)})}}),t.VALID_UNIT=/^([0-9]+)( ?px)?$/,t.VALID_COLOR=/^(#(?:[0-9a-f]{3}|[0-9a-f]{6}))$/i,t.retinize=function(a){if(!i.retina())return;var b=a.getElementsByTagName("IMG"),c,d,e=0,f=b.length;for(;e<f;e++)c=b[e],d=c.getAttribute("data-src-2x"),d&&(c.src=d)},t.scaleDimensions=function(a,b,c,d){return b>a&&b>d?(a*=d/b,b=d):a>c&&(b*=c/a,a=c,b>d&&(a*=d/b,b=d)),{width:Math.ceil(a),height:Math.ceil(b)}},t.constrainMedia=function(a,b){var c=a.getElementsByTagName("IMG"),d=a.getElementsByTagName("IFRAME"),e,f,g,h=0,i=0,j;for(;e=[c,d][i];i++)if(e.length)for(j=0;f=e[j];j++)g=t.scaleDimensions(f.getAttribute("width")||f.width,f.getAttribute("height")||f.height,b,375),g.width>0&&(f.width=g.width),g.height>0&&(f.height=g.height),h=g.height>h?g.height:h;return h},q(),a(t)})});
+provide("tfw/widget/timeline",function(a){using("tfw/widget/syndicatedbase","anim/transition","tfw/widget/intent","tfw/util/data","tfw/util/tracking","tfw/util/params","util/css","util/datetime","util/env","util/iframe","util/insert","util/throttle","util/twitter","util/querystring","util/util","dom/delegate","dom/classname","dom/get",function(b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s){function O(a){if(!a)return;var c;this.a11yTitle=this._("Twitter Timeline Widget"),b.apply(this,[a]),c=this.params(),this.preview=c.previewParams,this.widgetId=c.widgetId||this.dataAttr("widget-id"),this.widgetScreenName=c.screenName||this.dataAttr("screen-name"),this.widgetUserId=c.userId||this.dataAttr("user-id");if(c.showReplies===!0||this.dataAttr("show-replies")=="true")this.widgetShowReplies="true";this.chromeless=(c.chrome||this.dataAttr("chrome"))=="none",this.headingStyle=h.sanitize(c.headingStyle||this.dataAttr("heading-style"),undefined,!0),this.classAttr.push("twitter-timeline-rendered"),this.ariaPolite=c.ariaPolite||this.dataAttr("aria-polite")}function P(a,c){var d=a.ownerDocument,e=s.one(D,a,"DIV"),f=e.children[0],g=f.getAttribute("data-expanded-media"),h,i=0,j=s.one(E,a,"A"),k=j&&j.getElementsByTagName("B")[0],l=k&&(k.innerText||k.textContent),m;if(!k)return;k.innerHTML=j.getAttribute("data-toggled-text"),j.setAttribute("data-toggled-text",l);if(r.present(a,C)){r.remove(a,C),e.style.cssText="";return}g&&(h=d.createElement("DIV"),h.innerHTML=g,b.retinize(h),i=b.constrainMedia(h,c),f.removeAttribute("data-expanded-media"),f.appendChild(h)),m=Math.max(f.offsetHeight,i),e.style.cssText="height:"+m+"px",r.add(a,C)}var t="1.0",u={CLIENT_SIDE_USER:0,CLIENT_SIDE_APP:2},v="timeline",w="new-tweets-bar",x="timeline-header",y="timeline-footer",z="stream",A="h-feed",B="tweet",C="expanded",D="detail-expander",E="expand",F="permalink",G="twitter-tweet-box",H="tweet-box-button",I="twitter-follow-button",J="no-more-pane",K="pending-scroll-in",L="pending-new-tweet",M="show-new-tweet",N="show-tweet-box";O.prototype=new b,p.aug(O.prototype,{renderedClassNames:"twitter-timeline twitter-timeline-rendered",dimensions:{DEFAULT_HEIGHT:"600",DEFAULT_WIDTH:"520",NARROW_WIDTH:"320",MIN_WIDTH:"220",MIN_HEIGHT:"350",WIDE_MEDIA_PADDING:81,NARROW_MEDIA_PADDING:16},create:function(a){var c=this.sandbox.doc.createElement("div"),d,e=this,g,h,i,j=[],k,l;c.innerHTML=a.body,d=c.children[0]||!1;if(!d)return;this.reconfigure(a.config),this.augmentWidgets(d),b.retinize(d),b.constrainMedia(d,this.contentWidth()),this.searchQuery=d.getAttribute("data-search-query"),this.profileId=d.getAttribute("data-profile-id"),k=this.getTweetDetails(c);for(l in k)k.hasOwnProperty(l)&&j.push(l);return f.enqueue({page:"timeline",component:"timeline",element:"initial",action:j.length?"results":"no_results"},{widget_id:this.widgetId,widget_origin:document.location.href,item_ids:j,item_details:k,client_version:t,message:this.partner,query:this.searchQuery,profile_id:this.profileId},!0,this.dnt),f.flush(),this.ariaPolite=="assertive"&&(h=s.one(w,d,"DIV"),h.setAttribute("aria-polite","assertive")),d.id=this.id,d.className+=" "+this.classAttr.join(" "),d.lang=this.lang,twttr.widgets.load(d),i=function(){e.sandbox.body.appendChild(d),e.sandbox.win.setTimeout(function(){var a=s.one(x,d,"DIV"),b=s.one(y,d,"DIV"),c=s.one(z,d,"DIV");b?g=a.offsetHeight+b.offsetHeight:g=a.offsetHeight,c.style.cssText="height:"+(e.height-g-2)+"px"},500),e.sandbox.frame.style.cssText="",e.sandbox.frame.width=e.width,e.sandbox.frame.height=e.height,e.sandbox.frame.style.border="none",e.sandbox.frame.style.maxWidth="100%",e.sandbox.frame.style.minWidth=e.dimensions.MIN_WIDTH+"px"},this.callsWhenSandboxReady(i)(),this.srcEl&&this.srcEl.parentNode&&this.srcEl.parentNode.removeChild(this.srcEl),d},render:function(a,b){function j(){d.success=function(a){c.element=c.create(a),c.readTranslations(),c.bindInteractions(),b&&b(c.sandbox.frame);return},d.error=function(a){a&&a.headers&&b&&b(a.headers.status)},d.params=c.preview,e.timelinePreview(d);return}function k(){f.initPostLogging(),e.timeline({id:c.widgetId,screenName:c.widgetScreenName,userId:c.widgetUserId,withReplies:c.widgetShowReplies,dnt:c.dnt,lang:c.lang,success:function(a){c.element=c.create(a),c.readTranslations(),c.bindInteractions(),a.headers.xPolling&&/\d/.test(a.headers.xPolling)&&(c.pollInterval=a.headers.xPolling*1e3),c.updateTimeStamps(),c.schedulePolling(),b&&b(c.sandbox.frame);return},error:function(a){a&&a.headers&&b&&b(a.headers.status)}})}var c=this,d={},g,h,i;if(!this.preview&&!this.widgetId){b&&b(400);return}i=this.preview?j:k,this.sandboxReady?i():window.setTimeout(i,0)},reconfigure:function(a){this.lang=a.lang,this.theme||(this.theme=a.theme),this.theme=="dark"&&this.classAttr.push("thm-dark"),this.chromeless&&this.classAttr.push("var-chromeless"),!this.linkColor&&a.linkColor&&b.VALID_COLOR.test(a.linkColor)&&(this.linkColor=RegExp.$1),this.addSiteStyles(),!this.height&&b.VALID_UNIT.test(a.height)&&(this.height=RegExp.$1),this.height=Math.max(this.dimensions.MIN_HEIGHT,this.height?this.height:this.dimensions.DEFAULT_HEIGHT),this.preview&&this.classAttr.push("var-preview"),this.narrow=this.width<=this.dimensions.NARROW_WIDTH,this.narrow&&this.classAttr.push("var-narrow")},getTweetDetails:function(a){var b=s.all(B,a,"LI"),c={},d,e,f,g,h={TWEET:0,RETWEET:10},i=0;for(;d=b[i];i++)e=s.one(F,d,"A"),f=n.status(e.href),g=d.getAttribute("data-tweet-id"),f===g?c[f]={item_type:h.TWEET}:c[f]={item_type:h.RETWEET,target_type:h.TWEET,target_id:g};return c},bindInteractions:function(){var a=this,b=this.element,c=!0;this.bindIntentHandlers(),q.delegate(b,"click","."+E,function(c){P(s.ancestor("."+B,this,b),a.contentWidth()),q.stop(c)}),q.delegate(b,"click","A",function(a){q.stopPropagation(a)}),q.delegate(b,"click",".with-expansion",function(b){P(this,a.contentWidth()),q.stop(b)}),q.delegate(b,"click",".load-more",function(b){a.loadMore()}),q.delegate(b,"click","."+w,function(b){a.scrollToTop(),a.hideNewTweetNotifier(!0)}),q.delegate(b,"click",".load-tweets",function(b){c&&(c=!1,a.forceLoad(),q.stop(b))}),q.delegate(b,"click",".display-sensitive-image",function(c){a.showNSFW(s.ancestor("."+B,this,b)),q.stop(c)}),q.delegate(b,"mouseover","."+v,function(b){a.mouseOver=!0}),q.delegate(b,"mouseout","."+v,function(b){a.mouseOver=!1}),q.delegate(b,"mouseover","."+w,function(b){a.mouseOverNotifier=!0}),q.delegate(b,"mouseout","."+w,function(b){a.mouseOverNotifier=!1,window.setTimeout(function(){a.hideNewTweetNotifier()},3e3)})},scrollToTop:function(){var a=s.one(z,this.element,"DIV");a.scrollTop=0,a.focus()},update:function(){var a=this,b=s.one(B,this.element,"LI"),c=b&&b.getAttribute("data-tweet-id");this.updateTimeStamps(),this.requestTweets(c,!0,function(b){b.childNodes.length>0&&a.insertNewTweets(b)})},loadMore:function(){var a=this,b=s.all(B,this.element,"LI").pop(),c=b&&b.getAttribute("data-tweet-id");this.requestTweets(c,!1,function(b){var d=s.one(J,a.element,"P"),e=b.childNodes[0];d.style.cssText="",e&&e.getAttribute("data-tweet-id")==c&&b.removeChild(e);if(b.childNodes.length>0){a.appendTweets(b);return}r.add(a.element,"no-more"),d.focus()})},forceLoad:function(){var a=this,b=!!s.all(A,this.element,"OL").length;this.requestTweets(1,!0,function(c){c.childNodes.length&&(a[b?"insertNewTweets":"appendTweets"](c),r.add(a.element,"has-tweets"))})},schedulePolling:function(a){var b=this;if(this.pollInterval===null)return;a=twttr.widgets.poll||a||this.pollInterval||1e4,a>-1&&window.setTimeout(function(){this.isUpdating||b.update(),b.schedulePolling()},a)},requestTweets:function(a,c,d){var g=this,h={id:this.widgetId,screenName:this.widgetScreenName,userId:this.widgetUserId,withReplies:this.widgetShowReplies,dnt:this.dnt,lang:this.lang};h[c?"sinceId":"maxId"]=a,h.complete=function(){this.isUpdating=!1},h.error=function(a){if(a&&a.headers){if(a.headers.status=="404"){g.pollInterval=null;return}if(a.headers.status=="503"){g.pollInterval*=1.5;return}}},h.success=function(a){var e=g.sandbox.doc.createDocumentFragment(),h=g.sandbox.doc.createElement("div"),i=[],j,k;a&&a.headers&&a.headers.xPolling&&/\d+/.test(a.headers.xPolling)&&(g.pollInterval=a.headers.xPolling*1e3);if(a&&a.body!==undefined){h.innerHTML=a.body;if(h.children[0]&&h.children[0].tagName!="LI")return;j=g.getTweetDetails(h);for(k in j)j.hasOwnProperty(k)&&i.push(k);i.length&&(f.enqueue({page:"timeline",component:"timeline",element:c?"newer":"older",action:"results"},{widget_id:g.widgetId,widget_origin:document.location.href,item_ids:i,item_details:j,client_version:t,message:g.partner,query:g.searchQuery,profile_id:g.profileId,event_initiator:c?u.CLIENT_SIDE_APP:u.CLIENT_SIDE_USER},!0,g.dnt),f.flush()),b.retinize(h),b.constrainMedia(h,g.contentWidth());while(h.children[0])e.appendChild(h.children[0]);d(e)}},e.timelinePoll(h)},insertNewTweets:function(a){var b=this,d=s.one(z,this.element,"DIV"),e=s.one(A,d,"OL"),f=e.offsetHeight,g;this.updateTimeStamps(),e.insertBefore(a,e.firstChild),g=e.offsetHeight-f;if(d.scrollTop>40||this.mouseIsOver()){d.scrollTop=d.scrollTop+g,this.showNewTweetNotifier();return}r.remove(this.element,K),e.style.cssText="margin-top: -"+g+"px",window.setTimeout(function(){d.scrollTop=0,r.add(b.element,K),j.cssTransitions()?e.style.cssText="":c.animate(function(a){a<g?e.style.cssText="margin-top: -"+(g-a)+"px":e.style.cssText=""},g,500,c.easeOut)},500),this.gcTweets(50)},appendTweets:function(a){var b=s.one(z,this.element,"DIV"),c=s.one(A,b,"OL");this.updateTimeStamps(),c.appendChild(a)},gcTweets:function(a){var b=s.one(A,this.element,"OL"),c=b.children.length,d;a=a||50;for(;c>a&&(d=b.children[c-1]);c--)b.removeChild(d)},showNewTweetNotifier:function(){var a=this,b=s.one(w,this.element,"DIV"),c=b.children[0];b.style.cssText="",r.add(this.element,L),b.removeChild(c),b.appendChild(c),r.replace(this.element,L,M),this.newNoticeDisplayTime=+(new Date),window.setTimeout(function(){a.hideNewTweetNotifier()},5e3)},hideNewTweetNotifier:function(a){var b=this,c=s.one(w,this.element,"DIV");if(!a&&this.mouseOverNotifier)return;r.replace(this.element,M,L),window.setTimeout(function(){r.remove(b.element,L)},500)},augmentWidgets:function(a){var b=s.all(I,a,"A"),c=s.one(G,a,"A"),d=s.one(H,a,"BUTTON"),e=0,f=b.concat([c]),g;for(;g=f[e];e++)g.setAttribute("data-related",this.related),g.setAttribute("data-partner",this.partner),g.setAttribute("data-dnt",this.dnt),g.setAttribute("data-autofocus","true"),g.setAttribute("data-search-query",this.searchQuery),g.setAttribute("data-profile-id",this.profileId);if(this.width<250)for(e=0;g=b[e];e++)g.setAttribute("data-show-screen-name","false");c&&(d&&d.parentNode.removeChild(d),c.className=[H,"web-intent"].join(" "))},readTranslations:function(){var a=this.element,b="data-dt-";this.i18n={phrases:{now:a.getAttribute(b+"now"),s:a.getAttribute(b+"s"),m:a.getAttribute(b+"m"),h:a.getAttribute(b+"h"),second:a.getAttribute(b+"second"),seconds:a.getAttribute(b+"seconds"),minute:a.getAttribute(b+"minute"),minutes:a.getAttribute(b+"minutes"),hour:a.getAttribute(b+"hour"),hours:a.getAttribute(b+"hours")},months:a.getAttribute(b+"months").split("|"),formats:{abbr:a.getAttribute(b+"abbr"),shortdate:a.getAttribute(b+"short"),longdate:a.getAttribute(b+"long")}}},updateTimeStamps:function(){var a=s.all(F,this.element,"A"),b,c,d=0,e,f;for(;a[d]&&(b=a[d]);d++){e=a[d].getAttribute("data-datetime"),f=i.timeAgo(e,this.i18n),c=b.getElementsByTagName("TIME")[0];if(c&&c.innerHTML){c.innerHTML=f;continue}b.innerHTML=f}},mouseIsOver:function(){return this.mouseOver},addUrlParams:function(a){var b=this,c={tw_w:this.widgetId,related:this.related,partner:this.partner,query:this.searchQuery,profile_id:this.profileId,tw_p:"embeddedtimeline"};return this.addUrlParams=g(c,function(a){var c=s.ancestor("."+B,a,b.element);return c&&{tw_i:c.getAttribute("data-tweet-id")}}),this.addUrlParams(a)},showNSFW:function(a){var c=s.one("nsfw",a,"DIV"),d,e,f=0,g,h,i,k;if(!c)return;e=b.scaleDimensions(c.getAttribute("data-width"),c.getAttribute("data-height"),this.contentWidth(),c.getAttribute("data-height")),d=!!(h=c.getAttribute("data-player")),d?i=this.sandbox.doc.createElement("iframe"):(i=this.sandbox.doc.createElement("img"),h=c.getAttribute(j.retina()?"data-image-2x":"data-image"),i.alt=c.getAttribute("data-alt"),k=this.sandbox.doc.createElement("a"),k.href=c.getAttribute("data-href"),k.appendChild(i)),i.title=c.getAttribute("data-title"),i.src=h,i.width=e.width,i.height=e.height,g=s.ancestor("."+D,c,a),f=e.height-c.offsetHeight,c.parentNode.replaceChild(d?i:k,c),g.style.cssText="height:"+(g.offsetHeight+f)+"px"},handleResize:function(){this.handleResize=m(function(){var a=Math.min(this.dimensions.DEFAULT_WIDTH,Math.max(this.dimensions.MIN_WIDTH,this.sandbox.frame.offsetWidth));if(!this.element)return;a<this.dimensions.NARROW_WIDTH?(this.narrow=!0,r.add(this.element,"var-narrow")):(this.narrow=!1,r.remove(this.element,"var-narrow"))},50,this),this.handleResize()}}),a(O)})});
+provide("tfw/widget/embed",function(a){using("tfw/widget/base","tfw/widget/syndicatedbase","tfw/util/params","dom/classname","dom/get","util/util","util/throttle","util/twitter","tfw/util/data","tfw/util/tracking",function(b,c,d,e,f,g,h,i,j,k){function p(a,b,c){var d=f.one("subject",a,"BLOCKQUOTE"),e=f.one("reply",a,"BLOCKQUOTE"),g=d&&d.getAttribute("data-tweet-id"),h=e&&e.getAttribute("data-tweet-id"),i={},j={};if(!g)return;i[g]={item_type:0},k.enqueue({page:"tweet",section:"subject",component:"tweet",action:"results"},{client_version:l,widget_origin:document.location.href,message:b,item_ids:[g],item_details:i},!0,c);if(!h)return;j[h]={item_type:0},k.enqueue({page:"tweet",section:"conversation",component:"tweet",action:"results"},{client_version:l,widget_origin:document.location.href,message:b,item_ids:[h],item_details:j,associations:{4:{association_id:g,association_type:4}}},!0,c)}function q(a,b,c){var d={};if(!a)return;d[a]={item_type:0},k.enqueue({page:"tweet",section:"subject",component:"rawembedcode",action:"no_results"},{client_version:l,widget_origin:document.location.href,message:b,item_ids:[a],item_details:d},!0,c)}function r(a,b,c,d,e){n[a]=n[a]||[],n[a].push({s:c,f:d,r:e,lang:b})}function s(a){if(!a)return;var b,d,e;this.a11yTitle=this._("Embedded Tweet"),c.apply(this,[a]),b=this.params(),d=this.srcEl&&this.srcEl.getElementsByTagName("A"),e=d&&d[d.length-1],this.hideThread=(b.conversation||this.dataAttr("conversation"))=="none"||~g.indexOf(this.classAttr,"tw-hide-thread"),this.hideCard=(b.cards||this.dataAttr("cards"))=="hidden"||~g.indexOf(this.classAttr,"tw-hide-media");if((b.align||this.attr("align"))=="left"||~g.indexOf(this.classAttr,"tw-align-left"))this.align="left";else if((b.align||this.attr("align"))=="right"||~g.indexOf(this.classAttr,"tw-align-right"))this.align="right";else if((b.align||this.attr("align"))=="center"||~g.indexOf(this.classAttr,"tw-align-center"))this.align="center",this.containerWidth>this.dimensions.MIN_WIDTH*(1/.7)&&this.width>this.containerWidth*.7&&(this.width=this.containerWidth*.7);this.narrow=b.narrow||this.width<=this.dimensions.NARROW_WIDTH,this.narrow&&this.classAttr.push("var-narrow"),this.tweetId=b.tweetId||e&&i.status(e.href)}var l="2.0",m="tweetembed",n={},o={};s.prototype=new c,g.aug(s.prototype,{renderedClassNames:"twitter-tweet twitter-tweet-rendered",dimensions:{DEFAULT_HEIGHT:"0",DEFAULT_WIDTH:"500",NARROW_WIDTH:"350",MIN_WIDTH:"220",MIN_HEIGHT:"0",WIDE_MEDIA_PADDING:32,NARROW_MEDIA_PADDING:32},create:function(a){var b=this.sandbox.doc.createElement("div"),d,e=this.sandbox.frame,f=e.style;b.innerHTML=a,d=b.children[0]||!1;if(!d)return;return this.theme=="dark"&&this.classAttr.push("thm-dark"),this.linkColor&&this.addSiteStyles(),this.augmentWidgets(d),c.retinize(d),c.constrainMedia(d,this.contentWidth()),d.id=this.id,d.className+=" "+this.classAttr.join(" "),d.lang=this.lang,twttr.widgets.load(d),this.sandbox.body.appendChild(d),f.cssText="",e.width=this.width,e.height=0,f.display="block",f.border="#ddd 1px solid",f.maxWidth="99%",f.minWidth=this.dimensions.MIN_WIDTH+"px",f.margin="10px 0",f.borderRadius="10px",f.borderTopColor="#eee",f.borderBottomColor="#bbb",f.boxShadow="0 1px 3px rgba(0, 0, 0, 0.15)",this.align=="center"?(f.margin="7px auto",f.float="none"):this.align&&(this.width==this.dimensions.DEFAULT_WIDTH&&(e.width=this.dimensions.NARROW_WIDTH),f.float=this.align),p(d,this.partner,this.dnt),d},render:function(a,b){var c=this,d="",e=this.tweetId,f,g,h;if(!e)return;this.hideCard&&(d+="c"),this.hideThread&&(d+="t"),d&&(e+="-"+d),h=this.callsWhenSandboxReady(function(a){function d(){c.srcEl&&c.srcEl.parentNode&&c.srcEl.parentNode.removeChild(c.srcEl),c.handleResize()}var b;c.sandbox.doc.body.style.display!=="none"&&c.sandbox.frame.offsetHeight&&c.element.offsetHeight?d():b=window.setInterval(function(){c.sandbox.doc.body.style.display!=="none"&&c.sandbox.frame.offsetHeight&&c.element.offsetHeight&&(window.clearInterval(b),d())},100)}),f=this.callsWhenSandboxReady(function(a,d){c.element=c.create(d),c.bindIntentHandlers(),b&&b(c.sandbox.frame)}),g=this.callsWhenSandboxReady(function(a){q(c.tweetId,c.partner,c.dnt)}),r(e,this.lang,f,g,h)},augmentWidgets:function(a){var b=f.all("twitter-follow-button",a,"A"),c,d=0;for(;c=b[d];d++)c.setAttribute("data-related",this.related),c.setAttribute("data-partner",this.partner),c.setAttribute("data-dnt",this.dnt),c.setAttribute("data-show-screen-name","false")},addUrlParams:function(a){var b=this,c={related:this.related,partner:this.partner,tw_p:m};return this.addUrlParams=d(c,function(a){var c=f.ancestor(".tweet",a,b.element);return{tw_i:c.getAttribute("data-tweet-id")}}),this.addUrlParams(a)},handleResize:function(){this.handleResize=h(function(){var a=this,b=Math.min(this.dimensions.DEFAULT_WIDTH,Math.max(this.dimensions.MIN_WIDTH,this.sandbox.frame.offsetWidth));if(!this.element)return;b<this.dimensions.NARROW_WIDTH?(this.narrow=!0,e.add(this.element,"var-narrow")):(this.narrow=!1,e.remove(this.element,"var-narrow")),window.setTimeout(function(){a.sandbox.frame.height=a.height=a.element.offsetHeight},0)},50,this),this.handleResize()}}),s.fetchAndRender=function(){var a=n,b=[],c=0,d,e;n={};if(a.keys)b=a.keys();else for(d in a)a.hasOwnProperty(d)&&b.push(d);if(!b.length)return;k.initPostLogging(),e=a[b[0]][0].lang,j.tweets({ids:b.sort(),lang:e,complete:function(b){var c,d,e,f,g,h,i=[];for(c in b)if(b.hasOwnProperty(c)){g=a[c]&&a[c];for(e=0;g.length&&(f=g[e]);e++)f.s&&(f.s.call(this,b[c]),f.r&&i.push(f.r));delete a[c]}for(e=0;h=i[e];e++)h.call(this);for(d in a)if(a.hasOwnProperty(d)){g=a[d];for(e=0;g.length&&(f=g[e]);e++)f.f&&f.f.call(this,b[c])}k.flush()}})},b.afterLoad(s.fetchAndRender),a(s)})});
+provide("dom/textsize",function(a){function c(a,b,c){var d=[],e=0,f;for(;f=c[e];e++)d.push(f[0]),d.push(f[1]);return a+b+d.join(":")}function d(a){var b=a||"";return b.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()})}var b={};a(function(a,e,f){var g=document.createElement("span"),h={},i="",j,k=0,l=0,m=[];f=f||[],e=e||"",i=c(a,e,f);if(b[i])return b[i];g.className=e+" twitter-measurement";try{for(;j=f[k];k++)g.style[j[0]]=j[1]}catch(n){for(;j=f[l];l++)m.push(d(j[0])+":"+j[1]);g.setAttribute("style",m.join(";")+";")}return g.innerHTML=a,document.body.appendChild(g),h.width=g.clientWidth||g.offsetWidth,h.height=g.clientHeight||g.offsetHeight,document.body.removeChild(g),delete g,b[i]=h})});
+provide("tfw/widget/tweetbase",function(a){using("util/util","tfw/widget/base","util/querystring","util/uri",function(b,c,d,e){function h(a){if(!a)return;var b;c.apply(this,[a]),b=this.params(),this.text=b.text||this.dataAttr("text"),this.align=b.align||this.dataAttr("align")||"",this.via=b.via||this.dataAttr("via"),this.placeid=b.placeid||this.dataAttr("placeid"),this.hashtags=b.hashtags||this.dataAttr("hashtags"),this.screen_name=b.screen_name||this.dataAttr("button-screen-name"),this.url=b.url||this.dataAttr("url")}var f=document.title,g=encodeURI(location.href);h.prototype=new c,b.aug(h.prototype,{parameters:function(){var a={text:this.text,url:this.url,related:this.related,lang:this.lang,placeid:this.placeid,original_referer:location.href,id:this.id,screen_name:this.screen_name,hashtags:this.hashtags,dnt:this.dnt,_:+(new Date)};return b.compact(a),d.encode(a)}}),a(h)})});
+provide("tfw/widget/tweetbutton",function(a){using("tfw/widget/tweetbase","util/util","util/querystring","util/uri","dom/textsize",function(b,c,d,e,f){var g=document.title,h=encodeURI(location.href),i=["vertical","horizontal","none"],j=function(a){b.apply(this,[a]);var d=this.params(),f=d.count||this.dataAttr("count"),j=d.size||this.dataAttr("size"),k=e.getScreenNameFromPage();if(d.type=="hashtag"||~c.indexOf(this.classAttr,"twitter-hashtag-button"))this.type="hashtag";else if(d.type=="mention"||~c.indexOf(this.classAttr,"twitter-mention-button"))this.type="mention";this.text=d.text||this.dataAttr("text"),this.align=d.align||this.dataAttr("align")||"",this.via=d.via||this.dataAttr("via"),this.related=d.related||this.dataAttr("related"),this.counturl=d.counturl||this.dataAttr("counturl"),this.searchlink=d.searchlink||this.dataAttr("searchlink"),this.placeid=d.placeid||this.dataAttr("placeid"),this.hashtags=d.hashtags||this.dataAttr("hashtags"),this.screen_name=d.screen_name||d.screenName||this.dataAttr("button-screen-name"),this.button_hashtag=d.button_hashtag||d.hashtag||this.dataAttr("button-hashtag"),this.url=d.url||this.dataAttr("url"),this.size=j=="large"?"l":"m",this.dnt=d.dnt||this.dataAttr("dnt")||"",this.type?(this.count="none",k&&(this.related=this.related?k+","+this.related:k)):(this.text=this.text||g,this.url=this.url||e.getCanonicalURL()||h,this.count=~c.indexOf(i,f)?f:"horizontal",this.count=this.count=="vertical"&&this.size=="l"?"none":this.count,this.via=this.via||k)};j.prototype=new b,c.aug(j.prototype,{parameters:function(){var a={text:this.text,url:this.url,via:this.via,related:this.related,count:this.count,lang:this.lang,counturl:this.counturl,searchlink:this.searchlink,placeid:this.placeid,original_referer:location.href,id:this.id,size:this.size,type:this.type,screen_name:this.screen_name,button_hashtag:this.button_hashtag,hashtags:this.hashtags,align:this.align,dnt:this.dnt,_:+(new Date)};return c.compact(a),d.encode(a)},height:function(){return this.count=="vertical"?62:this.size=="m"?20:28},width:function(){var a={ver:8,cnt:14,btn:24,xlcnt:18,xlbtn:38},b=this.count=="vertical",d=this.type=="hashtag"?"Tweet %{hashtag}":this.type=="mention"?"Tweet to %{name}":"Tweet",e=this._(d,{name:"@"+this.screen_name,hashtag:"#"+this.button_hashtag}),g=this._("K"),h=this._("100K+"),i=(b?"8888":"88888")+g,j=0,k=0,l=0,m=0,n=this.styles.base,o=n;return~c.indexOf(["ja","ko"],this.lang)?i+=this._("10k unit"):i=i.length>h.length?i:h,b?(o=n.concat(this.styles.vbubble),m=a.ver,l=a.btn):this.size=="l"?(n=o=n.concat(this.styles.large),l=a.xlbtn,m=a.xlcnt):(l=a.btn,m=a.cnt),this.count!="none"&&(k=f(i,"",o).width+m),j=f(e,"",n.concat(this.styles.button)).width+l,b?j>k?j:k:this.calculatedWidth=j+k},render:function(a,b){var c=twttr.widgets.config.assetUrl()+"/widgets/tweet_button.1362008198.html#"+this.parameters();this.count&&this.classAttr.push("twitter-count-"+this.count),this.element=this.create(c,this.dimensions(),{title:this._("Twitter Tweet Button")}),b&&b(this.element)}}),a(j)})});
+provide("tfw/widget/follow",function(a){using("util/util","tfw/widget/base","util/querystring","util/uri","util/twitter","dom/textsize",function(b,c,d,e,f,g){function h(a){if(!a)return;var b,d,e,g;c.apply(this,[a]),b=this.params(),d=b.size||this.dataAttr("size"),e=b.show_screen_name||this.dataAttr("show-screen-name"),g=b.show_count||this.dataAttr("show-count"),this.classAttr.push("twitter-follow-button"),this.showScreenName=e!="false",this.showCount=g!="false",this.explicitWidth=b.width||this.dataAttr("width")||"",this.screenName=b.screenName||f.screenName(this.attr("href")),this.preview=b.preview||this.dataAttr("preview")||"",this.align=b.align||this.dataAttr("align")||"",this.size=d=="large"?"l":"m"}h.prototype=new c,b.aug(h.prototype,{parameters:function(){var a={screen_name:this.screenName,lang:this.lang,show_count:this.showCount,show_screen_name:this.showScreenName,align:this.align,id:this.id,preview:this.preview,size:this.size,dnt:this.dnt,_:+(new Date)};return b.compact(a),d.encode(a)},render:function(a,b){if(!this.screenName)return;var c=twttr.widgets.config.assetUrl()+"/widgets/follow_button.1362008198.html#"+this.parameters();this.element=this.create(c,this.dimensions(),{title:this._("Twitter Follow Button")}),b&&b(this.element)},width:function(){if(this.calculatedWidth)return this.calculatedWidth;if(this.explicitWidth)return this.explicitWidth;var a={cnt:13,btn:24,xlcnt:22,xlbtn:38},c=this.showScreenName?"Follow %{screen_name}":"Follow",d=this._(c,{screen_name:"@"+this.screenName}),e=~b.indexOf(["ja","ko"],this.lang)?this._("10k unit"):this._("M"),f=this._("%{followers_count} followers",{followers_count:"88888"+e}),h=0,i=0,j,k,l=this.styles.base;return this.size=="l"?(l=l.concat(this.styles.large),j=a.xlbtn,k=a.xlcnt):(j=a.btn,k=a.cnt),this.showCount&&(i=g(f,"",l).width+k),h=g(d,"",l.concat(this.styles.button)).width+j,this.calculatedWidth=h+i}}),a(h)})});
+!function(){function a(a){return(a||!/^http\:$/.test(window.location.protocol))&&!twttr.ignoreSSL?"https":"http"}window.twttr=window.twttr||{},twttr.host=twttr.host||"platform.twitter.com";if(twttr.widgets&&twttr.widgets.loaded)return twttr.widgets.load(),!1;if(twttr.init)return!1;twttr.init=!0,twttr._e=twttr._e||[],twttr.ready=twttr.ready||function(a){twttr.widgets&&twttr.widgets.loaded?a(twttr):twttr._e.push(a)},using.path.length||(using.path=a()+"://"+twttr.host+"/js"),twttr.ignoreSSL=twttr.ignoreSSL||!1;var b=[];twttr.events={bind:function(a,c){return b.push([a,c])}},using("util/domready",function(c){c(function(){using("tfw/widget/base","tfw/widget/follow","tfw/widget/tweetbutton","tfw/widget/embed","tfw/widget/timeline","tfw/widget/intent","tfw/util/globals","util/events","util/util",function(c,d,e,f,g,h,i,j,k){function q(b){var c=twttr.host;return a(b)=="https"&&twttr.secureHost&&(c=twttr.secureHost),a(b)+"://"+c}function r(){using("tfw/hub/client",function(a){twttr.events.hub=a.init(n),a.init(n,!0)})}var l,m,n={widgets:{"a.twitter-share-button":e,"a.twitter-mention-button":e,"a.twitter-hashtag-button":e,"a.twitter-follow-button":d,"blockquote.twitter-tweet":f,"a.twitter-timeline":g,body:h}},o=twttr.events&&twttr.events.hub?twttr.events:{},p;i.init(),n.assetUrl=q,twttr.widgets=twttr.widgets||{},k.aug(twttr.widgets,{config:{assetUrl:q},load:function(a){c.init(n),c.embed(a),twttr.widgets.loaded=!0},createShareButton:function(a,b,c,d){if(!a||!b)return c&&c(!1);d=k.aug({},d||{},{url:a,targetEl:b}),(new e(d)).render(n,c)},createHashtagButton:function(a,b,c,d){if(!a||!b)return d&&d(!1);c=k.aug({},c||{},{hashtag:a,targetEl:b,type:"hashtag"}),(new e(c)).render(n,d)},createMentionButton:function(a,b,c,d){if(!a||!b)return c&&c(!1);d=k.aug({},d||{},{screenName:a,targetEl:b,type:"mention"}),(new e(d)).render(n,c)},createFollowButton:function(a,b,c,e){if(!a||!b)return c&&c(!1);e=k.aug({},e||{},{screenName:a,targetEl:b}),(new d(e)).render(n,c)},createTweetEmbed:function(a,b,c,d){if(!a||!b)return c&&c(!1);d=k.aug({},d||{},{tweetId:a,targetEl:b}),(new f(d)).render(n,c),f.fetchAndRender()},createTimeline:function(a,b,c,d){if(!a||!b)return c&&c(!1);d=k.aug({},d||{},{widgetId:a,targetEl:b}),(new g(d)).render(n,c)}}),k.aug(twttr.events,o,j.Emitter),p=twttr.events.bind,twttr.events.bind=function(a,b){r(),this.bind=p,this.bind(a,b)};for(l=0;m=b[l];l++)twttr.events.bind(m[0],m[1]);for(l=0;m=twttr._e[l];l++)m(twttr);twttr.ready=function(a){a(twttr)},/^twitter\.com(\:\d+)?$/.test(document.location.host)&&(twttr.widgets.createTimelinePreview=function(a,b,c){if(!n||!b)return c&&c(!1);(new g({previewParams:a,targetEl:b,linkColor:a.link_color,theme:a.theme,height:a.height})).render(n,c)}),twttr.widgets.load()})})})}()});
View
14 app/assets/stylesheets/_tweets.css.sass
@@ -18,6 +18,8 @@
ul.actions
li
:padding 0
+ :margin 0
+ li.twitter
a
:float left
img
@@ -44,6 +46,10 @@
:line-height 25px
:padding 0 5px 15px
:word-wrap break-word
+ .copied
+ :font-size 14px
+ :color #999999
+ :line-height inherit
.meta
:padding 0 5px
:color #666666
@@ -58,6 +64,11 @@
.created_at
:display block
:float left
+ .copied
+ :float left
+ :margin-left 10px
+ a
+ :color #ff6666
.source
:display block
:float right
@@ -79,6 +90,9 @@
:font-weight normal
:font-size 10px
:text-transform uppercase
+ .full
+ :font-weight normal
+ :font-size 9px
dd
:margin 0
ul
View
17 app/controllers/application_controller.rb
@@ -29,7 +29,14 @@ def get_include_user_stats
end
end
- def render_tweets(a = nil, &blk)
+ def render_page(a = nil, &blk)
+ @items = (a || blk.call).page(page || 1).per(count)
+ @page_param = true
+
+ render "shared/tweets"
+ end
+
+ def render_timeline(a = nil, &blk)
@items = a || blk.call
if max_id
@@ -40,7 +47,7 @@ def render_tweets(a = nil, &blk)
@items = @items.where("tweets.id > ?", since_id)
end
- @items = @items.page(page || 1).per(count)
+ @items = @items.page(1).per(count)
render "shared/tweets"
end
@@ -64,9 +71,9 @@ def order
end
end
- def all
- get_bool(params[:all])
- end
+ def all; get_bool(params[:all]) end
+
+ def full; get_bool(params[:full]) end
private
def get_bool(str)
View
18 app/controllers/i_controller.rb
@@ -1,39 +1,31 @@
class IController < ApplicationController
def best
@title = "Best Tweets"
- render_tweets do
+ render_page do
Tweet
.reacted
.order_by_reactions
+ .original
end
end
def recent
@title = "Recent Best Tweets"
- render_tweets do
+ render_page do
Tweet
.recent
.reacted
.order_by_reactions
+ .original
end
end
def timeline
@title = "Public Timeline"
- render_tweets do
+ render_timeline do
Tweet
.reacted
.order_by_id
end
end
-
- def report
- if request.post?
- case params[:type]
- when "steal"
- # パクリツイート
-
- end
- end
- end
end
View
69 app/controllers/report_controller.rb
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+class ReportController < ApplicationController
+ layout "index"
+ def index
+ # いんでっくす
+ end
+
+ def tweet
+ original_id, tweet_id = [get_tweet_id(params[:tweet_id_0]), get_tweet_id(params[:tweet_id_1])].sort
+
+ unless original_id && tweet_id
+ # 何かがおかしいよ
+ raise ActionController::BadRequest
+ end
+
+ tweet = Tweet.cached(tweet_id)
+ if tweet
+ original = Tweet.cached(original_id)
+ unless original
+ add_issue_stolen(false, tweet_id, original_id)
+ return
+ # 記録されてなかった
+ # どうしよう。どのアカウントのAPIを使うか?
+ end
+
+ if original_id < tweet_id
+ if iscopy?(original, tweet)
+ # 両方記録されており、パクリツイート
+ logger.debug("pakuri!!!")
+ StolenTweet.register(original, tweet)
+ add_issue_stolen(true, tweet_id, original_id)
+ else
+ # パクリツイートではない(違う)
+ logger.debug("not pakuri!")
+ add_issue_stolen(false, tweet_id, original_id)
+ end
+ else
+ # パクリツイートではない(新しい)
+ logger.debug("not old, new")
+ end
+ else
+ # 記録されてないけど?
+ # 403
+ logger.debug("not recorded?")
+ end
+ end
+
+ private
+ def get_tweet_id(str)
+ case str
+ when /^(?:(?:https?:\/\/)?(?:(?:www\.)?twitter\.com|aclog\.koba789\.com)\/(?:i\/|[0-9A-Za-z_]{1,15}\/status(?:es)?\/))?(\d+)/
+ $1.to_i
+ end
+ end
+
+ def iscopy?(original, tweet)
+ textr = -> str do
+ str.gsub(/([  \t\n\r\f]|[\x20\x00-\x20\x0f])/, "")
+ end
+
+ textr.call(original.text) == textr.call(tweet.text)
+ end
+
+ def add_issue_stolen(resolved, tweet_id, original_id)
+ Issue.register(Aclog::Constants::IssueType::TWEET_STOLEN,
+ resolved ? Aclog::Constants::IssueStatus::RESOLVED : Aclog::Constants::IssueStatus::PENDING,
+ {:tweet_id => tweet_id, :original_id => original_id})
+ end
+end
View
4 app/controllers/search_controller.rb
@@ -7,7 +7,7 @@ def search
# TODO: OR とか () とか対応したいよね
unless params[:query]
- render_tweets(Tweet.where(:id => -1))
+ render_page(Tweet.where(:id => -1))
return
end
words = Shellwords.shellwords(params[:query])
@@ -74,7 +74,7 @@ def search
end
end
- render_tweets(result)
+ render_page(result)
end
private
View
21 app/controllers/users_controller.rb
@@ -4,7 +4,7 @@ class UsersController < ApplicationController
def best
@title = "@#{@user.screen_name}'s Best Tweets"
- render_tweets do
+ render_page do
case order
when :favorite
@user.tweets.reacted.order_by_favorites
@@ -18,7 +18,7 @@ def best
def recent
@title = "@#{@user.screen_name}'s Recent Best Tweets"
- render_tweets do
+ render_page do
case order
when :favorite
@user.tweets.recent.reacted.order_by_favorites
@@ -34,7 +34,7 @@ def timeline
raise Aclog::Exceptions::UserProtected if @user.protected
@title = "@#{@user.screen_name}'s Newest Tweets"
- render_tweets do
+ render_timeline do
if all
@user.tweets.order_by_id
else
@@ -45,7 +45,7 @@ def timeline
def discovered
@title = "@#{@user.screen_name}'s Recent Discoveries"
- render_tweets do
+ render_timeline do
case params[:tweets]
when /^fav/
Tweet.favorited_by(@user).order_by_id
@@ -73,7 +73,7 @@ def info
def favorited_by
if @user_b
@title = "@#{@user.screen_name}'s Tweets"
- render_tweets(@user.tweets.favorited_by(@user_b).order_by_id)
+ render_timeline(@user.tweets.favorited_by(@user_b).order_by_id)
else
@title = "Who Favorited @#{@user.screen_name}"
@event_type = "favs"
@@ -84,7 +84,7 @@ def favorited_by
def retweeted_by
if @user_b
@title = "@#{@user.screen_name}'s Tweets"
- render_tweets(@user.tweets.retweeted_by(@user_b).order_by_id)
+ render_timeline(@user.tweets.retweeted_by(@user_b).order_by_id)
else
@title = "Who Retweeted @#{@user.screen_name}"
@event_type = "retweets"
@@ -95,7 +95,7 @@ def retweeted_by
def given_favorites_to
if @user_b
@title = "@#{@user_b.screen_name}'s Tweets"
- render_tweets(@user_b.tweets.favorited_by(@user).order_by_id)
+ render_timeline(@user_b.tweets.favorited_by(@user).order_by_id)
else
@title = "@#{@user.screen_name}'s Favorites"
@event_type = "favs"
@@ -106,7 +106,7 @@ def given_favorites_to
def given_retweets_to
if @user_b
@title = "@#{@user_b.screen_name}'s Tweets"
- render_tweets(@user_b.tweets.retweeted_by(@user).order_by_id)
+ render_timeline(@user_b.tweets.retweeted_by(@user).order_by_id)
else
@title = "@#{@user.screen_name}'s Retweets"
@event_type = "retweets"
@@ -131,7 +131,10 @@ def show
@title_b = "@#{@user.screen_name}'s Tweet"
respond_to do |format|
- format.html
+ format.html do
+ @full = full
+ end
+
format.json do
render "shared/_tweet", :locals => {:item => @item}
end
View
7 app/helpers/application_helper.rb
@@ -39,8 +39,13 @@ def link_to_user_page(screen_name, &blk)
link_to(body, :controller => "users", :action => "best", :screen_name => screen_name)
end
+ # _tweet
+ def show_count(c)
+ params[:action] == "show" ? (@full ? c : 100) : 20
+ end
+
# utf8
def utf8_enforcer_tag
- ""
+ raw ""
end
end
View
2  app/helpers/search_helper.rb
@@ -1,2 +0,0 @@
-module SearchHelper
-end
View
10 app/models/issue.rb
@@ -0,0 +1,10 @@
+class Issue < ActiveRecord::Base
+ def self.register(issue_type, status, data)
+ begin
+ create!(:issue_type => issue_type, :status => status, :data => Yajl::Encoder::encode(data))
+ rescue
+ logger.error($!)
+ logger.error($@)
+ end
+ end
+end
View
14 app/models/stolen_tweet.rb
@@ -0,0 +1,14 @@
+class StolenTweet < ActiveRecord::Base
+ belongs_to :tweet
+ belongs_to :original, :class_name => :Tweet
+
+ def self.register(original_tweet, the_tweet)
+ begin
+ create!(:tweet_id => the_tweet.id, :original_id => original_tweet.id)
+ rescue ActiveRecord::RecordNotUnique
+ logger.error("Duplicate Stolen Info")
+ rescue
+ logger.error("Unknown error while inserting stolen info: #{$!}/#{$@}")
+ end
+ end
+end
View
14 app/models/tweet.rb
@@ -1,7 +1,13 @@
class Tweet < ActiveRecord::Base
belongs_to :user
+
has_many :favorites, :dependent => :delete_all
has_many :retweets, :dependent => :delete_all
+ has_many :favoriters, ->{order("favorites.id")}, :through => :favorites, :source => :user
+ has_many :retweeters, ->{order("retweets.id")}, :through => :retweets, :source => :user
+
+ has_one :stolen_tweet, ->{includes(:original)}, :dependent => :delete
+ has_one :original, :through => :stolen_tweet, :source => :original
scope :recent, -> do
where("tweeted_at > ?", Time.zone.now - 3.days)
@@ -43,6 +49,10 @@ class Tweet < ActiveRecord::Base
") AS m ON m.tweet_id = tweets.id")
end
+ scope :original, -> do
+ joins("LEFT JOIN stolen_tweets ON tweets.id = stolen_tweets.tweet_id").where(:stolen_tweets => {:tweet_id => nil})
+ end
+
def self.cached(id)
Rails.cache.fetch("tweet/#{id}", :expires_in => 3.hour) do
where(:id => id).first
@@ -54,8 +64,8 @@ def user
end
def notify_favorite
- if [50, 100, 250, 500, 1000].include? favorites_count
- Aclog::Notification.reply_favs(self, favorites_count)
+ if [50, 100, 250, 500, 1000].include? favorites.count
+ Aclog::Notification.reply_favs(self, favorites.count)
end
end
View
4 app/views/layouts/_base.html.haml
@@ -1,7 +1,7 @@
!!! xml
%html{xmlns: "http://www.w3.org/1999/xhtml"}
%head
- %title= @title
+ %title= @title.to_s + " - aclog"
= stylesheet_link_tag "application"
= javascript_include_tag "twitter"
= javascript_include_tag "application"
@@ -13,6 +13,8 @@
= link_to "aclog", :controller => "main", :action => "index"
%ul.nav.pull-right
%li
+ = link_to "report", :controller => "report", :action => "index"
+ %li
= link_to "search", :controller => "search", :action => "search"
%li
= link_to "about", :controller => "main", :action => "about"
View
42 app/views/main/about.html.haml
@@ -2,6 +2,9 @@
= link_to "@re4k", "https://twitter.com/re4k"
が Favstar BAN されたので仕方なく代わりを作りました。
%p
+ = link_to "@KOBA789", "https://twitter.com/KOBA789"
+ さんにサーバーを借りています。
+%p
そーすはこっち
= link_to "GitHub", "https://github.com/re4k/aclog"
%p
@@ -10,8 +13,39 @@
%li
読み込み中アニメーションGIF
%span= link_to "http://www.ajaxload.info/", "http://www.ajaxload.info/"
+%h3 各ページのURLについてメモ
+%dl
+ %dt best
+ %dd= link_to "/cn", "/cn"
+ %dt recent(最近3日のbest)
+ %dd= link_to "/cn/recent", "/cn/recent"
+ %dt timeline(Favstar の Recent)
+ %dd= link_to "/cn/timeline", "/cn/timeline"
+%p まだいろいろありますがユーザーのページを開くとサイドバーに一覧があるのでそちらからどうぞ
+%dl
+ %dt 全体のbest
+ %dd= link_to "/i/best", "/i/best"
+ %dt 全体の最新3日のbest
+ %dd= link_to "/i/recent", "/i/recent"
+ %dt 全体の最新反応あり
+ %dd= link_to "/i/timeline", "/i/timeline"
%p
- このページ作ったはいいけど書くことがない…
- トップページ見てくださいな
-%p
- = link_to "トップページ", :root
+ Favstar のパスにアクセスされた場合リダイレクトするようになっているはず…
+%h3 検索クエリ
+%p 半角スペース区切りで、すべて AND 検索になります。OR 検索付けたいけどまだ使えません。
+%p order 以外は先頭に - を付けることで否定になります。
+%dl
+ %dt ユーザーの
+ %dd user:cn
+ %dt 反応数 〜〜以上
+ %dd reaction:30
+ %dd favorite:30
+ %dd retweet:30
+ %dt 並び替え
+ %dd order:old
+ %dd order:reaction
+ %dd order:favorite
+ %dd order:retweet
+ %dt 期間
+ %dd 20130328..20130330
+ %dt ツイート本文・クライアント名での検索はできません。クライアント名での検索は付けたいけれど…%p
View
66 app/views/main/index.html.haml
@@ -2,58 +2,26 @@
.lead
Favstar クローン
%p
- = link_to "@KOBA789", "https://twitter.com/KOBA789"
- さんにサーバーを貸していただけることになりました…!!ありがとうございます!ありがとうございます!!!
-.alert
- 開発中です。まだ不具合あるかもしれません。一応動いてるっぽいですが
+ UserStreams で登録ユーザーのふぁぼり・ふぁぼられ・RTを集めて表示するサービスです。あんふぁぼも反映されます。
%p
- 基本的に Favstar のパクリです。トロフィー・50favs通知以外の機能は一応全部つけたつもり。
- トロフィー機能って必要ですかね、Favstar Pro じゃないし Favstar BAN されたしわかりません。
+ Favstar を参考に開発しています。現時点でトロフィー以外の機能はすべて使えるはずです。
%p
- 不具合があったら私
- = link_to "contact@re4k.info", "mailto:contact@re4k.info"
- にメールするか、
- = link_to "@cn", "https://twitter.com/cn"
- へリプライを飛ばしてくれるとありがたいです。
-%h3
- 今後の予定
+ API も提供する予定です。about → api を見てください(まだ開発中であり、変更がある可能性もあります)
+%h4
+ 今後の予定(2013/04/03)
%ul
%li トロフィー機能を付ける予定はありません
- %li 50favs通知・100favs通知・250favs通知・500favs通知…は付ける予定
- %li ふぁぼったー・Favstar からのデータの取り込み: したいけど…
-%h3 URL
-%dl
- %dt best
- %dd= link_to "/cn", "/cn"
- %dt recent(最近3日のbest)
- %dd= link_to "/cn/recent", "/cn/recent"
- %dt timeline(Favstar の Recent)
- %dd= link_to "/cn/timeline", "/cn/timeline"
-%p まだいろいろありますがユーザーのページを開くとサイドバーに一覧があるのでそちらからどうぞ
-%dl
- %dt 全体のbest
- %dd= link_to "/i/best", "/i/best"
- %dt 全体の最新3日のbest
- %dd= link_to "/i/recent", "/i/recent"
- %dt 全体の最新反応あり
- %dd= link_to "/i/timeline", "/i/timeline"
+ %li ふぁぼったー・Favstar からのデータの取り込み
+ %li パクリツイート対策
+ %li ふぁぼ爆撃対策
%p
- Favstar のパスにアクセスされた場合リダイレクトするようになっているはず…
-%h3 検索クエリ
-%p 半角スペース区切りで、すべて AND 検索になります。OR 検索付けたいけどまだ使えません。
-%p order 以外は先頭に - を付けることで否定になります。
+ = link_to "ツイート", "https://twitter.com/share", :class => "twitter-share-button", :"data-text" => "aclog", :"data-count" => "none", :"data-url" => "http://aclog.koba789.com/"
+%hr
+%h5
+ 連絡先
%dl
- %dt ユーザーの
- %dd user:cn
- %dt 反応数 〜〜以上
- %dd reaction:30
- %dd favorite:30
- %dd retweet:30
- %dt 並び替え
- %dd order:old
- %dd order:reaction
- %dd order:favorite
- %dd order:retweet
- %dt 期間
- %dd 20130328..20130330
- %dt ツイート本文・クライアント名での検索はできません。クライアント名での検索は付けたいけれど…
+ %dt Twitter
+ %dd= link_to "@cn", "https://twitter.com/cn"
+ %dt メール(あんまり見ていません)
+ %dd= link_to "contact@re4k.info", "mailto:contact@re4k.info"
+
View
17 app/views/report/index.html.haml
@@ -0,0 +1,17 @@
+%h1 パクリツイートの報告
+%p
+ まだ準備中です。全く同一のツイートのみしか対応しておりません。
+%hr
+= form_tag({:controller => "report", :action => "tweet"}, {:method => :post, :class => "form-horizontal"}) do
+ .control-group
+ = label_tag "tweet_id_0", "ツイート1", :class => "control-label"
+ .controls
+ = text_field_tag "tweet_id_0", params[:tweet_id_0], :style => "width: 100%"
+ .control-group
+ = label_tag "tweet_id_1", "ツイート2", :class => "control-label"
+ .controls
+ = text_field_tag "tweet_id_1", params[:tweet_id_1], :style => "width: 100%"
+ .control-group
+ .controls
+ = submit_tag "送信", :name => nil, :class => "btn"
+
View
2  app/views/report/issue.html.haml
@@ -0,0 +1,2 @@
+%h1 Report#issue
+%p Find me in app/views/report/issue.html.haml
View
2  app/views/report/spam.html.haml
@@ -0,0 +1,2 @@
+%h1 Report#spam
+%p Find me in app/views/report/spam.html.haml
View
2  app/views/report/tweet.html.haml
@@ -0,0 +1,2 @@
+%h1 パクリツイートの報告
+%p 報告ありがとうございました。
View
22 app/views/shared/_tweet.html.haml
@@ -4,7 +4,7 @@
.avatar
= link_to image_tag(item.user.profile_image_url, :alt => item.user.screen_name, :title => item.user.name), :controller => "users", :action => "best", :screen_name => item.user.screen_name
%ul.inline.actions
- %li
+ %li.twitter
= link_to image_tag("reply.png", :alt => "reply"), "https://twitter.com/intent/tweet?in_reply_to=#{item.id}"
= link_to image_tag("retweet.png", :alt => "retweet"), "https://twitter.com/intent/retweet?tweet_id=#{item.id}"
= link_to image_tag("favorite.png", :alt => "favorite"), "https://twitter.com/intent/favorite?tweet_id=#{item.id}"
@@ -15,28 +15,30 @@
= link_to_user_page item.user.screen_name do
= item.user.name
%span.screen_name= link_to_user_page item.user.screen_name
- .text
+ .text{:class => item.stolen_tweet ? "copied" : nil}
= raw format_tweet_text(item.text)
.meta.clearfix
%span.twitter_bird
= link_to image_tag("bird_gray_16.png", :alt => "Twitter"), twitter_status_url(item), :target => "_blank"
%span.created_at
= link_to format_time(item.tweeted_at), :controller => "users", :action => "show", :id => item.id
+ - if item.stolen_tweet
+ %span.copied
+ = link_to "original", :controller => "users", :action => "show", :id => item.original.id
%span.source
= raw format_source_text(item.source)
.stats
- - [["favs", item.favorites.order("id")], ["retweets", item.retweets.order("id")]].select{|m| m[1].count > 0}.each do |type, actions|
+ - [["favs", item.favoriters], ["retweets", item.retweeters]].select{|m| m[1].count > 0}.each do |type, actions|
%dl.dl-horizontal
%dt
%span.count= actions.count
%span.type= type
+ - if actions.count > show_count(actions.count)
+ %span.full
+ = link_to "show full", params.merge(:full => true)
%dd
%ul.inline
- - actions.take(params[:action] == "show" ? actions.count : 20).each do |a|
- - m = a.user
+ - actions.take(show_count(actions.count)).each do |m|
%li
- - if m
- = link_to_user_page m.screen_name do
- = image_tag m.profile_image_url, :alt => m.screen_name, :title => m.name
- - else
- = image_tag asset_path("missing_profile_image.png"), :alt => "Missing User: #{a.user_id}", :title => "Missing User: #{a.user_id}"
+ = link_to_user_page m.screen_name do
+ = image_tag m.profile_image_url, :alt => m.screen_name, :title => m.name
View
7 app/views/shared/tweets.html.haml
@@ -5,7 +5,8 @@
.loading
= image_tag "loading.gif", :alt => "loading...", :title => nil
- if @items
- - if params[:page]
- = link_to_next_page @items, raw("Next &#8250;")
+ - if @page_param
+ = paginate(@items)
- elsif @items.last
- = link_to raw("Next &#8250;"), params.merge(:max_id => @items.last.id - 1), :rel => :next
+ .pagination
+ = link_to raw("Next &#8250;"), params.merge(:max_id => @items.last.id - 1), :rel => :next
View
7 config/routes.rb
@@ -10,9 +10,8 @@
:order => /(fav(orite[sd]?|(or)?ed|s)?|re?t(weet(s|ed)?|s)?)/,
}
- root :to => "main#index"
-
# static
+ root :to => "main#index"
get "/about" => "main#about"
get "/about/api" => "main#api"
@@ -28,6 +27,10 @@
get "/i/show" => "users#show"
get "/i/:id" => "users#show", :constraints => constraints
+ # report
+ get "/i/report" => "report#index"
+ post "/i/report/tweet" => "report#tweet"
+
get "/search" => "search#search"
# i -- end
View
11 db/migrate/20130403114115_create_stolen_tweets.rb
@@ -0,0 +1,11 @@
+class CreateStolenTweets < ActiveRecord::Migration
+ def change
+ create_table :stolen_tweets do |t|
+ t.integer :tweet_id, :limit => 8
+ t.integer :original_id, :limit => 8
+ end
+
+ add_index :stolen_tweets, :tweet_id, :unique => true
+ add_index :stolen_tweets, :original_id
+ end
+end
View
14 db/migrate/20130403160821_create_issues.rb
@@ -0,0 +1,14 @@
+class CreateIssues < ActiveRecord::Migration
+ def change
+ create_table :issues do |t|
+ t.integer :issue_type, :limit => 2
+ t.integer :status, :limit => 2
+ t.text :data
+
+ t.timestamps
+ end
+
+ add_index :issues, :issue_type
+ add_index :issues, :status
+ end
+end
View
21 db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20130323045606) do
+ActiveRecord::Schema.define(version: 20130403160821) do
create_table "accounts", force: true do |t|
t.integer "user_id", limit: 8, null: false
@@ -33,6 +33,17 @@
add_index "favorites", ["tweet_id"], name: "index_favorites_on_tweet_id"
add_index "favorites", ["user_id"], name: "index_favorites_on_user_id"
+ create_table "issues", force: true do |t|
+ t.integer "issue_type", limit: 2
+ t.integer "status", limit: 2
+ t.text "data"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ add_index "issues", ["issue_type"], name: "index_issues_on_issue_type"
+ add_index "issues", ["status"], name: "index_issues_on_status"
+
create_table "retweets", force: true do |t|
t.integer "tweet_id", limit: 8, null: false
t.integer "user_id", limit: 8, null: false
@@ -42,6 +53,14 @@
add_index "retweets", ["tweet_id"], name: "index_retweets_on_tweet_id"
add_index "retweets", ["user_id"], name: "index_retweets_on_user_id"
+ create_table "stolen_tweets", force: true do |t|
+ t.integer "tweet_id", limit: 8
+ t.integer "original_id", limit: 8
+ end
+
+ add_index "stolen_tweets", ["original_id"], name: "index_stolen_tweets_on_original_id"
+ add_index "stolen_tweets", ["tweet_id"], name: "index_stolen_tweets_on_tweet_id", unique: true
+
create_table "tweets", force: true do |t|
t.text "text", null: false
t.text "source"
View
12 lib/aclog/constants.rb
@@ -0,0 +1,12 @@
+module Aclog
+ module Constants
+ module IssueStatus
+ RESOLVED = 0
+ PENDING = 1
+ end
+
+ module IssueType
+ TWEET_STOLEN = 0
+ end
+ end
+end
View
4 lib/receiver/worker.rb
@@ -242,7 +242,9 @@ def receive_data(data)
def initialize(opts = {})
super(opts)
- ActiveRecord::Base.logger = Rails.logger = Logger.new(STDOUT)
+ _logger = Logger.new(STDOUT)
+ _logger.level = Rails.env.production? ? Logger::INFO : Logger::DEBUG
+ ActiveRecord::Base.logger = Rails.logger = _logger
end
def start(args)
View
24 test/controllers/report_controller_test.rb
@@ -0,0 +1,24 @@
+require 'test_helper'
+
+class ReportControllerTest < ActionController::TestCase
+ test "should get index" do
+ get :index
+ assert_response :success
+ end
+
+ test "should get tweet" do
+ get :tweet
+ assert_response :success
+ end
+
+ test "should get spam" do
+ get :spam
+ assert_response :success
+ end
+
+ test "should get issue" do
+ get :issue
+ assert_response :success
+ end
+
+end
View
9 test/fixtures/issues.yml
@@ -0,0 +1,9 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
+
+one:
+ type: 1
+ data: MyText
+
+two:
+ type: 1
+ data: MyText
View
9 test/fixtures/stolen_tweets.yml
@@ -0,0 +1,9 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
+
+one:
+ tweet_id: 1
+ original_id: 1
+
+two:
+ tweet_id: 1
+ original_id: 1
View
4 test/helpers/report_helper_test.rb
@@ -0,0 +1,4 @@
+require 'test_helper'
+
+class ReportHelperTest < ActionView::TestCase
+end
View
7 test/models/issue_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class IssueTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
View
7 test/models/stolen_tweet_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class StolenTweetTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.