!function(e){!function t(e,n,a){function o(s,r){if(!n[s]){if(!e[s]){var l="function"==typeof require&&require;if(!r&&l)return l(s,!0);if(i)return i(s,!0);throw new Error("Cannot find module '"+s+"'")}var c=n[s]={exports:{}};e[s][0].call(c.exports,function(t){var n=e[s][1][t];return o(n?n:t)},c,c.exports,t,e,n,a)}return n[s].exports}for(var i="function"==typeof require&&require,s=0;se&&this._legacy_load_bots(e))})},n.prototype._legacy_load_donors=function(e){jQuery.ajax(a.SERVER+"script/donors.txt",{cache:!1,context:this}).done(function(e){this._legacy_parse_badges(e,1,1)}).fail(function(t){return 404!=t.status?(e=(e||0)+1,10>e?this._legacy_load_donors(e):void 0):void 0})},n.prototype._legacy_parse_badges=function(e,t,n){var a=this.badges[n].title,i=0;if(ds=1==n?".donor":"",null!=e)for(var s=e.trim().split(/\W+/),r=0;r50)return"Each user you unmod counts as a single message. To avoid being globally banned, please limit yourself to 50 at a time and wait between uses.";for(var a=t.length;t.length;){var o=t.shift();e.room.tmiRoom.sendMessage("/unmod "+o)}return"Sent unmod command for "+a+" users."},t.ffz_commands.massunmod.help="Usage: /ffz massunmod \nBroadcaster only. Unmod all the users in the provided list.",t.ffz_commands.massmod=function(e,t){if(t=t.join(" ").trim(),!t.length)return"You must provide a list of users to mod.";t=t.split(/\W*,\W*/);var n=this.get_user();if(!n||!n.login==e.id)return"You must be the broadcaster to use massmod.";if(t.length>50)return"Each user you mod counts as a single message. To avoid being globally banned, please limit yourself to 50 at a time and wait between uses.";for(var a=t.length;t.length;){var o=t.shift();e.room.tmiRoom.sendMessage("/mod "+o)}return"Sent mod command for "+a+" users."},t.ffz_commands.massmod.help="Usage: /ffz massmod \nBroadcaster only. Mod all the users in the provided list."},{}],3:[function(e,t){var n='',a="true"==localStorage.ffzDebugMode&&document.body.classList.contains("ffz-dev");t.exports={DEBUG:a,SERVER:a?"//localhost:8000/":"//cdn.frankerfacez.com/",SVGPATH:n,ZREKNARF:''+n+"",CHAT_BUTTON:''+n+"",CLOCK:'',GEAR:'',HEART:'',EMOTE:''}},{}],4:[function(){var t=e.FrankerFaceZ;t.settings_info.developer_mode={type:"boolean",value:!1,storage_key:"ffzDebugMode",visible:function(){return this.settings.developer_mode||Date.now()-parseInt(localStorage.ffzLastDevMode||"0")<6048e5},category:"Debugging",name:"Developer Mode",help:"Load FrankerFaceZ from the local development server instead of the CDN. Please refresh after changing this setting.",on_update:function(){localStorage.ffzLastDevMode=Date.now()}},t.ffz_commands.developer_mode=function(e,t){var n,t=t&&t.length?t[0].toLowerCase():null;return"y"==t||"yes"==t||"true"==t||"on"==t?n=!0:("n"==t||"no"==t||"false"==t||"off"==t)&&(n=!1),void 0===n?"Developer Mode is currently "+(this.settings.developer_mode?"enabled.":"disabled."):(this.settings.set("developer_mode",n),"Developer Mode is now "+(n?"enabled":"disabled")+". Please refresh your browser.")},t.ffz_commands.developer_mode.help="Usage: /ffz developer_mode \nEnable or disable Developer Mode. When Developer Mode is enabled, the script will be reloaded from //localhost:8000/script.js instead of from the CDN."},{}],5:[function(t){var n=e.FrankerFaceZ,a=t("../utils"),o=t("../constants");n.prototype.setup_channel=function(){this.channels={},this.log("Creating channel style element.");var e=this._channel_style=document.createElement("style");e.id="ffz-channel-css",document.head.appendChild(e),this.log("Hooking the Ember Channel view.");var t=App.__container__.lookup("controller:channel"),n=this;t&&(t.reopen({ffzUpdateUptime:function(){n.update_uptime()}.observes("isLive","content.id").on("init")}),this.update_uptime())},n.settings_info.stream_uptime={type:"boolean",value:!1,category:"Channel Metadata",name:"Stream Uptime",help:"Display the stream uptime under a channel by the viewer count.",on_update:function(){this.update_uptime()}},n.prototype.update_uptime=function(e){this._uptime_update&&(clearTimeout(this._uptime_update),delete this._uptime_update);var t=App.__container__.lookup("controller:channel");if(e||!this.settings.stream_uptime||!t||!t.get("isLiveAccordingToKraken")){var n=document.querySelector("#ffz-uptime-display");return void(n&&n.parentElement.removeChild(n))}this._update_uptime=setTimeout(this.update_uptime.bind(this),1e3);var i=t.get("content.stream.created_at");if(i&&(i=a.parse_date(i))){var s=Math.floor((Date.now()-i.getTime())/1e3);if(!(0>s)){var n=document.querySelector("#ffz-uptime-display span");if(!n){var r=document.querySelector("#channel .stats-and-actions .channel-stats");if(!r)return;var l=document.createElement("span");l.className="ffz stat",l.id="ffz-uptime-display",l.title="Stream Uptime (since "+i.toLocaleString()+")",l.innerHTML=o.CLOCK+" ",n=document.createElement("span"),l.appendChild(n);var c=r.querySelector(".live-count");if(c)r.insertBefore(l,c.nextSibling);else try{c=r.querySelector("script:nth-child(0n+2)"),r.insertBefore(l,c.nextSibling)}catch(u){r.insertBefore(l,r.childNodes[0])}jQuery(l).tipsy({html:!0})}n.innerHTML=a.time_to_string(s)}}}},{"../constants":3,"../utils":28}],6:[function(){var t=e.FrankerFaceZ;t.prototype.setup_chatview=function(){this.log("Hooking the Ember Chat view.");var e=App.__container__.resolve("view:chat");this._modify_cview(e);try{e.create().destroy()}catch(t){}for(var n in Ember.View.views)if(Ember.View.views.hasOwnProperty(n)){var a=Ember.View.views[n];if(a instanceof e){this.log("Adding UI link manually to Chat view.",a);try{a.$(".textarea-contain").append(this.build_ui_link(a))}catch(t){this.error("setup: build_ui_link: "+t)}}}},t.prototype._modify_cview=function(e){var t=this;e.reopen({didInsertElement:function(){this._super();try{this.$()&&this.$(".textarea-contain").append(t.build_ui_link(this))}catch(e){t.error("didInsertElement: build_ui_link: "+e)}},willClearRender:function(){this._super();try{this.$(".ffz-ui-toggle").remove()}catch(e){t.error("willClearRender: remove ui link: "+e)}},ffzUpdateLink:Ember.observer("controller.currentRoom",function(){try{t.update_ui_link()}catch(e){t.error("ffzUpdateLink: update_ui_link: "+e)}})})}},{}],7:[function(t){var n=e.FrankerFaceZ,a=t("../utils"),o=function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},i="[\\s`~<>!-#%-\\x2A,-/:;\\x3F@\\x5B-\\x5D_\\x7B}\\u00A1\\u00A7\\u00AB\\u00B6\\u00B7\\u00BB\\u00BF\\u037E\\u0387\\u055A-\\u055F\\u0589\\u058A\\u05BE\\u05C0\\u05C3\\u05C6\\u05F3\\u05F4\\u0609\\u060A\\u060C\\u060D\\u061B\\u061E\\u061F\\u066A-\\u066D\\u06D4\\u0700-\\u070D\\u07F7-\\u07F9\\u0830-\\u083E\\u085E\\u0964\\u0965\\u0970\\u0AF0\\u0DF4\\u0E4F\\u0E5A\\u0E5B\\u0F04-\\u0F12\\u0F14\\u0F3A-\\u0F3D\\u0F85\\u0FD0-\\u0FD4\\u0FD9\\u0FDA\\u104A-\\u104F\\u10FB\\u1360-\\u1368\\u1400\\u166D\\u166E\\u169B\\u169C\\u16EB-\\u16ED\\u1735\\u1736\\u17D4-\\u17D6\\u17D8-\\u17DA\\u1800-\\u180A\\u1944\\u1945\\u1A1E\\u1A1F\\u1AA0-\\u1AA6\\u1AA8-\\u1AAD\\u1B5A-\\u1B60\\u1BFC-\\u1BFF\\u1C3B-\\u1C3F\\u1C7E\\u1C7F\\u1CC0-\\u1CC7\\u1CD3\\u2010-\\u2027\\u2030-\\u2043\\u2045-\\u2051\\u2053-\\u205E\\u207D\\u207E\\u208D\\u208E\\u2329\\u232A\\u2768-\\u2775\\u27C5\\u27C6\\u27E6-\\u27EF\\u2983-\\u2998\\u29D8-\\u29DB\\u29FC\\u29FD\\u2CF9-\\u2CFC\\u2CFE\\u2CFF\\u2D70\\u2E00-\\u2E2E\\u2E30-\\u2E3B\\u3001-\\u3003\\u3008-\\u3011\\u3014-\\u301F\\u3030\\u303D\\u30A0\\u30FB\\uA4FE\\uA4FF\\uA60D-\\uA60F\\uA673\\uA67E\\uA6F2-\\uA6F7\\uA874-\\uA877\\uA8CE\\uA8CF\\uA8F8-\\uA8FA\\uA92E\\uA92F\\uA95F\\uA9C1-\\uA9CD\\uA9DE\\uA9DF\\uAA5C-\\uAA5F\\uAADE\\uAADF\\uAAF0\\uAAF1\\uABEB\\uFD3E\\uFD3F\\uFE10-\\uFE19\\uFE30-\\uFE52\\uFE54-\\uFE61\\uFE63\\uFE68\\uFE6A\\uFE6B\\uFF01-\\uFF03\\uFF05-\\uFF0A\\uFF0C-\\uFF0F\\uFF1A\\uFF1B\\uFF1F\\uFF20\\uFF3B-\\uFF3D\\uFF3F\\uFF5B\\uFF5D\\uFF5F-\\uFF65]",s=new RegExp(i+"*,"+i+"*"),r=function(e){return(e+"").replace(/&/g,"&").replace(/'/g,"'").replace(/"/g,""").replace(//g,">")},l="http://static-cdn.jtvnw.net/emoticons/v1/",c=function(e){return l+e+"/1.0 1x, "+l+e+"/2.0 2x, "+l+e+"/3.0 4x"},u=function(e){var t=e.set,n=e.set_type;return void 0===n&&(n="Channel"),t?(("00000turbo"==t||"turbo"==t)&&(t="Twitch Turbo",n=null),"Emoticon: "+e.code+"\n"+(n?n+": ":"")+t):e.code},d=function(e){{var t=this._twitch_emotes[e];t?t.set:null}return t?"string"==typeof t?t:t.tooltip?t.tooltip:t.tooltip=u(t):"???"},h=function(e,t,n,a){if(n){t&&(a.code=t),this._twitch_emotes[e]=a;for(var o=d.bind(this)(e),i=document.querySelectorAll('img[emote-id="'+e+'"]'),s=0;sYouTube: "+a.sanitize(n.title)+"
",t+="Channel: "+a.sanitize(n.channel)+" | "+a.time_to_string(n.duration)+"
",t+=a.number_commas(n.views||0)+" Views | 👍 "+a.number_commas(n.likes||0)+" 👎 "+a.number_commas(n.dislikes||0);else if("strawpoll"==n.type){t="Strawpoll: "+a.sanitize(n.title)+"
";for(var o in n.items){{var i=n.items[o];Math.floor(i/n.total*100)}t+='"}t+="
'+a.sanitize(o)+''+a.number_commas(i)+"

Total: "+a.number_commas(n.total);var s=a.parse_date(n.fetched);if(s){var r=Math.floor((s.getTime()-Date.now())/1e3);r>60&&(t+="
Data was cached "+a.time_to_string(r)+" ago.")}}else if("twitch"==n.type){t="Twitch: "+a.sanitize(n.display_name)+"
";var l=a.parse_date(n.since);l&&(t+="Member Since: "+a.date_string(l)+"
"),t+="Views: "+a.number_commas(n.views)+" | Followers: "+a.number_commas(n.followers)+""}else if("twitter"==n.type)t="Tweet By: "+a.sanitize(n.user)+"
",t+=a.sanitize(n.tweet);else if("reputation"==n.type){if(t=''+a.sanitize(n.full.toLowerCase())+"",n.trust<50||n.safety<50||n.tags&&n.tags.length>0){t+="
";var c=!1;(n.trust<50||n.safety<50)&&(n.unsafe=!0,t+="Potentially Unsafe Link
",t+="Trust: "+n.trust+"% | Child Safety: "+n.safety+"%",c=!0),n.tags&&n.tags.length>0&&(t+=(c?"
":"")+"Tags: "+n.tags.join(", ")),t+="
Data Source: WOT"}}else n.full&&(t=''+a.sanitize(n.full.toLowerCase())+"");return t||(t=''+a.sanitize(e.toLowerCase())+""),n.tooltip=t,t},m=function(e,t,n){if(t){this._link_data[e]=n,n.unsafe=!1;var a,o=p.bind(this)(e),i="/"==e.charAt(e.length-1)?e.substr(0,e.length-1):null;if(a=document.querySelectorAll(i?'span.message a[href="'+e+'"], span.message a[href="'+i+'"], span.message a[data-url="'+e+'"], span.message a[data-url="'+i+'"]':'span.message a[href="'+e+'"], span.message a[data-url="'+e+'"]'),this.settings.link_info)for(var s=0;sBeta",help:"Check links against known bad websites, unshorten URLs, and show YouTube info."},n.settings_info.chat_rows={type:"boolean",value:!1,category:"Chat",no_bttv:!0,name:"Chat Line Backgrounds",help:"Display alternating background colors for lines in chat.",on_update:function(e){this.has_bttv||document.body.classList.toggle("ffz-chat-background",e)}},n.prototype.setup_line=function(){document.body.classList.toggle("ffz-chat-colors",!this.has_bttv&&this.settings.fix_color),document.body.classList.toggle("ffz-chat-background",!this.has_bttv&&this.settings.chat_rows),this._colors={},this._last_row={};var t=this._fix_color_style=document.createElement("style");t.id="ffz-style-username-colors",t.type="text/css",document.head.appendChild(t),this._twitch_emotes={},this._link_data={},this.log("Hooking the Ember Line controller.");var a=App.__container__.resolve("controller:line"),o=this;a.reopen({tokenizedMessage:function(){var e=this._super();try{var t=performance.now();e=o._remove_banned(e),e=o._emoticonize(this,e);var a=o.get_user();a&&this.get("model.from")==a.login||(e=o._mentionize(this,e));var i=this.get("model.tags.display-name");i&&i.length&&(n.capitalization[this.get("model.from")]=[i.trim(),Date.now()]);var s=performance.now();s-t>5&&o.log("Tokenizing Message Took Too Long - "+(s-t)+"ms",e,!1,!0)}catch(r){try{o.error("LineController tokenizedMessage: "+r)}catch(r){}}return e}.property("model.message","isModeratorOrHigher")}),this.log("Hooking the Ember Line view.");var a=App.__container__.resolve("view:line");a.reopen({didInsertElement:function(){this._super();try{var t=performance.now(),a=this.get("element"),i=this.get("context"),s=i.get("model.from"),r=i.get("parentController.content.id"),l=i.get("model.color"),d=i.get("model.ffz_alternate");l&&o._handle_color(l),void 0===d&&(d=o._last_row[r]=o._last_row.hasOwnProperty(r)?!o._last_row[r]:!1,this.set("context.model.ffz_alternate",d)),a.classList.toggle("ffz-alternate",d),a.setAttribute("data-room",r),a.setAttribute("data-sender",s),a.setAttribute("data-deleted",i.get("model.deleted")),o.render_badge(this);var p=a.querySelector("span.mentioned");if(p&&(a.classList.add("ffz-mentioned"),o.settings.highlight_notifications&&!document.hasFocus()&&!this.get("context.model.ffz_notified"))){var _=n.get_capitalization(r),f=n.get_capitalization(s),g=_,v=this.get("context.model.message");this.get("context.parentController.content.isGroupRoom")&&(g=this.get("context.parentController.content.tmiRoom.displayName")),v="action"==this.get("context.model.style")?"* "+f+" "+v:f+": "+v,o.show_notification(v,"Twitch Chat Mention in "+g,_,6e4,e.focus.bind(e))}this.set("context.model.ffz_notified",!0);for(var b=a.querySelectorAll("a.deleted-link"),y=0;y-1&&(-1===t.indexOf("/")||t.indexOf("@")5&&o.log("Line Took Too Long - "+P+"ms",a.innerHTML,!1,!0)}catch(H){try{o.error("LineView didInsertElement: "+H)}catch(H){}}}});var i=this.get_user();i&&i.name&&(n.capitalization[i.login]=[i.name,Date.now()])},n.prototype._handle_color=function(e){if(e&&!this._colors[e]){this._colors[e]=!0;var t=parseInt(e.substr(1),16),n=[t>>16,t>>8&255,255&t],o=a.get_luminance(n),i="",s='span[style="color:'+e+'"]',r=!1;if(o>.3){r=!0;for(var l=127,c=n;l--&&(c=a.darken(c),!(a.get_luminance(c)<=.3)););i+=".ffz-chat-colors .ember-chat-container:not(.dark) .chat-line "+s+", .ffz-chat-colors .chat-container:not(.dark) .chat-line "+s+" { color: "+a.rgb_to_css(c)+" !important; }\n"}else i+=".ffz-chat-colors .ember-chat-container:not(.dark) .chat-line "+s+", .ffz-chat-colors .chat-container:not(.dark) .chat-line "+s+" { color: "+e+" !important; }\n";if(.15>o){r=!0;for(var l=127,c=n;l--&&(c=a.brighten(c),!(a.get_luminance(c)>=.15)););i+=".ffz-chat-colors .theatre .chat-container .chat-line "+s+", .ffz-chat-colors .chat-container.dark .chat-line "+s+", .ffz-chat-colors .ember-chat-container.dark .chat-line "+s+" { color: "+a.rgb_to_css(c)+" !important; }\n"}else i+=".ffz-chat-colors .theatre .chat-container .chat-line "+s+", .ffz-chat-colors .chat-container.dark .chat-line "+s+", .ffz-chat-colors .ember-chat-container.dark .chat-line "+s+" { color: "+e+" !important; }\n";r&&(this._fix_color_style.innerHTML+=i)}},n.capitalization={},n._cap_fetching=0,n.get_capitalization=function(t,a){if(e.BetterTTV&&BetterTTV.chat&&BetterTTV.chat.helpers.lookupDisplayName)return BetterTTV.chat.helpers.lookupDisplayName(t);if(!t)return t;if(t=t.toLowerCase(),"jtv"==t||"twitchnotify"==t)return t;var o=n.capitalization[t];return o&&Date.now()-o[1]<36e5?o[0]:(n._cap_fetching<25&&(n._cap_fetching++,n.get().ws_send("get_display_name",t,function(e,o){var i=e?o:t;n.capitalization[t]=[i,Date.now()],n._cap_fetching--,"function"==typeof a&&a(i)})),o?o[0]:t)},n._regex_cache={},n._get_regex=function(e){return n._regex_cache[e]=n._regex_cache[e]||RegExp("\\b"+o(e)+"\\b","ig")},n._words_to_regex=function(e){var t=n._regex_cache[e];if(!t){for(var a="",s=0;s<banned link>',own:!0}:s)}return o},n.prototype._emoticonize=function(e,t){var n=e.get("parentController.model.id"),a=e.get("model.from"),o=this,i=this.getEmotes(a,n),s=[];return _.each(i,function(e){var n=o.emote_sets[e];n&&_.each(n.emotes,function(e){_.any(t,function(t){return _.isString(t)&&t.match(e.regex)})&&s.push(e)})}),s.length?("string"==typeof t&&(t=[t]),_.each(s,function(e){var n={isEmoticon:!0,cls:e.klass,srcSet:e.url+" 1x",emoticonSrc:e.url+'" data-ffz-emote="'+encodeURIComponent(JSON.stringify([e.id,e.set_id])),altText:e.hidden?"???":e.name};t=_.compact(_.flatten(_.map(t,function(t){if(_.isObject(t))return t;var a=t.split(e.regex),o=[];return a.forEach(function(e,t){o.push(e),t!==a.length-1&&o.push(n)}),o})))}),t):t}},{"../utils":28}],8:[function(t){var n=e.FrankerFaceZ,a=t("../utils"),o={ESC:27,P:80,B:66,T:84,U:85},i=[["5m",300],["10m",600],["1hr",3600],["12hr",43200],["24hr",86400]],s='',r='';n.settings_info.enhanced_moderation={type:"boolean",value:!1,no_bttv:!0,category:"Chat",name:"Enhanced Moderation",help:"Use /p, /t, /u and /b in chat to moderate chat, or use hotkeys with moderation cards."},n.prototype.setup_mod_card=function(){this.log("Hooking the Ember Moderation Card view.");var t=App.__container__.resolve("component:moderation-card"),n=this;t.reopen({didInsertElement:function(){this._super(),e._card=this;try{if(n.has_bttv||!n.settings.enhanced_moderation)return;var t=this.get("element"),l=this.get("controller");if(t.classList.add("ffz-moderation-card"),l.get("cardInfo.isModeratorOrHigher")){t.classList.add("ffz-is-mod"),t.setAttribute("tabindex",1),t.addEventListener("keyup",function(e){var t=e.keyCode||e.which,n=l.get("cardInfo.user.id"),a=App.__container__.lookup("controller:chat").get("currentRoom");if(t==o.P)a.send("/timeout "+n+" 1");else if(t==o.B)a.send("/ban "+n);else if(t==o.T)a.send("/timeout "+n+" 600");else if(t==o.U)a.send("/unban "+n);else if(t!=o.ESC)return;l.send("hideModOverlay")});var c=document.createElement("div");c.className="interface clearfix"; var u=function(e){var t=l.get("cardInfo.user.id"),n=App.__container__.lookup("controller:chat").get("currentRoom");n.send(-1===e?"/unban "+t:"/timeout "+t+" "+e)},d=function(e,t){var n=document.createElement("button");return n.className="button",n.innerHTML=e,n.title="Timeout User for "+a.number_commas(t)+" Second"+(1!=t?"s":""),600===t?n.title="(T)"+n.title.substr(1):1===t&&(n.title="(P)urge - "+n.title),jQuery(n).tipsy(),n.addEventListener("click",u.bind(this,t)),n};c.appendChild(d("Purge",1));var h=document.createElement("span");h.className="right",c.appendChild(h);for(var p=0;p button");b&&b.classList.contains("message-button")&&(b.innerHTML=s,b.classList.add("glyph-only"),b.classList.add("message"),b.title="Message User",jQuery(b).tipsy()),this.$().draggable({start:function(){t.focus()}}),t.focus()}catch(y){try{n.error("ModerationCardView didInsertElement: "+y)}catch(y){}}}})},n.chat_commands.purge=n.chat_commands.p=function(e,t){if(!t||!t.length)return"Purge Usage: /p username [more usernames separated by spaces]";if(t.length>10)return"Please only purge up to 10 users at once.";for(var n=0;n10)return"Please only ban up to 10 users at once.";for(var n=0;n10)return"Please only unban up to 10 users at once.";for(var n=0;nn?this._legacy_add_room(e,t,n):void 0)})},n.prototype._legacy_load_room_css=function(e,t,n){var s=e,r=s.match(i);r&&r[1]&&(s=r[1]);var l={id:e,menu_sets:[s],sets:[s],moderator_badge:null,css:null};return n&&(n=n.replace(a,"").trim()),n&&(n=n.replace(o,function(e,t){return l.moderator_badge||"modicon.png"!==t.substr(-11)?e:(l.moderator_badge=t,"")})),l.css=n||null,this._load_room_json(e,t,l)}},{"../constants":3,"../utils":28}],10:[function(){var t=e.FrankerFaceZ;t.prototype.setup_viewers=function(){this.log("Hooking the Ember Viewers controller.");var e=App.__container__.resolve("controller:viewers");this._modify_viewers(e)},t.prototype._modify_viewers=function(e){var n=this;e.reopen({lines:function(){var e=this._super();try{var a=[],o={},i=null,s=App.__container__.lookup("controller:channel"),r=this.get("parentController.model.id"),l=s&&s.get("id");if(l){var c=s.get("display_name");c&&(t.capitalization[l]=[c,Date.now()])}r!=l&&(l=null);for(var u=0;un?this._legacy_load_set(e,t,n):"function"==typeof t&&t(!1))})},n.prototype._legacy_load_css=function(e,t,n){var i={},s={id:e,emotes:i,extra_css:null},r=this;"global"==e?s.title="Global":"globalevent"==e?s.title="Global Event":".donor"==e&&(s.title="Donor"),n=n.replace(a,function(t,n,a,o,s,c,u,d){s=parseInt(s),c=parseInt(c),u=l(u,s);var h="."===o.substr(o.lastIndexOf("/")+1,1),p=++r._last_emote_id,m={id:p,set_id:e,hidden:h,name:a,height:s,width:c,url:o,margins:u,extra_css:d};return i[p]=m,""}).trim(),n&&n.replace(o,function(e,t){s.icon||"modicon.png"!==t.substr(-11)||(s.icon=t)}),this._load_set_json(e,t,s)}},{"./constants":3,"./utils":28}],12:[function(){var t=e.FrankerFaceZ;t.prototype.find_bttv=function(t,n){return this.has_bttv=!1,e.BTTVLOADED?this.setup_bttv(n||0):void(n>=6e4?this.log("BetterTTV was not detected after 60 seconds."):setTimeout(this.find_bttv.bind(this,t,(n||0)+t),t))},t.prototype.setup_bttv=function(e){this.log("BetterTTV was detected after "+e+"ms. Hooking."),this.has_bttv=!0,this.log("WOO"),document.body.classList.remove("ffz-dark"),this._dark_style&&(this._dark_style.parentElement.removeChild(this._dark_style),delete this._dark_style),document.body.classList.remove("ffz-chat-colors"),document.body.classList.remove("ffz-chat-background");var t=BetterTTV.chat.helpers.sendMessage,n=this;BetterTTV.chat.helpers.sendMessage=function(e){var a=e.split(" ",1)[0].toLowerCase();return"/ffz"!==a?t(e):void n.run_ffz_command(e.substr(5),BetterTTV.chat.store.currentRoom)};var a,o=BetterTTV.chat.handlers.onPrivmsg;BetterTTV.chat.handlers.onPrivmsg=function(e,t){a=e;var n=o(e,t);return a=null,n};var i=BetterTTV.chat.templates.privmsg;BetterTTV.chat.templates.privmsg=function(e,t,o,s,r){try{return n.bttv_badges(r),'
'+BetterTTV.chat.templates.timestamp(r.time)+" "+(s?BetterTTV.chat.templates.modicons():"")+" "+BetterTTV.chat.templates.badges(r.badges)+BetterTTV.chat.templates.from(r.nickname,r.color)+BetterTTV.chat.templates.message(r.sender,r.message,r.emotes,t?r.color:!1)+"
"}catch(l){return n.log("Error: ",l),i(e,t,o,s,r)}};var s,r=BetterTTV.chat.templates.message;BetterTTV.chat.templates.message=function(e,t,a,o){try{o=o||!1;var i=encodeURIComponent(t);if("jtv"!==e){s=e;var l=BetterTTV.chat.templates.emoticonize(t,a);s=null;for(var c=0;c'+t+"
"}catch(u){return n.log("Error: ",u),r(e,t,a,o)}};var l=BetterTTV.chat.templates.emoticonize;BetterTTV.chat.templates.emoticonize=function(e,t){var o=l(e,t),i=n.getEmotes(s,a),t=[];return _.each(i,function(e){var a=n.emote_sets[e];a&&_.each(a.emotes,function(e){_.any(o,function(t){return _.isString(t)&&t.match(e.regex)})&&t.push(e)})}),t.length?(_.each(t,function(e){var t=[''+e.name+''],n=o;if(o=[],!n||!n.length)return o;for(var a=0;a=6e4?this.log("Emote Menu for Twitch was not detected after 60 seconds."):setTimeout(this.find_emote_menu.bind(this,t,(n||0)+t),t))},t.prototype.setup_emote_menu=function(e){this.log("Emote Menu for Twitch was detected after "+e+"ms. Registering emote enumerator."),emoteMenu.registerEmoteGetter("FrankerFaceZ",this._emote_menu_enumerator.bind(this))},t.prototype._emote_menu_enumerator=function(){for(var e=this.get_user(),n=e?e.login:null,a=App.__container__.lookup("controller:chat"),o=a?a.get("currentRoom.id"):null,i=this.getEmotes(n,o),s=[],r=0;r=6e4?this.log('Twitch application not detected in "'+location.toString()+'". Aborting.'):setTimeout(this.initialize.bind(this,t,(n||0)+t),t)))},n.prototype.setup_normal=function(t){var a=e.performance&&performance.now?performance.now():Date.now();this.log("Found non-Ember Twitch after "+(t||0)+' ms in "'+location+'". Initializing FrankerFaceZ version '+n.version_info),this.users={},this.load_settings(),this.setup_dark(),this.ws_create(),this.setup_emoticons(),this.setup_badges(),this.setup_notifications(),this.setup_css(),this.find_bttv(10);var o=e.performance&&performance.now?performance.now():Date.now(),i=o-a;this.log("Initialization complete in "+i+"ms")},n.prototype.is_dashboard=!1,n.prototype.setup_dashboard=function(t){var a=e.performance&&performance.now?performance.now():Date.now();this.log("Found Twitch Dashboard after "+(t||0)+' ms in "'+location+'". Initializing FrankerFaceZ version '+n.version_info),this.users={},this.is_dashboard=!0,this.load_settings(),this.setup_dark(),this.ws_create(),this.setup_emoticons(),this.setup_badges(),this.setup_notifications(),this.setup_css(),this.find_bttv(10);var o=e.performance&&performance.now?performance.now():Date.now(),i=o-a;this.log("Initialization complete in "+i+"ms")},n.prototype.setup_ember=function(t){var a=e.performance&&performance.now?performance.now():Date.now();this.log("Found Twitch application after "+(t||0)+' ms in "'+location+'". Initializing FrankerFaceZ version '+n.version_info),this.users={},this.load_settings(),this.setup_dark(),this.ws_create(),this.setup_emoticons(),this.setup_badges(),this.setup_channel(),this.setup_room(),this.setup_line(),this.setup_chatview(),this.setup_viewers(),this.setup_mod_card(),this.setup_notifications(),this.setup_css(),this.setup_menu(),this.setup_my_emotes(),this.setup_races(),this.find_bttv(10),this.find_emote_menu(10),this.check_ff();var o=e.performance&&performance.now?performance.now():Date.now(),i=o-a;this.log("Initialization complete in "+i+"ms")}},{"./badges":1,"./commands":2,"./debug":4,"./ember/channel":5,"./ember/chatview":6,"./ember/line":7,"./ember/moderation-card":8,"./ember/room":9,"./ember/viewers":10,"./emoticons":11,"./ext/betterttv":12,"./ext/emote_menu":13,"./featurefriday":15,"./settings":16,"./shims":17,"./socket":18,"./ui/about_page":19,"./ui/dark":20,"./ui/menu":21,"./ui/menu_button":22,"./ui/my_emotes":23,"./ui/notifications":24,"./ui/races":25,"./ui/styles":26,"./ui/viewer_count":27}],15:[function(t){var n=e.FrankerFaceZ,a=t("./constants");n.prototype.feature_friday=null,n.prototype.check_ff=function(e){e||this.log("Checking for Feature Friday data..."),jQuery.ajax(a.SERVER+"script/event.json",{cache:!1,dataType:"json",context:this}).done(function(e){return this._load_ff(e)}).fail(function(t){return 404==t.status?this._load_ff(null):(e=e||0,e++,10>e?setTimeout(this.check_ff.bind(this,e),250):this._load_ff(null))})},n.ws_commands.reload_ff=function(){this.check_ff()},n.prototype._feature_friday_ui=function(e,t,n){if(this.feature_friday&&this.feature_friday.channel!=e){this._emotes_for_sets(t,n,[this.feature_friday.set],this.feature_friday.title,this.feature_friday.icon,"FrankerFaceZ");var a=App.__container__.lookup("controller:channel");if(!a||a.get("id")!=this.feature_friday.channel){var o=this.feature_friday,i=document.createElement("div"),s=document.createElement("a");i.className="chat-menu-content",i.style.textAlign="center";var r=o.display_name+(o.live?" is live now!":"");s.className="button primary",s.classList.toggle("live",o.live),s.classList.toggle("blue",this.has_bttv&&BetterTTV.settings.get("showBlueButtons")),s.href="http://www.twitch.tv/"+o.channel,s.title=r,s.target="_new",s.innerHTML=""+r+"",i.appendChild(s),t.appendChild(i)}}},n.prototype._load_ff=function(e){if(this.feature_friday){this.global_sets.removeObject(this.feature_friday.set);var t=this.emote_sets[this.feature_friday.set];t&&(t.global=!1),this.feature_friday=null,this.update_ui_link()}e&&e.set&&e.channel&&(this.feature_friday={set:e.set,channel:e.channel,live:!1,title:e.title||"Feature Friday",display_name:n.get_capitalization(e.channel,this._update_ff_name.bind(this))},this.global_sets.push(e.set),this.load_set(e.set,this._update_ff_set.bind(this)),this._update_ff_live())},n.prototype._update_ff_live=function(){if(this.feature_friday){var e=this;Twitch.api.get("streams/"+this.feature_friday.channel).done(function(t){e.feature_friday.live=null!=t.stream,e.update_ui_link()}).always(function(){e.feature_friday.timer=setTimeout(e._update_ff_live.bind(e),12e4)})}},n.prototype._update_ff_set=function(e,t){t&&(t.global=!0)},n.prototype._update_ff_name=function(e){this.feature_friday&&(this.feature_friday.display_name=e)}},{"./constants":3}],16:[function(t){var n=e.FrankerFaceZ,a=t("./constants");make_ls=function(e){return"ffz_setting_"+e},toggle_setting=function(e,t){var n=!this.settings.get(t);this.settings.set(t,n),e.classList.toggle("active",n)},n.settings_info={},n.prototype.load_settings=function(){this.log("Loading settings."),this.settings={};for(var t in n.settings_info)if(n.settings_info.hasOwnProperty(t)){var a=n.settings_info[t],o=a.storage_key||make_ls(t),i=a.hasOwnProperty("value")?a.value:void 0;if(localStorage.hasOwnProperty(o))try{i=JSON.parse(localStorage.getItem(o))}catch(s){this.log('Error loading value for "'+t+'": '+s)}this.settings[t]=i}this.settings.get=this._setting_get.bind(this),this.settings.set=this._setting_set.bind(this),this.settings.del=this._setting_del.bind(this),e.addEventListener("storage",this._setting_update.bind(this),!1)},n.settings_info.replace_twitch_menu={type:"boolean",value:!1,name:"Replace Twitch Emoticon Menu Beta",help:"Completely replace the default Twitch emoticon menu.",on_update:function(e){document.body.classList.toggle("ffz-menu-replace",e)}},n.menu_pages.settings={render:function(e,t){var a={},o=[];for(var i in n.settings_info)if(n.settings_info.hasOwnProperty(i)){var s=n.settings_info[i],r=s.category||"Miscellaneous",l=a[r];if(void 0!==s.visible&&null!==s.visible){var c=s.visible;if("function"==typeof s.visible&&(c=s.visible.bind(this)()),!c)continue}l||(o.push(r),l=a[r]=[]),l.push([i,s])}o.sort(function(e,t){var e=e.toLowerCase(),t=t.toLowerCase();return"debugging"===e&&(e="zzz"+e),"debugging"===t&&(t="zzz"+t),t>e?-1:e>t?1:0});for(var u=0;un?-1:n>a?1:i>o?-1:o>i?1:0});for(var _=0;_",v.className="switch-label",v.innerHTML=s.name,f.appendChild(y),f.appendChild(v),y.addEventListener("click",toggle_setting.bind(this,y,i))}else{f.classList.add("option");var w=document.createElement("a");w.innerHTML=s.name,w.href="#",f.appendChild(w),w.addEventListener("click",s.method.bind(this))}if(s.help){var b=document.createElement("span");b.className="help",b.innerHTML=s.help,f.appendChild(b)}}p.appendChild(f)}t.appendChild(p)}},name:"Settings",icon:a.GEAR,sort_order:99999,wide:!0},n.prototype._setting_update=function(t){if(t||(t=e.event),t.key&&"ffz_setting_"===t.key.substr(0,12)){var a=t.key,o=a.substr(12),i=void 0,s=n.settings_info[o];if(!s){for(o in n.settings_info)if(n.settings_info.hasOwnProperty(o)&&(s=n.settings_info[o],s.storage_key==a))break;if(s.storage_key!=a)return}this.log("Updated Setting: "+o);try{i=JSON.parse(t.newValue)}catch(r){this.log('Error loading new value for "'+o+'": '+r),i=s.value||void 0}if(this.settings[o]=i,s.on_update)try{s.on_update.bind(this)(i,!1)}catch(r){this.log('Error running updater for setting "'+o+'": '+r)}}},n.prototype._setting_get=function(e){return this.settings[e]},n.prototype._setting_set=function(e,t){var a=n.settings_info[e],o=a.storage_key||make_ls(e),i=JSON.stringify(t);if(this.settings[e]=t,localStorage.setItem(o,i),this.log('Changed Setting "'+e+'" to: '+i),a.on_update)try{a.on_update.bind(this)(t,!0)}catch(s){this.log('Error running updater for setting "'+e+'": '+s)}},n.prototype._setting_del=function(e){var t=n.settings_info[e],a=t.storage_key||make_ls(e),o=void 0;if(localStorage.hasOwnProperty(a)&&localStorage.removeItem(a),delete this.settings[e],t&&(o=this.settings[e]=t.hasOwnProperty("value")?t.value:void 0),t.on_update)try{t.on_update.bind(this)(o,!0)}catch(i){this.log('Error running updater for setting "'+e+'": '+i)}}},{"./constants":3}],17:[function(){Array.prototype.equals=function(e){if(!e)return!1;if(this.length!=e.length)return!1;for(var t=0,n=this.length;n>t;t++)if(this[t]instanceof Array&&e[t]instanceof Array){if(!this[t].equals(e[t]))return!1}else if(this[t]!=e[t])return!1;return!0}},{}],18:[function(){var t=e.FrankerFaceZ;t.prototype._ws_open=!1,t.prototype._ws_delay=0,t.ws_commands={},t.ws_on_close=[],t.prototype.ws_create=function(){var e,n=this;this._ws_last_req=0,this._ws_callbacks={},this._ws_pending=this._ws_pending||[];try{e=this._ws_sock=new WebSocket("ws://catbag.frankerfacez.com/")}catch(a){return this._ws_exists=!1,this.log("Error Creating WebSocket: "+a)}this._ws_exists=!0,e.onopen=function(){n._ws_open=!0,n._ws_delay=0,n.log("Socket connected.");var e=n.get_user();if(e&&n.ws_send("setuser",e.login),n.is_dashboard){var t=location.pathname.match(/\/([^\/]+)/);t&&n.ws_send("sub",t[1])}for(var a in n.rooms)n.rooms.hasOwnProperty(a)&&n.ws_send("sub",a);var o=n._ws_pending;n._ws_pending=[];for(var i=0;i0){o=!0;break}}var l=document.createElement("div"),c="";c+="

FrankerFaceZ

",c+='
new ways to woof
',l.className="chat-menu-content center",l.innerHTML=c,t.appendChild(l);var u=0,d=l.querySelector("h1");d&&d.addEventListener("click",function(){if(d.style.cursor="pointer",u++,u>=3){u=0;var e=document.querySelector(".app-main")||document.querySelector(".ember-chat-container");e&&e.classList.toggle("ffz-flip")}setTimeout(function(){u=0,d.style.cursor=""},2e3)});var h=document.createElement("div"),p=document.createElement("a"),m="To use custom emoticons in "+(o?"this channel":"tons of channels")+", get FrankerFaceZ from http://www.frankerfacez.com";p.className="button primary",p.innerHTML="Advertise in Chat",p.addEventListener("click",this._add_emote.bind(this,e,m)),h.appendChild(p);var _=document.createElement("a");_.className="button ffz-donate",_.href="http://www.frankerfacez.com/donate.html",_.target="_new",_.innerHTML="Donate",h.appendChild(_),h.className="chat-menu-content center",t.appendChild(h);var f=document.createElement("div");c='',c+='',c+='',c+='',c+='',f.className="chat-menu-content center",f.innerHTML=c; var g=!1;f.querySelector("#ffz-debug-logs").addEventListener("click",function(){g||(g=!0,i._pastebin(i._log_data.join("\n"),function(e){g=!1,e?prompt("Your FrankerFaceZ logs have been uploaded to the URL:",e):alert("There was an error uploading the FrankerFaceZ logs.")}))}),t.appendChild(f)}}},{"../constants":3}],20:[function(t){var n=e.FrankerFaceZ,a=t("../constants");n.settings_info.twitch_chat_dark={type:"boolean",value:!1,visible:!1},n.settings_info.dark_twitch={type:"boolean",value:!1,no_bttv:!0,name:"Dark Twitch",help:"Apply a dark background to channels and other related pages for easier viewing.",on_update:function(t){if(!this.has_bttv){document.body.classList.toggle("ffz-dark",t);var n=e.App?App.__container__.lookup("controller:settings").get("model"):void 0;t?(this._load_dark_css(),n&&this.settings.set("twitch_chat_dark",n.get("darkMode")),n&&n.set("darkMode",!0)):n&&n.set("darkMode",this.settings.twitch_chat_dark)}}},n.prototype.setup_dark=function(){this.has_bttv||(document.body.classList.toggle("ffz-dark",this.settings.dark_twitch),this.settings.dark_twitch&&e.App&&App.__container__.lookup("controller:settings").set("model.darkMode",!0),this.settings.dark_twitch&&this._load_dark_css())},n.prototype._load_dark_css=function(){if(!this._dark_style){this.log("Injecting FrankerFaceZ Dark Twitch CSS.");var e=this._dark_style=document.createElement("link");e.id="ffz-dark-css",e.setAttribute("rel","stylesheet"),e.setAttribute("href",a.SERVER+"script/dark.css?_="+Date.now()),document.head.appendChild(e)}}},{"../constants":3}],21:[function(t){var n=e.FrankerFaceZ,a=t("../constants"),o=t("../utils"),i="http://static-cdn.jtvnw.net/emoticons/v1/";n.prototype.setup_menu=function(){this.log("Installing mouse-up event to auto-close menus.");var e=this;jQuery(document).mouseup(function(t){var n,a=e._popup;a&&(a=jQuery(a),n=a.parent(),n.is(t.target)||0!==n.has(t.target).length||(a.remove(),delete e._popup,e._popup_kill&&e._popup_kill(),delete e._popup_kill))}),document.body.classList.toggle("ffz-menu-replace",this.settings.replace_twitch_menu)},n.menu_pages={},n.prototype.build_ui_popup=function(e){var t=this._popup;if(t)return t.parentElement.removeChild(t),delete this._popup,this._popup_kill&&this._popup_kill(),void delete this._popup_kill;var o=document.createElement("div"),i=document.createElement("div"),s=document.createElement("ul"),r=this.has_bttv?BetterTTV.settings.get("darkenedMode"):!1;o.className="emoticon-selector chat-menu ffz-ui-popup",i.className="emoticon-selector-box dropmenu",o.appendChild(i),o.classList.toggle("dark",r);var l=document.createElement("div");l.className="ffz-ui-menu-page",i.appendChild(l),s.className="menu clearfix",i.appendChild(s);var c=document.createElement("li");c.className="title",c.innerHTML=""+(a.DEBUG?"[DEV] ":"")+"FrankerFaceZ",s.appendChild(c);var u=[];for(var d in n.menu_pages)if(n.menu_pages.hasOwnProperty(d)){var h=n.menu_pages[d];h&&(!h.hasOwnProperty("visible")||h.visible&&("function"!=typeof h.visible||h.visible.bind(this)()))&&u.push([h.sort_order||0,d,h])}u.sort(function(e,t){if(e[0]t[0])return-1;var n=e[1].toLowerCase(),a=t[1].toLowerCase();return a>n?1:n>a?-1:0});for(var p=0;p0,u.className="emoticon-grid",d.className="heading",c&&(d.style.backgroundImage='url("'+c+'")'),d.innerHTML='TwitchSubscriber Emoticons',u.appendChild(d);for(var p=r.get("emoticons"),m=0;m0&&t.appendChild(u),l){var b=a.room.get("channel.isSubscribed.content");if(b=b.length>0?b[b.length-1]:void 0,b&&b.purchase_profile&&!b.purchase_profile.will_renew){var y=o.parse_date(b.access_end||"");w=document.createElement("div"),k=document.createElement("div"),F=document.createElement("span"),end_time=y?Math.floor((y.getTime()-Date.now())/1e3):null,w.className="subscribe-message",k.className="non-subscriber-message",w.appendChild(k),F.className="unlock-text",F.innerHTML="Subscription expires in "+o.time_to_string(end_time,!0,!0),k.appendChild(F),t.appendChild(w)}}else{var w=document.createElement("div"),k=document.createElement("div"),F=document.createElement("span"),E=document.createElement("a");w.className="subscribe-message",k.className="non-subscriber-message",w.appendChild(k),F.className="unlock-text",F.innerHTML="Subscribe to unlock Emoticons",k.appendChild(F),E.className="action subscribe-button button primary",E.href=r.get("product_url"),E.innerHTML='",k.appendChild(E),t.appendChild(w)}}}this._emotes_for_sets(t,e,a&&a.menu_sets||[],this.feature_friday||s?"Channel Emoticons":null,"http://cdn.frankerfacez.com/channel/global/devicon.png","FrankerFaceZ"),this._feature_friday_ui(n,t,e)},name:"Channel",icon:a.ZREKNARF},n.prototype._emotes_for_sets=function(e,t,n,a,o,i){var s=document.createElement("div"),r=0;if(s.className="emoticon-grid",null!=a){var l=document.createElement("div");if(l.className="heading",i){var c=document.createElement("span");c.className="right",c.appendChild(document.createTextNode(i)),l.appendChild(c)}l.appendChild(document.createTextNode(a)),o&&(l.style.backgroundImage='url("'+o+'")'),s.appendChild(l)}for(var u=0;u0){i=!0;break}}t.classList.toggle("no-emotes",!i),t.classList.toggle("live",l),t.classList.toggle("dark",s),t.classList.toggle("blue",r)}}},{"../constants":3}],23:[function(t){var n=e.FrankerFaceZ,a=t("../constants"),o="http://static-cdn.jtvnw.net/emoticons/v1/",i={"00000turbo":!0},s={"#-?[\\\\/]":"#-/",":-?(?:7|L)":":-7","\\<\\;\\]":"<]","\\:-?(S|s)":":-S","\\:-?\\\\":":-\\","\\:\\>\\;":":>","B-?\\)":"B-)","\\:-?[z|Z|\\|]":":-Z","\\:-?\\)":":-)","\\:-?\\(":":-(","\\:-?(p|P)":":-P","\\;-?(p|P)":";-P","\\<\\;3":"<3","\\:-?[\\\\/]":":-/","\\;-?\\)":";-)","R-?\\)":"R-)","[o|O](_|\\.)[o|O]":"O.o","\\:-?D":":-D","\\:-?(o|O)":":-O","\\>\\;\\(":">(","Gr(a|e)yFace":"GrayFace"},r=function(e){var t=App.__container__.lookup("controller:chat"),n=t.get("currentRoom.id"),a=e.rooms[n],o=a?a.room.tmiSession:null,i=o&&o._emotesParser&&o._emotesParser.emoticonSetIds||"0",s=e.get_user(),r=s&&e.users[s.login]&&e.users[s.login].sets||[];return i=i.split(",").removeObject("0"),e.settings.global_emotes_in_menu&&(i.push("0"),r=_.union(r,e.global_sets)),[i,r]};n.settings_info.global_emotes_in_menu={type:"boolean",value:!1,name:"Display Global Emotes in My Emotes",help:"Display the global Twitch emotes in the My Emoticons menu."},n.prototype.setup_my_emotes=function(){if(this._twitch_emote_sets={},this._twitch_set_to_channel={},localStorage.ffzTwitchSets)try{this._twitch_set_to_channel=JSON.parse(localStorage.ffzTwitchSets)}catch(e){}this._twitch_set_to_channel[0]="twitch_global",this._twitch_set_to_channel[33]="twitch_tfaces",this._twitch_set_to_channel[42]="twitch_tfaces"},n.menu_pages.my_emotes={name:"My Emoticons",icon:a.EMOTE,visible:function(){var e=r(this);return e[0].length>0||e[1].length>0},render:function(e,t){var a=r(this),l=this;new RSVP.Promise(function(e){for(var t=[],o=0;oe?-1:e>t?1:0}),a.emotes=o,a.source="Twitch"}e()}).fail(function(){e()}):e()}),new RSVP.Promise(function(e){if(!t.length)return e();var a=[],o=t,s=function(e,t){var o=l._twitch_emote_sets[e]=l._twitch_emote_sets[e]||{};if(t&&!i[t]){if("twitch_global"==t)return n.capitalization["global emoticons"]=["Global Emoticons",Date.now()],o.channel="Global Emoticons",void(o.badge="//cdn.frankerfacez.com/channel/global/twitch_logo.png");if("turbo"==t||"twitch_tfaces"==t)return o.channel="Twitch Turbo",void(o.badge="//cdn.frankerfacez.com/script/turbo_badge.png");a.push(new RSVP.Promise(function(e,t,n){Twitch.api.get("chat/"+t+"/badges",null,{version:3}).done(function(t){t.subscriber&&t.subscriber.image&&(e.badge=t.subscriber.image),n()}).fail(n)}.bind(this,o,t)));var s=t.toLowerCase(),r=n.capitalization[s];return r&&Date.now()-r[1]<36e5?void(o.channel=r[0]):void a.push(new RSVP.Promise(function(e,t,a,o){l.ws_send("get_display_name",t,function(i,s){var r=i?s:a;n.capitalization[t]=[r,Date.now()],e.channel=r,o()})||(e.channel=a,o()),setTimeout(function(e,t,n){e.channel||(e.channel=t),n()}.bind(this,e,a,o),500)}.bind(this,o,s,t)))}},r=function(){a.length?RSVP.all(a).then(e,e):e()};t=[];for(var c=0;c0?(l.ws_send("twitch_sets",t,function(e,n){if(t=[],e){for(var a in n)n.hasOwnProperty(a)&&(l._twitch_set_to_channel[a]=n[a],s(a,n[a]));localStorage.ffzTwitchSets=JSON.stringify(l._twitch_set_to_channel)}r()}),setTimeout(function(){t.length&&r()},2e3)):r()})]).then(function(){for(var t={},n=0;n0&&c.push([2,d.id,d])}c.sort(function(e,t){if(e[0]t[0])return 1;var n=e[1].toLowerCase(),a=t[1].toLowerCase();return"twitch turbo"===n||"twitch_tfaces"===n?n="zza|"+n:"global emoticons"===n&&(n="zzz|"+n),"twitch turbo"===a||"twitch_tfaces"===a?a="zza|"+a:"global emoticons"===a&&(a="zzz|"+a),a>n?-1:n>a?1:0});for(var h=0;h'+b+""+m,p&&(g.style.backgroundImage='url("'+p+'")'),v.className="emoticon-grid",v.appendChild(g);for(var k=0;k<_.length;k++){var w=_[k],F=s[w.code]||w.code,E=document.createElement("span");if(E.className="emoticon tooltip",E.style.backgroundImage='url("'+(w.url?w.url:o+w.id+"/1.0")+'")',w.height&&(E.style.height=w.height+"px"),w.width&&(E.style.width=w.width+"px"),!w.url){var z='image-set(url("'+o+w.id+'/1.0") 1x, url("'+o+w.id+'/2.0") 2x, url("'+o+w.id+'/3.0") 4x)';E.style.backgroundImage="-webkit-"+z,E.style.backgroundImage="-moz-"+z,E.style.backgroundImage="-ms-"+z,E.style.backgroundImage=z}E.title=F,E.addEventListener("click",l._add_emote.bind(l,e,F)),v.appendChild(E)}t.appendChild(v)}}if(!c.length){var v=document.createElement("div");v.className="chat-menu-content center",v.innerHTML="Error Loading Subscriptions",t.appendChild(v)}}catch(T){l.log("My Emotes Menu Error",T),t.innerHTML="";var v=document.createElement("div"),g=document.createElement("div"),C=document.createElement("p");g.className="heading",g.innerHTML="Error Loading Menu",v.appendChild(g),C.className="clearfix",C.textContent=T,v.appendChild(C),v.className="chat-menu-content",t.appendChild(v)}})}}},{"../constants":3}],24:[function(){var t=e.FrankerFaceZ;t.prototype.setup_notifications=function(){this.log("Adding event handler for window focus."),e.addEventListener("focus",this.clear_notifications.bind(this))},t.settings_info.highlight_notifications={type:"boolean",value:!1,category:"Chat",no_bttv:!0,name:"Highlight Notifications",help:"Display notifications when a highlighted word appears in chat in an unfocused tab.",on_update:function(e,t){if(e&&t){if("denied"===Notification.permission)return this.log("Notifications have been denied by the user."),void this.settings.set("highlight_notifications",!1);if("granted"!==Notification.permission){var n=this;Notification.requestPermission(function(e){"denied"===e&&(n.log("Notifications have been denied by the user."),n.settings.set("highlight_notifications",!1))})}}}},t.ws_commands.message=function(e){this.show_message(e)},t._notifications={},t._last_notification=0,t.prototype.clear_notifications=function(){for(var e in t._notifications){var n=t._notifications[e];if(n)try{n.close()}catch(a){}}t._notifications={},t._last_notification=0},t.prototype.show_notification=function(e,n,a,o,i,s){var r=Notification.permission;if("denied "===r)return!1;if("granted"===r){n=n||"FrankerFaceZ",o=o||1e4;var l={lang:"en-US",dir:"ltr",body:e,tag:a||"FrankerFaceZ",icon:"http://cdn.frankerfacez.com/icon32.png"},c=this,u=new Notification(n,l),d=t._last_notification++;return t._notifications[d]=u,u.addEventListener("click",function(){delete t._notifications[d],i&&i.bind(c)()}),u.addEventListener("close",function(){delete t._notifications[d],s&&s.bind(c)()}),void("number"==typeof o&&u.addEventListener("show",function(){setTimeout(function(){delete t._notifications[d],u.close()},o)}))}var c=this;Notification.requestPermission(function(){c.show_notification(e,n,a)})},t.prototype.show_message=function(t){e.noty({text:t,theme:"ffzTheme",layout:"bottomCenter",closeWith:["button"]}).show()}},{}],25:[function(t){var n=e.FrankerFaceZ,a=t("../utils");n.prototype.setup_races=function(){this.log("Initializing race support."),this.srl_races={}},n.settings_info.srl_races={type:"boolean",value:!0,category:"Channel Metadata",name:"SRL Race Information",help:'Display information about SpeedRunsLive races under channels.',on_update:function(){this.rebuild_race_ui()}},n.ws_on_close.push(function(){var t=e.App&&App.__container__.lookup("controller:channel"),n=t&&t.get("id"),a=!1;if(t){for(var o in this.srl_races)delete this.srl_races[o],o==n&&(a=!0);a&&this.rebuild_race_ui()}}),n.ws_commands.srl_race=function(e){for(var t=App.__container__.lookup("controller:channel"),n=t.get("id"),a=!1,o=0;o=300?"right":"left")+" share dropmenu",this._popup_kill=this._race_kill.bind(this),this._popup=e;var l="http://kadgar.net/live",c=!1;for(var u in s.entrants){var d=s.entrants[u].state;s.entrants.hasOwnProperty(u)&&s.entrants[u].channel&&("racing"==d||"entered"==d)&&(l+="/"+s.entrants[u].channel,c=!0)}var h=document.querySelector(".app-main.theatre")?document.body.clientHeight-300:t.parentElement.offsetTop-175,p=App.__container__.lookup("controller:channel"),m=p?p.get("display_name"):n.get_capitalization(i),_=encodeURIComponent("I'm watching "+m+" race "+s.goal+" in "+s.game+" on SpeedRunsLive!");r='
',r+='
Developers
Dan Salvato  
Stendec  
Version '+n.version_info+'Logs
',r+="
#Entrant Time
",r+='
',r+='',r+='

SRL',c&&(r+='   Multitwitch'),r+="

",e.innerHTML=r,t.appendChild(e),this._update_race(!0)}}},n.prototype._update_race=function(e){this._race_timer&&e&&(clearTimeout(this._race_timer),delete this._race_timer);var t=document.querySelector("#ffz-ui-race");if(t){var n=t.getAttribute("data-channel"),o=this.srl_races[n];if(!o)return t.parentElement.removeChild(t),this._popup_kill&&this._popup_kill(),void(this._popup&&(delete this._popup,delete this._popup_kill));var i=o.twitch_entrants[n],s=o.entrants[i],r=t.querySelector("#ffz-race-popup"),l=Date.now()/1e3,c=Math.floor(l-o.time);if(t.querySelector(".logo").innerHTML=a.placement(s),r){var u=r.querySelector("tbody"),d=r.querySelector(".heading span"),h=r.querySelector(".heading div");u.innerHTML="";var p=[],m=!0;for(var _ in o.entrants)o.entrants.hasOwnProperty(_)&&("racing"==o.entrants[_].state&&(m=!1),p.push(o.entrants[_]));p.sort(function(e,t){var n=e.place||9999,a=t.place||9999,o=e.time||c,i=t.time||c;return("forfeit"==e.state||"dq"==e.state)&&(n=1e4),("forfeit"==t.state||"dq"==t.state)&&(a=1e4),a>n?-1:n>a?1:e.namet.name?1:i>o?-1:o>i?1:void 0});for(var f=0;f'+_.display_name+"",v=_.channel?'':"",b=_.hitbox?'':"",y=c?a.time_to_string(_.time||c):"",w=a.place_string(_.place),k=_.comment?a.sanitize(_.comment):"";u.innerHTML+="'+w+""+g+""+v+b+''+("forfeit"==_.state?"Forfeit":y)+""}if(this._race_game!=o.game||this._race_goal!=o.goal){this._race_game=o.game,this._race_goal=o.goal;var F=a.sanitize(o.game),E=a.sanitize(o.goal);h.innerHTML='

'+F+"

Goal: "+E}c?m?d.innerHTML="Done":(d.innerHTML=a.time_to_string(c),this._race_timer=setTimeout(this._update_race.bind(this),1e3)):d.innerHTML="Entry Open"}}}},{"../utils":28}],26:[function(t){var n=e.FrankerFaceZ,a=t("../constants");n.prototype.setup_css=function(){this.log("Injecting main FrankerFaceZ CSS.");var e=this._main_style=document.createElement("link");e.id="ffz-ui-css",e.setAttribute("rel","stylesheet"),e.setAttribute("href",a.SERVER+"script/style.css?_="+Date.now()),document.head.appendChild(e),jQuery.noty.themes.ffzTheme={name:"ffzTheme",style:function(){this.$bar.removeClass().addClass("noty_bar").addClass("ffz-noty").addClass(this.options.type)},callback:{onShow:function(){},onClose:function(){}}}}},{"../constants":3}],27:[function(t){var n=e.FrankerFaceZ,a=t("../constants"),o=t("../utils");n.ws_commands.viewers=function(t){var n=t[0],i=t[1],s=e.App&&App.__container__.lookup("controller:channel"),r=this.is_dashboard?location.pathname.match(/\/([^\/]+)/):void 0,l=this.is_dashboard?r&&r[1]:s&&s.get&&s.get("id");if(l===n){var c=document.querySelector("#ffz-viewer-display"),u=a.ZREKNARF+" "+o.number_commas(i);if(c)c.innerHTML=u;else{var d=document.querySelector(this.is_dashboard?"#stats":".stats-and-actions .channel-stats");if(!d)return;c=document.createElement("span"),c.id="ffz-viewer-display",c.className="ffz stat",c.title="Chatters with FrankerFaceZ",c.innerHTML=u,d.appendChild(c),jQuery(c).tipsy(this.is_dashboard?{gravity:"s"}:void 0)}}}},{"../constants":3,"../utils":28}],28:[function(t,n){var a=(e.FrankerFaceZ,t("./constants"),{}),o=document.createElement("span"),i=function(e){return 1==e?"1st":2==e?"2nd":3==e?"3rd":null==e?"---":e+"th"},s=function(e,t){t=0===t?0:t||1,t=Math.round(255*-(t/100));var n=Math.max(0,Math.min(255,e[0]-t)),a=Math.max(0,Math.min(255,e[1]-t)),o=Math.max(0,Math.min(255,e[2]-t));return[n,a,o]},r=function(e){return"rgb("+e[0]+", "+e[1]+", "+e[2]+")"},l=function(e,t){return t=0===t?0:t||1,s(e,-t)},c=function(e){e=[e[0]/255,e[1]/255,e[2]/255];for(var t=0;ts;(l||n)&&(l&&(a=a.substr(0,s)+a.substr(r+i.length)),n&&(a+=o+n+i),e.innerHTML=a)},get_luminance:c,brighten:s,darken:l,rgb_to_css:r,parse_date:d,number_commas:function(e){var t=e.toString().split(".");return t[0]=t[0].replace(/\B(?=(\d{3})+(?!\d))/g,","),t.join(".")},place_string:i,placement:function(e){return"forfeit"==e.state?"Forfeit":"dq"==e.state?"DQed":e.place?i(e.place):""},sanitize:function(e){var t=a[e];return t||(o.textContent=e,t=a[e]=o.innerHTML,o.innerHTML=""),t},date_string:function(e){return e.getFullYear()+"-"+(e.getMonth()+1)+"-"+e.getDate()},time_to_string:function(e,t,n){var a=e%60,o=Math.floor(e/60),i=Math.floor(o/60),s="";if(o%=60,t){if(s=Math.floor(i/24),i%=24,n&&s>0)return s+" days";s=s>0?s+" days, ":""}return s+(10>i?"0":"")+i+":"+(10>o?"0":"")+o+":"+(10>a?"0":"")+a}}},{"./constants":3}]},{},[14]),e.ffz=new FrankerFaceZ}(window);