1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-28 15:27:43 +00:00
FrankerFaceZ/script.min.js
2015-02-24 02:48:29 -05:00

3 lines
No EOL
74 KiB
JavaScript

!function(e){!function t(e,n,o){function i(s,a){if(!n[s]){if(!e[s]){var l="function"==typeof require&&require;if(!a&&l)return l(s,!0);if(r)return r(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 i(n?n:t)},c,c.exports,t,e,n,o)}return n[s].exports}for(var r="function"==typeof require&&require,s=0;s<o.length;s++)i(o[s]);return i}({1:[function(t){var n=e.FrankerFaceZ,o=t("./constants"),i=t("./utils");n.prototype.setup_badges=function(){this.log("Preparing badge system."),this.badges={},this.log("Creating badge style element.");var e=this._badge_style=document.createElement("style");e.id="ffz-badge-css",document.head.appendChild(e),this.log("Adding legacy donor badges."),this._legacy_add_donors()};var r=function(e){return".badges .ffz-badge-"+e.id+" { background-color: "+e.color+'; background-image: url("'+e.image+'"); '+(e.extra_css||"")+"}"};n.prototype.bttv_badges=function(e){var t=e.sender,n=this.users[t],o=[],i=-1;if(n&&n.badges){for(var r=0;r<e.badges.length;r++){var s=e.badges[r];if("subscriber"==s.type||"turbo"==s.type){i=r;break}}for(var a in n.badges)if(n.badges.hasOwnProperty(a)){var s=n.badges[a],l=this.badges[s.id]||{},c=s.title||l.title,u="",d=BetterTTV.settings.get("alphaTags");s.image&&(u+='background-image: url(\\"'+s.image+'\\"); '),s.color&&!d&&(u+="background-color: "+s.color+"; "),s.extra_css&&(u+=s.extra_css),u&&(c+='" style="'+u),o.push([(-1==i?1:-1)*a,{type:"ffz-badge-"+s.id+(d?" alpha":""),name:"",description:c}])}if(o.sort(function(e,t){return e[0]-t[0]}),-1==i)for(;o.length;)e.badges.push(o.shift()[1]);else for(;o.length;)e.badges.insertAt(i,o.shift()[1])}},n.prototype.render_badge=function(e){var t=e.get("context.model.from"),n=e.get("context.parentController.content.id"),o=e.$(".badges"),i=this.users[t];if(i&&i.badges){var r=o.find(".badge").filter(function(){var e=this.title.toLowerCase();return"subscriber"==e||"turbo"==e}).first(),s=[],a=!!r.length;for(var l in i.badges)if(i.badges.hasOwnProperty(l)){var c=i.badges[l],u=this.badges[c.id]||{};if(void 0!==u.visible){var d=u.visible;if("function"==typeof d)try{d=d.bind(this)(n,t)}catch(h){}if(!d)continue}var p=document.createElement("div");p.className="badge float-left tooltip ffz-badge-"+c.id,p.setAttribute("title",c.title||u.title),c.image&&(p.style.backgroundImage='url("'+c.image+'")'),c.color&&(p.style.backgroundColor=c.color),c.extra_css&&(p.style.cssText+=c.extra_css),s.push([(a?1:-1)*l,p])}if(s.sort(function(e,t){return e[0]-t[0]}),a)for(;s.length;)r.before(s.shift()[1]);else for(;s.length;)o.append(s.shift()[1])}},n.known_bots=["quoteconut","quoconut","zenwan","nightbot","moobot","xanbot"],n.prototype._legacy_add_donors=function(e){this.badges[1]={id:1,title:"FFZ Donor",color:"#755000",image:"//cdn.frankerfacez.com/channel/global/donoricon.png"},i.update_css(this._badge_style,1,r(this.badges[1])),this.badges[0]={id:0,title:"FFZ Developer",color:"#FAAF19",image:"//cdn.frankerfacez.com/channel/global/devicon.png"},i.update_css(this._badge_style,0,r(this.badges[0])),this.users.sirstendec={badges:{0:{id:0}}},jQuery.ajax(o.SERVER+"script/donors.txt",{cache:!1,context:this}).done(function(e){this._legacy_parse_donors(e)}).fail(function(t){return 404!=t.status?(e=(e||0)+1,10>e?this._legacy_add_donors(e):void 0):void 0})},n.prototype._legacy_parse_donors=function(e){var t=0;if(null!=e)for(var n=e.trim().split(/\W+/),o=0;o<n.length;o++){var r=n[o],s=this.users[r]=this.users[r]||{},a=s.badges=s.badges||{};a[0]||(a[0]={id:1},t+=1)}this.log("Added donor badge to "+i.number_commas(t)+" users.")}},{"./constants":3,"./utils":27}],2:[function(){var t=e.FrankerFaceZ;t.ffz_commands.log=function(e){this._pastebin(this._log_data.join("\n"),function(t){return t?void this.room_message(e,"Your FrankerFaceZ log has been pasted to: "+t):this.room_message(e,"There was an error uploading the FrankerFaceZ log.")})},t.ffz_commands.massunmod=function(e,t){if(t=t.join(" ").trim(),!t.length)return"You must provide a list of users to unmod.";t=t.split(/\W*,\W*/);var n=this.get_user();if(!n||!n.login==e.id)return"You must be the broadcaster to use massunmod.";if(t.length>50)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 o=t.length;t.length;){var i=t.shift();e.room.tmiRoom.sendMessage("/unmod "+i)}return"Sent unmod command for "+o+" users."},t.ffz_commands.massunmod.help="Usage: /ffz massunmod <list, of, users>\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 o=t.length;t.length;){var i=t.shift();e.room.tmiRoom.sendMessage("/mod "+i)}return"Sent mod command for "+o+" users."},t.ffz_commands.massmod.help="Usage: /ffz massmod <list, of, users>\nBroadcaster only. Mod all the users in the provided list."},{}],3:[function(e,t){var n='<path d="m120.95 1.74c4.08-0.09 8.33-0.84 12.21 0.82 3.61 1.8 7 4.16 11.01 5.05 2.08 3.61 6.12 5.46 8.19 9.07 3.6 5.67 7.09 11.66 8.28 18.36 1.61 9.51 7.07 17.72 12.69 25.35 3.43 7.74 1.97 16.49 3.6 24.62 2.23 5.11 4.09 10.39 6.76 15.31 1.16 2 4.38 0.63 4.77-1.32 1.2-7.1-2.39-13.94-1.97-21.03 0.38-3.64-0.91-7.48 0.25-10.99 2.74-3.74 4.57-8.05 7.47-11.67 3.55-5.47 10.31-8.34 16.73-7.64 2.26 2.89 5.13 5.21 7.58 7.92 2.88 4.3 6.52 8.01 9.83 11.97 1.89 2.61 3.06 5.64 4.48 8.52 2.81 4.9 4 10.5 6.63 15.49 2.16 6.04 5.56 11.92 5.37 18.5 0.65 1.95 0.78 4 0.98 6.03 1.01 3.95 2.84 8.55 0.63 12.42-2.4 5.23-7.03 8.97-11.55 12.33-6.06 4.66-11.62 10.05-18.37 13.75-4.06 2.65-8.24 5.17-12.71 7.08-3.59 1.57-6.06 4.94-9.85 6.09-2.29 1.71-3.98 4.51-6.97 5.02-4.56 1.35-8.98-3.72-13.5-1.25-2.99 1.83-6.19 3.21-9.39 4.6-8.5 5.61-18.13 9.48-28.06 11.62-8.36-0.2-16.69 0.62-25.05 0.47-3.5-1.87-7.67-1.08-11.22-2.83-6.19-1.52-10.93-6.01-16.62-8.61-2.87-1.39-5.53-3.16-8.11-4.99-2.58-1.88-4.17-4.85-6.98-6.44-3.83-0.11-6.54 3.42-10.24 3.92-2.31 0.28-4.64 0.32-6.96 0.31-3.5-3.65-5.69-8.74-10.59-10.77-5.01-3.68-10.57-6.67-14.84-11.25-2.52-2.55-5.22-4.87-8.24-6.8-4.73-4.07-7.93-9.51-11.41-14.62-3.08-4.41-5.22-9.73-4.6-15.19 0.65-8.01 0.62-16.18 2.55-24.02 4.06-10.46 11.15-19.34 18.05-28.06 3.71-5.31 9.91-10.21 16.8-8.39 3.25 1.61 5.74 4.56 7.14 7.89 1.19 2.7 3.49 4.93 3.87 7.96 0.97 5.85 1.6 11.86 0.74 17.77-1.7 6.12-2.98 12.53-2.32 18.9 0.01 2.92 2.9 5.36 5.78 4.57 3.06-0.68 3.99-4.07 5.32-6.48 1.67-4.06 4.18-7.66 6.69-11.23 3.61-5.28 5.09-11.57 7.63-17.37 2.07-4.56 1.7-9.64 2.56-14.46 0.78-7.65-0.62-15.44 0.7-23.04 1.32-3.78 1.79-7.89 3.8-11.4 3.01-3.66 6.78-6.63 9.85-10.26 1.72-2.12 4.21-3.32 6.55-4.6 7.89-2.71 15.56-6.75 24.06-7z"/>',o="true"==localStorage.ffzDebugMode&&document.body.classList.contains("ffz-dev");t.exports={DEBUG:o,SERVER:o?"//localhost:8000/":"//cdn.frankerfacez.com/",SVGPATH:n,ZREKNARF:'<svg style="padding:1.75px 0" class="svg-glyph_views" width="16px" viewBox="0 0 249 195" version="1.1" height="12.5px">'+n+"</svg>",CHAT_BUTTON:'<svg class="svg-emoticons ffz-svg" height="18px" width="24px" viewBox="0 0 249 195" version="1.1">'+n+"</svg>",GEAR:'<svg class="svg-gear" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M15,7v2h-2.115c-0.125,0.615-0.354,1.215-0.713,1.758l1.484,1.484l-1.414,1.414l-1.484-1.484C10.215,12.531,9.615,12.76,9,12.885V15H7v-2.12c-0.614-0.126-1.21-0.356-1.751-0.714l-1.491,1.49l-1.414-1.414l1.491-1.49C3.477,10.211,3.247,9.613,3.12,9H1V7h2.116C3.24,6.384,3.469,5.785,3.829,5.242L2.343,3.757l1.414-1.414l1.485,1.485C5.785,3.469,6.384,3.24,7,3.115V1h2v2.12c0.613,0.126,1.211,0.356,1.752,0.714l1.49-1.491l1.414,1.414l-1.49,1.492C12.523,5.79,12.754,6.387,12.88,7H15z M8,6C6.896,6,6,6.896,6,8s0.896,2,2,2s2-0.896,2-2S9.104,6,8,6z" fill-rule="evenodd"></path></svg>',HEART:'<svg class="svg-heart" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M8,13.5L1.5,7V4l2-2h3L8,3.5L9.5,2h3l2,2v3L8,13.5z" fill-rule="evenodd"></path></svg>',EMOTE:'<svg class="svg-emote" height="16px" version="1.1" viewBox="0 0 18 18" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M9,18c-4.971,0-9-4.029-9-9s4.029-9,9-9s9,4.029,9,9S13.971,18,9,18z M14,4.111V4h-0.111C12.627,2.766,10.904,2,9,2C7.095,2,5.373,2.766,4.111,4H4v0.111C2.766,5.373,2,7.096,2,9s0.766,3.627,2,4.889V14l0.05-0.051C5.317,15.217,7.067,16,9,16c1.934,0,3.684-0.783,4.949-2.051L14,14v-0.111c1.234-1.262,2-2.984,2-4.889S15.234,5.373,14,4.111zM11,6h2v4h-2V6z M12.535,12.535C11.631,13.44,10.381,14,9,14s-2.631-0.56-3.536-1.465l0.707-0.707C6.896,12.553,7.896,13,9,13s2.104-0.447,2.828-1.172L12.535,12.535z M5,6h2v4H5V6z" fill-rule="evenodd"></path></svg>'}},{}],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 <on|off>\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(){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 o=Ember.View.views[n];if(o instanceof e){this.log("Adding UI link manually to Chat view.",o);try{o.$(".textarea-contain").append(this.build_ui_link(o))}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)}})})}},{}],6:[function(t){var n=e.FrankerFaceZ,o=t("../utils"),i=function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},r="[\\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(r+"*,"+r+"*"),a=function(e){return(e+"").replace(/&/g,"&amp;").replace(/'/g,"&apos;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")},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="<tr><td>Emoticon</td><td>"+e.code+"</td></tr>",n=e.set,o=e.set_type;return void 0===o&&(o="Channel"),n?(("00000turbo"==n||"turbo"==n)&&(n="Twitch Turbo",o=null),t+=o?"<tr><td>"+o+"</td><td>"+n+"</td></tr>":'<tr><td class="center" colspan="2">'+n+"</td></tr>",'<table class="emote-data">'+t+"</table>"):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,o){if(n){t&&(o.code=t),this._twitch_emotes[e]=o;for(var i=d.bind(this)(e),r=document.querySelectorAll('img[emote-id="'+e+'"]'),s=0;s<r.length;s++)r[s].title=i}};n.settings_info.capitalize={type:"boolean",value:!0,category:"Chat",visible:function(){return!this.has_bttv},name:"Username Capitalization",help:"Display names in chat with proper capitalization."},n.settings_info.banned_words={type:"button",value:[],category:"Chat",visible:function(){return!this.has_bttv},name:"Banned Words",help:"Set a list of words that will be locally removed from chat messages.",method:function(){var e=this.settings.banned_words.join(", "),t=prompt("Banned Words\n\nPlease enter a comma-separated list of words that you would like to be removed from chat messages.",e);if(null!==t&&void 0!==t){t=t.trim().split(s);for(var n=[],o=0;o<t.length;o++)t[o]&&n.push(t[o]);1==n.length&&"disable"==n[0]&&(n=[]),this.settings.set("banned_words",n)}}},n.settings_info.keywords={type:"button",value:[],category:"Chat",visible:function(){return!this.has_bttv},name:"Highlight Keywords",help:"Set additional keywords that will be highlighted in chat.",method:function(){var e=this.settings.keywords.join(", "),t=prompt("Highlight Keywords\n\nPlease enter a comma-separated list of words that you would like to be highlighted in chat.",e);if(null!==t&&void 0!==t){t=t.trim().split(s);for(var n=[],o=0;o<t.length;o++)t[o]&&n.push(t[o]);1==n.length&&"disable"==n[0]&&(n=[]),this.settings.set("keywords",n)}}},n.settings_info.fix_color={type:"boolean",value:!1,category:"Chat",visible:function(){return!this.has_bttv},name:"Adjust Username Colors",help:"Ensure that username colors contrast with the background enough to be readable.",on_update:function(e){this.has_bttv||document.body.classList.toggle("ffz-chat-colors",e)}},n.settings_info.chat_rows={type:"boolean",value:!1,category:"Chat",visible:function(){return!this.has_bttv},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.log("Hooking the Ember Line controller.");var o=App.__container__.resolve("controller:line"),i=this;o.reopen({tokenizedMessage:function(){var e=this._super();try{e=i._remove_banned(e),e=i._emoticonize(this,e);var t=i.get_user();t&&this.get("model.from")==t.login||(e=i._mentionize(this,e))}catch(n){try{i.error("LineController tokenizedMessage: "+n)}catch(n){}}return e}.property("model.message","isModeratorOrHigher")}),this.log("Hooking the Ember Line view.");var o=App.__container__.resolve("view:line");o.reopen({didInsertElement:function(){this._super();try{var t=this.get("element"),o=this.get("context"),r=o.get("model.from"),s=o.get("parentController.content.id"),a=o.get("model.color"),l=o.get("model.ffz_alternate");a&&i._handle_color(a),void 0===l&&(l=i._last_row[s]=i._last_row.hasOwnProperty(s)?!i._last_row[s]:!1,this.set("context.model.ffz_alternate",l)),t.classList.toggle("ffz-alternate",l),t.setAttribute("data-room",s),t.setAttribute("data-sender",r),i.render_badge(this),i.settings.capitalize&&i.capitalize(this,r);var d=t.querySelector("span.mentioned");if(d&&(t.classList.add("ffz-mentioned"),!document.hasFocus()&&!this.get("context.model.ffz_notified")&&i.settings.highlight_notifications)){var p=n.get_capitalization(s),m=n.get_capitalization(r),_=p,f=this.get("context.model.message");this.get("context.parentController.content.isGroupRoom")&&(_=this.get("context.parentController.content.tmiRoom.displayName")),f="action"==this.get("context.model.style")?"* "+m+" "+f:m+": "+f,i.show_notification(f,"Twitch Chat Mention in "+_,p,6e4,e.focus.bind(e))}this.set("context.model.ffz_notified",!0);for(var g=t.querySelectorAll("a.deleted-link"),v=0;v<g.length;v++){var b=g[v];b.addEventListener("click",function(e){if(!this.classList.contains("deleted-link"))return!0;var t=this.getAttribute("data-url"),n=t;this.classList.remove("deleted-link"),this.removeAttribute("data-url"),this.removeAttribute("title"),this.removeAttribute("original-title"),t.indexOf("@")>-1&&(-1===t.indexOf("/")||t.indexOf("@")<t.indexOf("/"))?t="mailto:"+t:t.match(/^https?:\/\//)||(t="http://"+t),this.href=t,this.target="_new",this.textContent=n,e.preventDefault()}),jQuery(b).tipsy()}for(var y=t.querySelectorAll("img"),v=0;v<y.length;v++){var w=y[v],k=(w.alt,/\/emoticons\/v1\/(\d+)\/1\.0/.exec(w.src)),F=k?parseInt(k[1]):null;if(null!==F){w.setAttribute("srcset",c(F)),w.setAttribute("emote-id",F);var E=i._twitch_emotes[F];E?"string"!=typeof E&&(w.title=E.tooltip):(i._twitch_emotes[F]=w.alt,i.ws_send("twitch_emote",F,h.bind(i,F,w.alt))),jQuery(w).tipsy({html:!0})}else if(w.getAttribute("data-ffz-emote")){var z=JSON.parse(decodeURIComponent(w.getAttribute("data-ffz-emote"))),F=z&&z[0]||null,C=z&&z[1]||null,x=i.emote_sets[C],T=x?x.emotes[F]:null,A=x.id,L="FFZ Channel";"global"==x.id?(A="FrankerFaceZ Global",L=null):"globalevent"==x.id?(A="FrankerFaceZ Event",L=null):i.feature_friday&&x.id==i.feature_friday.set&&(A="Feature Friday - "+i.feature_friday.channel),w.title=u({code:T.hidden?"???":T.name,set:A,set_type:L}),jQuery(w).tipsy({html:!0})}else jQuery(w).tipsy()}}catch(S){try{i.error("LineView didInsertElement: "+S)}catch(S){}}}});var r=this.get_user();r&&r.name&&(n.capitalization[r.login]=[r.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],i=o.get_luminance(n),r="",s='span[style="color:'+e+'"]',a=!1;if(i>.3){a=!0;for(var l=255,c=n;l--&&(c=o.darken(c),!(o.get_luminance(c)<=.3)););r+=".ffz-chat-colors .ember-chat-container:not(.dark) .chat-line "+s+", .ffz-chat-colors .chat-container:not(.dark) .chat-line "+s+" { color: "+o.rgb_to_css(c)+" !important; }\n"}else r+=".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(.1>i){a=!0;for(var l=255,c=n;l--&&(c=o.brighten(c),!(o.get_luminance(c)>=.1)););r+=".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: "+o.rgb_to_css(c)+" !important; }\n"}else r+=".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";a&&(this._fix_color_style.innerHTML+=r)}},n.capitalization={},n._cap_fetching=0,n.get_capitalization=function(t,o){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 i=n.capitalization[t];return i&&Date.now()-i[1]<36e5?i[0]:(n._cap_fetching<25&&(n._cap_fetching++,n.get().ws_send("get_display_name",t,function(e,i){var r=e?i:t;n.capitalization[t]=[r,Date.now()],n._cap_fetching--,"function"==typeof o&&o(r)})),i?i[0]:t)},n.prototype.capitalize=function(e,t){var o=n.get_capitalization(t,this.capitalize.bind(this,e));o&&e&&e.$(".from").text(o)},n._regex_cache={},n._get_regex=function(e){return n._regex_cache[e]=n._regex_cache[e]||RegExp("\\b"+i(e)+"\\b","ig")},n._words_to_regex=function(e){var t=n._regex_cache[e];if(!t){for(var o="",s=0;s<e.length;s++)e[s]&&(o+=(o?"|":"")+i(e[s]));t=n._regex_cache[e]=new RegExp("(^|.*?"+r+")("+o+")(?=$|"+r+")","ig")}return t},n.prototype._mentionize=function(e,t){var o=this.settings.keywords;if(!o||!o.length)return t;"string"==typeof t&&(t=[t]);for(var i=n._words_to_regex(o),r=[],s=0;s<t.length;s++){var a=t[s];_.isString(a)&&a.match(i)?(a=a.replace(i,function(e,t,n){return r.push(t),r.push({mentionedUser:n,own:!1}),""}),a&&r.push(a)):r.push(a)}return r},n.prototype._remove_banned=function(e){var t=this.settings.banned_words;if(!t||!t.length)return e;"string"==typeof e&&(e=[e]);for(var o=n._words_to_regex(t),i=[],r=0;r<e.length;r++){var s=e[r];i.push(_.isString(s)?s.replace(o,"$1***"):s.emoticonSrc&&o.test(s.altText)?s.altText.replace(o,"$1***"):s.isLink&&o.test(s.href)?{mentionedUser:'</span><a class="deleted-link" title="'+a(s.href.replace(o,"$1***"))+'" data-url="'+a(s.href)+'" href="#">&lt;banned link&gt;</a><span class="mentioning">',own:!0}:s)}return i},n.prototype._emoticonize=function(e,t){var n=e.get("parentController.model.id"),o=e.get("model.from"),i=this,r=this.getEmotes(o,n),s=[];return _.each(r,function(e){var n=i.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,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 o=t.split(e.regex),i=[];return o.forEach(function(e,t){i.push(e),t!==o.length-1&&i.push(n)}),i})))}),t):t}},{"../utils":27}],7:[function(t){var n=e.FrankerFaceZ,o=t("../utils"),i={ESC:27,P:80,B:66,T:84},r=[["5m",300],["10m",600],["1hr",3600],["12hr",43200],["24hr",86400]],s='<svg class="svg-messages" height="16px" version="1.1" viewBox="0 0 18 18" width="16px" x="0px" y="0px"><path clip-rule="evenodd" d="M1,15V3h16v12H1z M15.354,5.354l-0.707-0.707L9,10.293L3.354,4.646L2.646,5.354L6.293,9l-3.646,3.646l0.707,0.707L7,9.707l1.646,1.646h0.707L11,9.707l3.646,3.646l0.707-0.707L11.707,9L15.354,5.354z" fill-rule="evenodd"></path></svg>',a='<svg class="svg-unban" height="16px" version="1.1" viewBox="0 0 16 16" width="16px" x="0px" y="0px"><path fill-rule="evenodd" clip-rule="evenodd" fill="#888888" d="M6.5,12.75L2,8.25l2-2l2.5,2.5l5.5-5.5l2,2L6.5,12.75z"/></svg>';n.settings_info.enhanced_moderation={type:"boolean",value:!1,visible:function(){return!this.has_bttv},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 e=App.__container__.resolve("view:moderation-card"),t=this;e.reopen({didInsertElement:function(){this._super();try{if(t.has_bttv||!t.settings.enhanced_moderation)return;var e=this.get("element"),n=this.get("context");if(e.classList.add("ffz-moderation-card"),n.get("parentController.model.isModeratorOrHigher")){e.classList.add("ffz-is-mod"),e.setAttribute("tabindex",1),e.addEventListener("keyup",function(e){var t=e.keyCode||e.which,o=n.get("model.user.id"),r=n.get("parentController.model");if(t==i.P)r.send("/timeout "+o+" 1");else if(t==i.B)r.send("/ban "+o);else if(t==i.T)r.send("/timeout "+o+" 600");else if(t!=i.ESC)return;n.send("hideModOverlay")});var l=document.createElement("div");l.className="interface clearfix";var c=function(e){var t=n.get("model.user.id"),o=n.get("parentController.model");o.send(-1===e?"/unban "+t:"/timeout "+t+" "+e)},u=function(e,t){var n=document.createElement("button");return n.className="button",n.innerHTML=e,n.title="Timeout User for "+o.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",c.bind(this,t)),n};l.appendChild(u("Purge",1));var d=document.createElement("span");d.className="right",l.appendChild(d);for(var h=0;h<r.length;h++)d.appendChild(u(r[h][0],r[h][1]));e.appendChild(l);var p=document.createElement("button");p.className="unban button glyph-only light",p.innerHTML=a,p.title="(U)nban User",jQuery(p).tipsy(),p.addEventListener("click",c.bind(this,-1));var m=e.querySelector("button.ban");m.setAttribute("title","(B)an User"),jQuery(m).after(p),this.$("button.timeout").remove()}var _=e.querySelector("button.mod");if(_){var f=n.get("parentController.model"),g=f.get("isBroadcaster")||f.get("isStaff")||f.get("isAdmin");g||_.parentElement.removeChild(_)}var v=e.querySelector(".interface > button");v&&"button"==v.className&&(v.innerHTML=s,v.classList.add("glyph-only"),v.classList.add("message"),v.title="Message User",jQuery(v).tipsy()),this.$().draggable({start:function(){e.focus()}}),e.focus()}catch(b){try{t.error("ModerationCardView didInsertElement: "+b)}catch(b){}}}})},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;n<t.length;n++){var o=t[n];o&&e.room.send("/timeout "+o+" 1")}},n.chat_commands.p.enabled=function(){return this.settings.enhanced_moderation},n.chat_commands.t=function(e,t){return t&&t.length?void e.room.send("/timeout "+t.join(" ")):"Timeout Usage: /t username [duration]"},n.chat_commands.t.enabled=function(){return this.settings.enhanced_moderation},n.chat_commands.b=function(e,t){if(!t||!t.length)return"Ban Usage: /b username [more usernames separated by spaces]";if(t.length>10)return"Please only ban up to 10 users at once.";for(var n=0;n<t.length;n++){var o=t[n];o&&e.room.send("/ban "+o)}},n.chat_commands.b.enabled=function(){return this.settings.enhanced_moderation},n.chat_commands.u=function(e,t){if(!t||!t.length)return"Unban Usage: /u username [more usernames separated by spaces]";if(t.length>10)return"Please only unban up to 10 users at once.";for(var n=0;n<t.length;n++){var o=t[n];o&&e.room.send("/unban "+o)}},n.chat_commands.u.enabled=function(){return this.settings.enhanced_moderation}},{"../utils":27}],8:[function(t){var n=e.FrankerFaceZ,o=/\.([\w\-_]+)\s*?\{content:\s*?"([^"]+)";\s*?background-image:\s*?url\("([^"]+)"\);\s*?height:\s*?(\d+)px;\s*?width:\s*?(\d+)px;\s*?margin:([^;}]+);?([^}]*)\}/gm,i=/[^\n}]*\.badges\s+\.moderator\s*{\s*background-image:\s*url\(\s*['"]([^'"]+)['"][^}]+(?:}|$)/,r=/^_([^_]+)_\d+$/,s=t("../constants"),a=t("../utils"),l=function(e){return e.moderator_badge?'.chat-line[data-room="'+e.id+'"] .badges .moderator { background-image:url("'+e.moderator_badge+'") !important; }':""};n.prototype.setup_room=function(){this.rooms={},this.log("Creating room style element.");var e=this._room_style=document.createElement("style");e.id="ffz-room-css",document.head.appendChild(e),this.log("Hooking the Ember Room model.");var t=App.__container__.resolve("model:room");this._modify_room(t);var n=t.instances;for(var o in n)if(n.hasOwnProperty(o)){var i=n[o];this.add_room(i.id,i),this._modify_room(i)}},n.chat_commands={},n.ffz_commands={},n.prototype.room_message=function(e,t){var n=t.split("\n");if(this.has_bttv)for(var o=0;o<n.length;o++)BetterTTV.chat.handlers.onPrivmsg(e.id,{style:"admin",date:new Date,from:"jtv",message:n[o]});else for(var o=0;o<n.length;o++)e.room.addMessage({style:"ffz admin",date:new Date,from:"FFZ",message:n[o]})},n.prototype.run_command=function(e,t){var o=this.rooms[t];if(!o||!o.room)return!1;if(e){var i,r=e.split(" "),s=r.shift().substr(1).toLowerCase(),a=n.chat_commands[s];if(!a)return!1;if(a.hasOwnProperty("enabled")){var l=a.enabled;if("function"==typeof l)try{l=a.enabled.bind(this)(o,r)}catch(c){this.error('command "'+s+'" enabled: '+c),l=!1}if(!l)return!1}this.log("Received Command: "+s,r,!0);try{i=a.bind(this)(o,r)}catch(c){this.error('command "'+s+'" runner: '+c),i="There was an error running the command."}return i&&this.room_message(o,i),!0}},n.prototype.run_ffz_command=function(e,t){var o=this.rooms[t];if(o&&o.room){if(!e){var i=document.querySelector("a.ffz-ui-toggle");if(i)return i.click();e="help"}var r=e.split(" "),s=r.shift().toLowerCase();this.log("Received Command: "+s,r,!0);var a,l=n.ffz_commands[s];if(l)try{a=l.bind(this)(o,r)}catch(c){this.log("Error Running Command - "+s+": "+c,o),a="There was an error running the command."}else a='There is no "'+s+'" command.';a&&this.room_message(o,a)}},n.ffz_commands.help=function(e,t){if(t&&t.length){var o=n.ffz_commands[t[0].toLowerCase()];return o?o.help?o.help:'No help is available for the command "'+t[0]+'".':'There is no "'+t[0]+'" command.'}var i=[];for(var r in n.ffz_commands)n.ffz_commands.hasOwnProperty(r)&&i.push(r);return"The available commands are: "+i.join(", ")},n.ffz_commands.help.help="Usage: /ffz help [command]\nList available commands, or show help for a specific command.",n.prototype.add_room=function(e,t){return this.rooms[e]?this.log("Tried to add existing room: "+e):(this.log("Adding Room: "+e),this.rooms[e]={id:e,room:t,menu_sets:[],sets:[],css:null},this.ws_send("sub",e),void this._legacy_add_room(e))},n.prototype.remove_room=function(e){var t=this.rooms[e];if(t){this.log("Removing Room: "+e),(t.css||t.moderator_badge)&&a.update_css(this._room_style,e,null),this.ws_send("unsub",e),delete this.rooms[e];for(var n=0;n<t.sets.length;n++){var o=t.sets[n],i=this.emote_sets[o];i&&(i.users.removeObject(e),i.global||i.users.length||this.unload_set(o))}}},n.prototype.load_room=function(e,t){return this._legacy_load_room(e,t)},n.prototype._load_room_json=function(e,t,n){this.rooms[e]&&(n.room=this.rooms[e].room),this.rooms[e]=n,(n.css||n.moderator_badge)&&a.update_css(this._room_style,e,l(n)+(n.css||""));for(var o=0;o<n.sets.length;o++){var i=n.sets[o];this.emote_sets.hasOwnProperty(i)||this.load_set(i)}this.update_ui_link(),t&&t(!0,n)},n.prototype._modify_room=function(e){var t=this;e.reopen({init:function(){this._super();try{t.add_room(this.id,this)}catch(e){t.error("add_room: "+e)}},willDestroy:function(){this._super();try{t.remove_room(this.id)}catch(e){t.error("remove_room: "+e)}},getSuggestions:function(){var e=this._super();try{t.settings.capitalize&&(e=_.map(e,n.get_capitalization))}catch(o){t.error("get_suggestions: "+o)}return e},send:function(e){try{var n=e.split(" ",1)[0].toLowerCase();if("/ffz"===n)return this.set("messageToSend",""),void t.run_ffz_command(e.substr(5),this.get("id"));if("/"===n.charAt(0)&&t.run_command(e,this.get("id")))return void this.set("messageToSend","")}catch(o){t.error("send: "+o)}return this._super(e)}})},n.prototype._legacy_add_room=function(e,t,n){jQuery.ajax(s.SERVER+"channel/"+e+".css",{cache:!1,context:this}).done(function(n){this._legacy_load_room_css(e,t,n)
}).fail(function(o){return 404==o.status?this._legacy_load_room_css(e,t,null):(n=n||0,n++,10>n?this._legacy_add_room(e,t,n):void 0)})},n.prototype._legacy_load_room_css=function(e,t,n){var s=e,a=s.match(r);a&&a[1]&&(s=a[1]);var l={id:e,menu_sets:[s],sets:[s],moderator_badge:null,css:null};return n&&(n=n.replace(o,"").trim()),n&&(n=n.replace(i,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":27}],9:[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 o=[],i={},r=null,s=App.__container__.lookup("controller:channel"),a=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()])}a!=l&&(l=null);for(var u=0;u<e.length;u++){var d=e[u];if(d.category)r=d.category,o.push(r),i[r]=[];else{var h=d.chatter.toLowerCase();if(!h)continue;h==l?(o.unshift("Broadcaster"),i.Broadcaster=[h]):i.hasOwnProperty(r)&&i[r].push(h)}}e=[];for(var u=0;u<o.length;u++){var p=o[u],m=i[p];if(m&&m.length)for(e.push({category:p}),e.push({chatter:""}),m.sort();m.length;){var h=m.shift();h=t.get_capitalization(h),e.push({chatter:h})}}}catch(_){n.error("ViewersController lines: "+_)}return e}.property("content.chatters")})}},{}],10:[function(t){var n=e.FrankerFaceZ,o=/\.([\w\-_]+)\s*?\{content:\s*?"([^"]+)";\s*?background-image:\s*?url\("([^"]+)"\);\s*?height:\s*?(\d+)px;\s*?width:\s*?(\d+)px;\s*?margin:([^;}]+);?([^}]*)\}/gm,i=/[^\n}]*\.badges\s+\.moderator\s*{\s*background-image:\s*url\(\s*['"]([^'"]+)['"][^}]+(?:}|$)/,r=t("./constants"),s=t("./utils"),a=function(e,t,n){t&&(n.global=!0,this.global_sets.push(e))},l=function(e,t){var n=e.split(/ +/);return 2!=n.length?e:(n[0]=parseFloat(n[0]),n[1]=parseFloat(n[1]),n[0]==(t-18)/-2&&0==n[1]?null:e)},c=function(e){var t=e.margins;return t||(t=(e.height-18)/-2+"px 0"),".ffz-emote-"+e.id+' { background-image: url("'+e.url+'"); height: '+e.height+"px; width: "+e.width+"px; margin: "+t+(e.extra_css?"; "+e.extra_css:"")+"}\n"},u=function(e){return e.margins||e.extra_css?c(e)+'img[src="'+e.url+'"] { '+(e.margins?"margin: "+e.margins+";":"")+(e.extra_css||"")+" }\n":c(e)},d=u;n.prototype.setup_emoticons=function(){this.log("Preparing emoticon system."),this.emote_sets={},this.global_sets=[],this._last_emote_id=0,this.log("Creating emoticon style element.");var e=this._emote_style=document.createElement("style");e.id="ffz-emoticon-css",document.head.appendChild(e),this.log("Loading global emote set."),this.load_set("global",a.bind(this,"global"))},n.prototype.getEmotes=function(e,t){var n=this.users[e],o=this.rooms[t];return _.union(n&&n.sets||[],o&&o.sets||[],this.global_sets)},n.ws_commands.reload_set=function(e){this.load_set(e)},n.prototype.load_set=function(e,t){return this._legacy_load_set(e,t)},n.prototype.unload_set=function(e){var t=this.emote_sets[e];if(t){this.log("Unloading emoticons for set: "+e),s.update_css(this._emote_style,e,null),delete this.emote_sets[e];for(var n=0;n<t.users.length;n++){var o=this.rooms[t.users[n]];o&&o.sets.removeObject(e)}}},n.prototype._load_set_json=function(e,t,n){this.emote_sets[e]=n,n.users=[],n.global=!1,n.count=0;var o="";for(var i in n.emotes)if(n.emotes.hasOwnProperty(i)){var r=n.emotes[i];r.klass="ffz-emote-"+r.id,r.regex="!"===r.name[r.name.length-1]?new RegExp("\\b"+r.name+"(?=\\W|$)","g"):new RegExp("\\b"+r.name+"\\b","g"),o+=d(r),n.count++}s.update_css(this._emote_style,e,o+(n.extra_css||"")),this.log("Updated emoticons for set: "+e,n),this.update_ui_link(),t&&t(!0,n)},n.prototype._legacy_load_set=function(e,t,n){jQuery.ajax(r.SERVER+"channel/"+e+".css",{cache:!1,context:this}).done(function(n){this._legacy_load_css(e,t,n)}).fail(function(o){return 404==o.status?"function"==typeof t&&t(!1):(n=n||0,n++,10>n?this._legacy_load_set(e,t,n):"function"==typeof t&&t(!1))})},n.prototype._legacy_load_css=function(e,t,n){var r={},s={id:e,emotes:r,extra_css:null},a=this;n=n.replace(o,function(t,n,o,i,s,c,u,d){s=parseInt(s),c=parseInt(c),u=l(u,s);var h="."===i.substr(i.lastIndexOf("/")+1,1),p=++a._last_emote_id,m={id:p,set_id:e,hidden:h,name:o,height:s,width:c,url:i,margins:u,extra_css:d};return r[p]=m,""}).trim(),n&&n.replace(i,function(e,t){s.icon||"modicon.png"!==t.substr(-11)||(s.icon=t)}),this._load_set_json(e,t,s)}},{"./constants":3,"./utils":27}],11:[function(){var t=e.FrankerFaceZ,n=/(\sdata-sender="[^"]*"(?=>))/;t.bttv_known_bots=["nightbot","moobot","sourbot","xanbot","manabot","mtgbot","ackbot","baconrobot","tardisbot","deejbot","valuebot","stahpbot"],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,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,o=this;BetterTTV.chat.helpers.sendMessage=function(e){var n=e.split(" ",1)[0].toLowerCase();return"/ffz"!==n?t(e):void o.run_ffz_command(e.substr(5),BetterTTV.chat.store.currentRoom)};var i,r=BetterTTV.chat.handlers.privmsg;BetterTTV.chat.handlers.privmsg=function(e,t){i=e;var n=r(e,t);return i=null,n};var s=BetterTTV.chat.templates.privmsg;BetterTTV.chat.templates.privmsg=function(e,t,r,a,l){o.bttv_badges(l);var c=s(e,t,r,a,l);return c.replace(n,'$1 data-room="'+i+'"')};var a,l=BetterTTV.chat.templates.message;BetterTTV.chat.templates.message=function(e,t,n,o){a=e;var i=l(e,t,n,o);return a=null,i};var c=BetterTTV.chat.templates.emoticonize;BetterTTV.chat.templates.emoticonize=function(e,t){var n=c(e,t),r=o.getEmotes(a,i),t=[];return _.each(r,function(e){var i=o.emote_sets[e];i&&_.each(i.emotes,function(e){_.any(n,function(t){return _.isString(t)&&t.match(e.regex)})&&t.push(e)})}),t.length?(_.each(t,function(e){var t=['<img class="emoticon" src="'+e.url+(e.hidden?"":'" alt="'+e.name+'" title="'+e.name)+'" />'],o=n;if(n=[],!o||!o.length)return n;for(var i=0;i<o.length;i++){var r=o[i];if("string"==typeof r){var s=r.split(e.regex);s.forEach(function(e,o){e&&e.length&&n.push(e),o!==s.length-1&&n.push(t)})}else n.push(r)}}),n):n},this.update_ui_link()}},{}],12:[function(){var t=e.FrankerFaceZ;t.prototype.find_emote_menu=function(t,n){return this.has_emote_menu=!1,e.emoteMenu&&emoteMenu.registerEmoteGetter?this.setup_emote_menu(n||0):void(n>=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,o=App.__container__.lookup("controller:chat"),i=o?o.get("currentRoom.id"):null,r=this.getEmotes(n,i),s=[],a=0;a<r.length;a++){var l=this.emote_sets[r[a]];if(l&&l.emotes)for(var c in l.emotes)if(l.emotes.hasOwnProperty(c)){var u=l.emotes[c];if(!u.hidden){var d=l.title,h=l.icon||null;d||(d="global"==l.id?"FrankerFaceZ Global Emotes":"globalevent"==l.id?"FrankerFaceZ Event Emotes":this.feature_friday&&l.id==this.feature_friday.set?"FrankerFaceZ Feature Friday: "+this.feature_friday.channel:"FrankerFaceZ Set: "+t.get_capitalization(l.id)),s.push({text:u.name,url:u.url,hidden:!1,channel:d,badge:h})}}}return s}},{}],13:[function(t){t("./shims");var n=e.FrankerFaceZ=function(){n.instance=this,this._log_data=[],this.initialize()};n.get=function(){return n.instance};var o=n.version_info={major:3,minor:2,revision:1,toString:function(){return[o.major,o.minor,o.revision].join(".")+(o.extra||"")}};n.prototype.log=function(e,t,n){e="FFZ: "+e+(n?" -- "+JSON.stringify(t):""),this._log_data.push(e),void 0!==t&&console.groupCollapsed&&console.dir?(console.groupCollapsed(e),-1!==navigator.userAgent.indexOf("Firefox/")?console.log(t):console.dir(t),console.groupEnd(e)):console.log(e)},n.prototype.error=function(e,t,n){e="FFZ Error: "+e+(n?" -- "+JSON.stringify(t):""),this._log_data.push(e),void 0!==t&&console.groupCollapsed&&console.dir?(console.groupCollapsed(e),-1!==navigator.userAgent.indexOf("Firefox/")?console.log(t):console.dir(t),console.groupEnd(e)):console.assert(!1,e)},n.prototype.paste_logs=function(){this._pastebin(this._log_data.join("\n"),function(e){return e?void console.log("FFZ: Your FrankerFaceZ log has been pasted to: "+e):console.log("FFZ Error: Unable to upload log to pastebin.")})},n.prototype._pastebin=function(e,t){jQuery.ajax({url:"http://putco.de/",type:"PUT",data:e,context:this}).success(function(e){t.bind(this)(e.trim()+".log")}).fail(function(){t.bind(this)(null)})},n.prototype.get_user=function(){if(e.PP&&PP.login)return PP;if(e.App){var t=App.__container__.lookup("controller:navigation");return t?t.get("userData"):void 0}},t("./ui/menu"),t("./settings"),t("./socket"),t("./emoticons"),t("./badges"),t("./ember/room"),t("./ember/line"),t("./ember/chatview"),t("./ember/viewers"),t("./ember/moderation-card"),t("./debug"),t("./ext/betterttv"),t("./ext/emote_menu"),t("./featurefriday"),t("./ui/styles"),t("./ui/dark"),t("./ui/notifications"),t("./ui/viewer_count"),t("./ui/menu_button"),t("./ui/races"),t("./ui/my_emotes"),t("./ui/about_page"),t("./commands"),n.prototype.initialize=function(t,n){var o=void 0!=e.App&&void 0!=App.__container__&&void 0!=App.__container__.resolve("model:room");return o?void this.setup_ember(n):(t=t||10,void(n>=6e4?this.log('Twitch application not detected in "'+location.toString()+'". Aborting.'):setTimeout(this.initialize.bind(this,t,(n||0)+t),t)))},n.prototype.setup_ember=function(t){var o=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_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 i=e.performance&&performance.now?performance.now():Date.now(),r=i-o;this.log("Initialization complete in "+r+"ms")}},{"./badges":1,"./commands":2,"./debug":4,"./ember/chatview":5,"./ember/line":6,"./ember/moderation-card":7,"./ember/room":8,"./ember/viewers":9,"./emoticons":10,"./ext/betterttv":11,"./ext/emote_menu":12,"./featurefriday":14,"./settings":15,"./shims":16,"./socket":17,"./ui/about_page":18,"./ui/dark":19,"./ui/menu":20,"./ui/menu_button":21,"./ui/my_emotes":22,"./ui/notifications":23,"./ui/races":24,"./ui/styles":25,"./ui/viewer_count":26}],14:[function(t){var n=e.FrankerFaceZ,o=t("./constants");n.prototype.feature_friday=null,n.prototype.check_ff=function(e){e||this.log("Checking for Feature Friday data..."),jQuery.ajax(o.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],"Feature Friday");var o=App.__container__.lookup("controller:channel");if(!o||o.get("id")!=this.feature_friday.channel){var i=this.feature_friday,r=document.createElement("div"),s=document.createElement("a");r.className="chat-menu-content",r.style.textAlign="center";var a=i.display_name+(i.live?" is live now!":"");s.className="button primary",s.classList.toggle("live",i.live),s.classList.toggle("blue",this.has_bttv&&BetterTTV.settings.get("showBlueButtons")),s.href="http://www.twitch.tv/"+i.channel,s.title=a,s.target="_new",s.innerHTML="<span>"+a+"</span>",r.appendChild(s),t.appendChild(r)}}},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,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}],15:[function(t){var n=e.FrankerFaceZ,o=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 o=n.settings_info[t],i=o.storage_key||make_ls(t),r=o.hasOwnProperty("value")?o.value:void 0;if(localStorage.hasOwnProperty(i))try{r=JSON.parse(localStorage.getItem(i))}catch(s){this.log('Error loading value for "'+t+'": '+s)}this.settings[t]=r}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.menu_pages.settings={render:function(e,t){var o={},i=[];for(var r in n.settings_info)if(n.settings_info.hasOwnProperty(r)){var s=n.settings_info[r],a=s.category||"Miscellaneous",l=o[a];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||(i.push(a),l=o[a]=[]),l.push([r,s])}i.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;u<i.length;u++){var d=i[u],h=o[d],p=document.createElement("div"),m=document.createElement("div");m.className="heading",p.className="chat-menu-content",m.innerHTML=d,p.appendChild(m),h.sort(function(e,t){var e=e[1],t=t[1],n=e.type,o=t.type,i=e.name.toLowerCase(),r=t.name.toLowerCase();return o>n?-1:n>o?1:r>i?-1:i>r?1:0});for(var _=0;_<h.length;_++){var r=h[_][0],s=h[_][1],f=document.createElement("p"),g=this.settings.get(r);if(f.className="clearfix","boolean"==s.type){var v=document.createElement("a"),b=document.createElement("span");v.className="switch",v.classList.toggle("active",g),v.innerHTML="<span></span>",b.className="switch-label",b.innerHTML=s.name,f.appendChild(v),f.appendChild(b),v.addEventListener("click",toggle_setting.bind(this,v,r))}else{f.classList.add("option");var y=document.createElement("a");y.innerHTML=s.name,y.href="#",f.appendChild(y),y.addEventListener("click",s.method.bind(this))}if(s.help){var w=document.createElement("span");w.className="help",w.innerHTML=s.help,f.appendChild(w)}p.appendChild(f)}t.appendChild(p)}},name:"Settings",icon:o.GEAR,sort_order:99999},n.prototype._setting_update=function(t){if(t||(t=e.event),this.log("Storage Event",t),t.key&&"ffz_setting_"===t.key.substr(0,12)){var o=t.key,i=o.substr(12),r=void 0,s=n.settings_info[i];if(!s){for(i in n.settings_info)if(n.settings_info.hasOwnProperty(i)&&(s=n.settings_info[i],s.storage_key==o))break;if(s.storage_key!=o)return}this.log("Updated Setting: "+i);try{r=JSON.parse(t.newValue)}catch(a){this.log('Error loading new value for "'+i+'": '+a),r=s.value||void 0}if(this.settings[i]=r,s.on_update)try{s.on_update.bind(this)(r,!1)}catch(a){this.log('Error running updater for setting "'+i+'": '+a)}}},n.prototype._setting_get=function(e){return this.settings[e]},n.prototype._setting_set=function(e,t){var o=n.settings_info[e],i=o.storage_key||make_ls(e),r=JSON.stringify(t);if(this.settings[e]=t,localStorage.setItem(i,r),this.log('Changed Setting "'+e+'" to: '+r),o.on_update)try{o.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],o=t.storage_key||make_ls(e),i=void 0;if(localStorage.hasOwnProperty(o)&&localStorage.removeItem(o),delete this.settings[e],t&&(i=this.settings[e]=t.hasOwnProperty("value")?t.value:void 0),t.on_update)try{t.on_update.bind(this)(i,!0)}catch(r){this.log('Error running updater for setting "'+e+'": '+r)}}},{"./constants":3}],16:[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}},{}],17:[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://ffz.stendec.me/")}catch(o){return this._ws_exists=!1,this.log("Error Creating WebSocket: "+o)}this._ws_exists=!0,e.onopen=function(){n._ws_open=!0,n._ws_delay=0,n.log("Socket connected.");var e=n.get_user();e&&n.ws_send("setuser",e.login);for(var t in n.rooms)n.rooms.hasOwnProperty(t)&&n.ws_send("sub",t);var o=n._ws_pending;n._ws_pending=[];for(var i=0;i<o.length;i++){var r=o[i];n.ws_send(r[0],r[1],r[2])}},e.onclose=function(){n.log("Socket closed."),n._ws_open=!1;for(var e=0;e<t.ws_on_close.length;e++)try{t.ws_on_close[e].bind(n)()}catch(o){n.log("Error on Socket Close Callback: "+o)}n._ws_delay<6e4?n._ws_delay+=5e3:n._ws_delay=1e3*(Math.floor(60*Math.random())+30),setTimeout(n.ws_create.bind(n),n._ws_delay)},e.onmessage=function(e){var o,i,r=e.data.indexOf(" "),s=e.data.substr(r+1),a=parseInt(e.data.slice(0,r));if(r=s.indexOf(" "),-1===r&&(r=s.length),o=s.slice(0,r),s=s.substr(r+1),s&&(i=JSON.parse(s)),-1===a){var l=t.ws_commands[o];l?l.bind(n)(i):n.log("Invalid command: "+o,i)}else{var c="True"===o,u=n._ws_callbacks[a];n.log("Socket Reply to "+a+" - "+(c?"SUCCESS":"FAIL"),i),u&&(delete n._ws_callbacks[a],u(c,i))}}},t.prototype.ws_send=function(e,t,n,o){if(!this._ws_open){if(o){var i=this._ws_pending=this._ws_pending||[];return i.push([e,t,n]),!0}return!1}var r=++this._ws_last_req;return t=void 0!==t?" "+JSON.stringify(t):"",n&&(this._ws_callbacks[r]=n),this._ws_sock.send(r+" "+e+t),r},t.ws_commands.do_authorize=function(e){var n;for(var o in this.rooms)if(this.rooms.hasOwnProperty(o)){var i=this.rooms[o];if(i&&i.room&&!i.room.get("roomProperties.eventchat")&&!i.room.get("isGroupRoom")&&i.room.tmiRoom){var r=i.room.tmiRoom._getConnection();if(r.isConnected){n=r;break}}}n?n._send("PRIVMSG #frankerfacezauthorizer :AUTH "+e):setTimeout(t.ws_commands.do_authorize.bind(this,e),5e3)}},{}],18:[function(t){var n=e.FrankerFaceZ,o=t("../constants");n.menu_pages.about={name:"About",icon:o.HEART,sort_order:1e5,render:function(e,t){var o=this.rooms[e.get("context.currentRoom.id")],i=!1,r=this;if(o&&o.sets.length)for(var s=0;s<o.sets.length;s++){var a=this.emote_sets[o.sets[s]];if(a&&a.count>0){i=!0;break}}var l=document.createElement("div"),c="";c+="<h1>FrankerFaceZ</h1>",c+='<div class="ffz-about-subheading">new ways to woof</div>',l.className="chat-menu-content center",l.innerHTML=c,t.appendChild(l);var u=document.createElement("div"),d=document.createElement("a"),h="To use custom emoticons in "+(i?"this channel":"tons of channels")+", get FrankerFaceZ from http://www.frankerfacez.com";d.className="button primary",d.innerHTML="Advertise in Chat",d.addEventListener("click",this._add_emote.bind(this,e,h)),u.appendChild(d);var p=document.createElement("a");p.className="button ffz-donate",p.href="http://www.frankerfacez.com/donate.html",p.target="_new",p.innerHTML="Donate",u.appendChild(p),u.className="chat-menu-content center",t.appendChild(u);var m=document.createElement("div");c='<table class="ffz-about-table">',c+='<tr><th colspan="4">Developers</th></tr>',c+='<tr><td>Dan Salvato</td><td><a class="twitch" href="http://www.twitch.tv/dansalvato" title="Twitch" target="_new">&nbsp;</a></td><td><a class="twitter" href="https://twitter.com/dansalvato1" title="Twitter" target="_new">&nbsp;</a></td><td><a class="youtube" href="https://www.youtube.com/user/dansalvato1" title="YouTube" target="_new">&nbsp;</a></td></tr>',c+='<tr><td>Stendec</td><td><a class="twitch" href="http://www.twitch.tv/sirstendec" title="Twitch" target="_new">&nbsp;</a></td><td><a class="twitter" href="https://twitter.com/SirStendec" title="Twitter" target="_new">&nbsp;</a></td><td><a class="youtube" href="https://www.youtube.com/channel/UCnxuvmK1DCPCXSJ-mXIh4KQ" title="YouTube" target="_new">&nbsp;</a></td></tr>',c+='<tr class="debug"><td>Version '+n.version_info+'</td><td colspan="3"><a href="#" id="ffz-debug-logs">Logs</a></td></tr>',m.className="chat-menu-content center",m.innerHTML=c;var _=!1;m.querySelector("#ffz-debug-logs").addEventListener("click",function(){_||(_=!0,r._pastebin(r._log_data.join("\n"),function(e){_=!1,e?prompt("Your FrankerFaceZ logs have been uploaded to the URL:",e):alert("There was an error uploading the FrankerFaceZ logs.")}))}),t.appendChild(m)}}},{"../constants":3}],19:[function(t){var n=e.FrankerFaceZ,o=t("../constants");n.settings_info.twitch_chat_dark={type:"boolean",value:!1,visible:!1},n.settings_info.dark_twitch={type:"boolean",value:!1,visible:function(){return!this.has_bttv},name:"Dark Twitch <span>Beta</span>",help:"Apply a dark background to channels and other related pages for easier viewing.",on_update:function(e){if(!this.has_bttv){document.body.classList.toggle("ffz-dark",e);var t=App.__container__.lookup("controller:settings").get("model");e?(this._load_dark_css(),this.settings.set("twitch_chat_dark",t.get("darkMode")),t.set("darkMode",!0)):t.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&&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",o.SERVER+"script/dark.css"),document.head.appendChild(e)}}},{"../constants":3}],20:[function(t){var n=e.FrankerFaceZ,o=t("../constants");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,o=e._popup;o&&(o=jQuery(o),n=o.parent(),n.is(t.target)||0!==n.has(t.target).length||(o.remove(),delete e._popup,e._popup_kill&&e._popup_kill(),delete e._popup_kill))})},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 i=document.createElement("div"),r=document.createElement("div"),s=document.createElement("ul"),a=this.has_bttv?BetterTTV.settings.get("darkenedMode"):!1;i.className="emoticon-selector chat-menu ffz-ui-popup",r.className="emoticon-selector-box dropmenu",i.appendChild(r),i.classList.toggle("dark",a);var l=document.createElement("div");l.className="ffz-ui-menu-page",r.appendChild(l),s.className="menu clearfix",r.appendChild(s);var c=document.createElement("li");c.className="title",c.innerHTML="<span>"+(o.DEBUG?"[DEV] ":"")+"FrankerFaceZ</span>",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;if(e[0]>t[0])return-1;var n=e[1].toLowerCase(),o=t[1].toLowerCase();return o>n?1:n>o?-1:0});for(var p=0;p<u.length;p++){var d=u[p][1],h=u[p][2],m=document.createElement("li"),_=document.createElement("a");m.className="item",m.id="ffz-menu-page-"+d,_.title=h.name,_.innerHTML=h.icon,jQuery(_).tipsy(),_.addEventListener("click",this._ui_change_page.bind(this,e,s,l,d)),m.appendChild(_),s.appendChild(m)}this._ui_change_page(e,s,l,this._last_page||"channel"),this._popup=i,l.style.maxHeight=Math.max(100,e.$().height()-162)+"px",e.$(".chat-interface").append(i)},n.prototype._ui_change_page=function(e,t,o,i){this._last_page=i,o.innerHTML="",o.setAttribute("data-page",i);for(var r=t.querySelectorAll("li.active"),s=0;s<r.length;s++)r[s].classList.remove("active");var a=t.querySelector("#ffz-menu-page-"+i);a?a.classList.add("active"):this.log("No matching page: "+i),n.menu_pages[i].render.bind(this)(e,o)},n.prototype._tokenize_message=function(e,t){var n=App.__container__.lookup("controller:line"),o=App.__container__.lookup("controller:room"),i=this.rooms[t],r=this.get_user();if(!n||!o||!i)return[e];o.set("model",i.room),n.set("parentController",o);var s={from:r&&r.login||"FrankerFaceZ",message:e,tags:{emotes:i.room.tmiSession._emotesParser.parseEmotesTag(e)}};n.set("model",s);var a=n.get("tokenizedMessage");return n.set("model",null),o.set("model",null),n.set("parentController",null),a},n.menu_pages.channel={render:function(e,t){var n=e.get("controller.currentRoom.id"),o=this.rooms[n];this._emotes_for_sets(t,e,o&&o.menu_sets||[]),this._feature_friday_ui(n,t,e)},name:"Channel",icon:o.ZREKNARF},n.prototype._emotes_for_sets=function(e,t,n,o,i){if(null!=o){var r=document.createElement("div");r.className="list-header",r.appendChild(document.createTextNode(o)),i&&r.appendChild(i),e.appendChild(r)}var s=document.createElement("div"),a=0;s.className="emoticon-grid";for(var l=0;l<n.length;l++){var c=this.emote_sets[n[l]];if(c&&c.emotes)for(var u in c.emotes)if(c.emotes.hasOwnProperty(u)){var d=c.emotes[u];if(c.emotes.hasOwnProperty(u)&&!d.hidden){a++;var h=document.createElement("span");h.className="emoticon tooltip",h.style.backgroundImage='url("'+d.url+'")',h.style.width=d.width+"px",h.style.height=d.height+"px",h.title=d.name,h.addEventListener("click",this._add_emote.bind(this,t,d.name)),s.appendChild(h)}}}a||(s.innerHTML="This channel has no emoticons.",s.className="chat-menu-content ffz-no-emotes center"),e.appendChild(s)},n.prototype._add_emote=function(e,t){var n,o,i;this.has_bttv?(n=e.get("element").querySelector("textarea"),o=n.value):(i=e.get("controller.currentRoom"),o=i.get("messageToSend")||""),o+=(o&&" "!==o.substr(-1)?" ":"")+(t.name||t),n?n.value=o:i.set("messageToSend",o)}},{"../constants":3}],21:[function(t){var n=e.FrankerFaceZ,o=t("../constants");n.prototype.build_ui_link=function(e){var t=document.createElement("a");return t.className="ffz-ui-toggle",t.innerHTML=o.CHAT_BUTTON,t.addEventListener("click",this.build_ui_popup.bind(this,e)),this.update_ui_link(t),t},n.prototype.update_ui_link=function(e){var t=App.__container__.lookup("controller:chat");if(e=e||document.querySelector("a.ffz-ui-toggle"),e&&t){var n=t.get("currentRoom.id"),o=this.rooms[n],i=!1,r=this.has_bttv?BetterTTV.settings.get("darkenedMode"):!1,s=this.has_bttv?BetterTTV.settings.get("showBlueButtons"):!1,a=this.feature_friday&&this.feature_friday.live;if(o&&o.sets.length)for(var l=0;l<o.sets.length;l++){var c=this.emote_sets[o.sets[l]];if(c&&c.count>0){i=!0;break}}e.classList.toggle("no-emotes",!i),e.classList.toggle("live",a),e.classList.toggle("dark",r),e.classList.toggle("blue",s)}}},{"../constants":3}],22:[function(t){var n=e.FrankerFaceZ,o=t("../constants"),i="http://static-cdn.jtvnw.net/emoticons/v1/",r={"00000turbo":!0},s=function(e){var t=App.__container__.lookup("controller:chat"),n=t.get("currentRoom.id"),o=e.rooms[n],i=o?o.room.tmiSession:null,r=i&&i._emotesParser&&i._emotesParser.emoticonSetIds||"0",s=e.get_user(),a=s&&e.users[s.login]&&e.users[s.login].sets||[];return r=r.split(",").removeObject("0"),[r,a]};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){}},n.menu_pages.my_emotes={name:"My Emoticons",icon:o.EMOTE,visible:function(){var e=s(this);return e[0].length>0||e[1].length>0},render:function(e,t){var o=s(this),a=this;new RSVP.Promise(function(e){for(var t=[],i=0;i<o[0].length;i++){var s=o[0][i];a._twitch_emote_sets[s]||t.push(s)}RSVP.all([new RSVP.Promise(function(e){return t.length?void Twitch.api.get("chat/emoticon_images",{emotesets:t.join(",")},{version:3}).done(function(t){if(t.emoticon_sets)for(var n in t.emoticon_sets)if(t.emoticon_sets.hasOwnProperty(n)){var o=a._twitch_emote_sets[n]=a._twitch_emote_sets[n]||{};o.emotes=t.emoticon_sets[n],o.source="Twitch"}e()}).fail(function(){e()}):e()}),new RSVP.Promise(function(e){if(!t.length)return e();var o=[],i=t,s=function(e,t){var i=a._twitch_emote_sets[e]=a._twitch_emote_sets[e]||{};if(t&&!r[t]){if("turbo"==t)return i.channel="Twitch Turbo",void(i.badge="//cdn.frankerfacez.com/script/turbo_badge.png");o.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,i,t)));var s=t.toLowerCase(),l=n.capitalization[s];return l&&Date.now()-l[1]<36e5?void(i.channel=l[0]):void o.push(new RSVP.Promise(function(e,t,o,i){a.ws_send("get_display_name",t,function(r,s){var a=r?s:o;n.capitalization[t]=[a,Date.now()],e.channel=a,i()})||(e.channel=o,i()),setTimeout(function(e,t,n){e.channel||(e.channel=t),n()}.bind(this,e,o,i),5e3)}.bind(this,i,s,t)))}},l=function(){o.length?RSVP.all(o).then(e,e):e()};t=[];for(var c=0;c<i.length;c++){var u=i[c];a._twitch_set_to_channel[u]?s(u,a._twitch_set_to_channel[u]):t.push(u)}t.length>0?(a.ws_send("twitch_sets",t,function(e,n){if(t=[],e){for(var o in n)n.hasOwnProperty(o)&&(a._twitch_set_to_channel[o]=n[o],s(o,n[o]));localStorage.ffzTwitchSets=JSON.stringify(a._twitch_set_to_channel)}l()}),setTimeout(function(){t.length&&l()},5e3)):l()})]).then(function(){for(var t={},n=0;n<o[0].length;n++){var i=o[0][n];a._twitch_emote_sets[i]&&(t[i]=a._twitch_emote_sets[i])}e(t)},function(){e({})})}).then(function(o){try{if("my_emotes"!=t.getAttribute("data-page"))return;t.innerHTML="";var r=[];for(var s in o)if(o.hasOwnProperty(s)){var l=o[s];l.channel&&l.emotes&&l.emotes.length&&r.push([1,l.channel,l])}r.sort(function(e,t){if(e[0]<t[0])return-1;if(e[0]>t[0])return 1;var n=e[1].toLowerCase(),o=t[1].toLowerCase();return"twitch turbo"===n&&(n="zzz"+n),"twitch turbo"===o&&(o="zzz"+o),o>n?-1:n>o?1:0});for(var c=0;c<r.length;c++){var l=r[c][2],u=document.createElement("div"),d=document.createElement("div");u.className="heading",u.innerHTML='<span class="right">'+l.source+"</span>"+n.get_capitalization(l.channel),l.badge&&(u.style.backgroundImage='url("'+l.badge+'")'),d.className="emoticon-grid",d.appendChild(u);for(var h=0;h<l.emotes.length;h++){var p=l.emotes[h],m=document.createElement("span");m.className="emoticon tooltip",m.style.backgroundImage='url("'+i+p.id+'/1.0")';
var _='image-set(url("'+i+p.id+'/1.0") 1x, url("'+i+p.id+'/2.0") 2x, url("'+i+p.id+'/3.0") 4x)';m.style.backgroundImage="-webkit-"+_,m.style.backgroundImage="-moz-"+_,m.style.backgroundImage="-ms-"+_,m.style.backgroundImage=_,m.title=p.code,m.addEventListener("click",a._add_emote.bind(a,e,p.code)),d.appendChild(m)}t.appendChild(d)}if(!r.length){var d=document.createElement("div");d.className="chat-menu-content center",d.innerHTML="Error Loading Subscriptions",t.appendChild(d)}}catch(f){a.log("My Emotes Menu Error",f),t.innerHTML="";var d=document.createElement("div"),u=document.createElement("div"),g=document.createElement("p");u.className="heading",u.innerHTML="Error Loading Menu",d.appendChild(u),g.className="clearfix",g.textContent=f,d.appendChild(g),d.className="chat-menu-content",t.appendChild(d)}})}}},{"../constants":3}],23:[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",visible:function(){return!this.has_bttv},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(o){}}t._notifications={},t._last_notification=0},t.prototype.show_notification=function(e,n,o,i,r,s){var a=Notification.permission;if("denied "===a)return!1;if("granted"===a){n=n||"FrankerFaceZ",i=i||1e4;var l={lang:"en-US",dir:"ltr",body:e,tag:o||"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],r&&r.bind(c)()}),u.addEventListener("close",function(){delete t._notifications[d],s&&s.bind(c)()}),void("number"==typeof i&&u.addEventListener("show",function(){setTimeout(function(){delete t._notifications[d],u.close()},i)}))}var c=this;Notification.requestPermission(function(){c.show_notification(e,n,o)})},t.prototype.show_message=function(t){e.noty({text:t,theme:"ffzTheme",layout:"bottomCenter",closeWith:["button"]}).show()}},{}],24:[function(t){var n=e.FrankerFaceZ,o=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 <a href="http://www.speedrunslive.com/" target="_new">SpeedRunsLive</a> races under channels.',on_update:function(){this.rebuild_race_ui()}},n.ws_on_close.push(function(){var e=App.__container__.lookup("controller:channel"),t=e.get("id"),n=!1;for(var o in this.srl_races)delete this.srl_races[o],o==t&&(n=!0);n&&this.rebuild_race_ui()}),n.ws_commands.srl_race=function(e){for(var t=App.__container__.lookup("controller:channel"),n=t.get("id"),o=!1,i=0;i<e[0].length;i++){var r=e[0][i];this.srl_races[r]=e[1],r==n&&(o=!0)}if(e[1]){var s=e[1],a=s.twitch_entrants={};for(var l in s.entrants)s.entrants.hasOwnProperty(l)&&(s.entrants[l].channel&&(a[s.entrants[l].channel]=l),s.entrants[l].name=l)}o&&this.rebuild_race_ui()},n.prototype.rebuild_race_ui=function(){var e=App.__container__.lookup("controller:channel"),t=e.get("id"),n=this.srl_races[t],o=this.settings.srl_races,i=document.querySelector(".stats-and-actions .channel-actions"),r=i.querySelector("#ffz-ui-race");if(!n||!o)return r&&r.parentElement.removeChild(r),void(this._popup&&"ffz-race-popup"==this._popup.id&&(delete this._popup,this._popup_kill&&this._popup_kill(),delete this._popup_kill));if(r)return this._update_race(!0);r=document.createElement("span"),r.setAttribute("data-channel",t),r.id="ffz-ui-race";var s=document.createElement("span");s.className="button drop action",s.title="SpeedRunsLive Race",s.innerHTML='<span class="logo"><span>',s.addEventListener("click",this.build_race_popup.bind(this)),r.appendChild(s),i.appendChild(r),this._update_race(!0)},n.prototype._race_kill=function(){this._race_timer&&(clearTimeout(this._race_timer),delete this._race_timer),delete this._race_game,delete this._race_goal},n.prototype.build_race_popup=function(){var e=this._popup;if(!e||(e.parentElement.removeChild(e),delete this._popup,this._popup_kill&&this._popup_kill(),delete this._popup_kill,"ffz-race-popup"!=e.id)){var t=document.querySelector("#ffz-ui-race");if(t){var o=t.querySelector(".button"),i=o.offsetLeft+o.offsetWidth,r=t.getAttribute("data-channel"),s=this.srl_races[r],e=document.createElement("div"),a="";e.id="ffz-race-popup",e.className=(i>=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(r),_=encodeURIComponent("I'm watching "+m+" race "+s.goal+" in "+s.game+" on SpeedRunsLive!");a='<div class="heading"><div></div><span></span></div>',a+='<div class="table" style="max-height:'+h+'px"><table><thead><tr><th>#</th><th>Entrant</th><th>&nbsp;</th><th>Time</th></tr></thead>',a+="<tbody></tbody></table></div>",a+='<div class="divider"></div>',a+='<iframe class="twitter_share_button" style="width:110px; height:20px" src="https://platform.twitter.com/widgets/tweet_button.html?text='+_+"%20Watch%20at&via=Twitch&url=http://www.twitch.tv/"+r+'"></iframe>',a+='<p class="right"><a target="_new" href="http://www.speedrunslive.com/race/?id='+s.id+'">SRL</a>',c&&(a+=' &nbsp; <a target="_new" href="'+l+'">Multitwitch</a>'),a+="</p>",e.innerHTML=a,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"),i=this.srl_races[n];if(!i)return t.parentElement.removeChild(t),this._popup_kill&&this._popup_kill(),void(this._popup&&(delete this._popup,delete this._popup_kill));var r=i.twitch_entrants[n],s=i.entrants[r],a=t.querySelector("#ffz-race-popup"),l=Date.now()/1e3,c=Math.floor(l-i.time);if(t.querySelector(".logo").innerHTML=o.placement(s),a){var u=a.querySelector("tbody"),d=a.querySelector(".heading span"),h=a.querySelector(".heading div");u.innerHTML="";var p=[],m=!0;for(var _ in i.entrants)i.entrants.hasOwnProperty(_)&&("racing"==i.entrants[_].state&&(m=!1),p.push(i.entrants[_]));p.sort(function(e,t){var n=e.place||9999,o=t.place||9999,i=e.time||c,r=t.time||c;return("forfeit"==e.state||"dq"==e.state)&&(n=1e4),("forfeit"==t.state||"dq"==t.state)&&(o=1e4),o>n?-1:n>o?1:e.name<t.name?-1:e.name>t.name?1:r>i?-1:i>r?1:void 0});for(var f=0;f<p.length;f++){var _=p[f],g='<a target="_new" href="http://www.speedrunslive.com/profiles/#!/'+o.sanitize(_.name)+'">'+_.display_name+"</a>",v=_.channel?'<a target="_new" class="twitch" href="http://www.twitch.tv/'+o.sanitize(_.channel)+'"></a>':"",b=_.hitbox?'<a target="_new" class="hitbox" href="http://www.hitbox.tv/'+o.sanitize(_.hitbox)+'"></a>':"",y=c?o.time_to_string(_.time||c):"",w=o.place_string(_.place),k=_.comment?o.sanitize(_.comment):"";u.innerHTML+="<tr"+(k?' title="'+k+'"':"")+' class="'+_.state+'"><td>'+w+"</td><td>"+g+"</td><td>"+v+b+'</td><td class="time">'+("forfeit"==_.state?"Forfeit":y)+"</td></tr>"}if(this._race_game!=i.game||this._race_goal!=i.goal){this._race_game=i.game,this._race_goal=i.goal;var F=o.sanitize(i.game),E=o.sanitize(i.goal);h.innerHTML='<h2 title="'+F+'">'+F+"</h2><b>Goal: </b>"+E}c?m?d.innerHTML="Done":(d.innerHTML=o.time_to_string(c),this._race_timer=setTimeout(this._update_race.bind(this),1e3)):d.innerHTML="Entry Open"}}}},{"../utils":27}],25:[function(t){var n=e.FrankerFaceZ,o=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",o.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}],26:[function(t){var n=e.FrankerFaceZ,o=t("../constants"),i=t("../utils");n.ws_commands.viewers=function(e){var t=e[0],n=e[1],r=App.__container__.lookup("controller:channel"),s=r&&r.get&&r.get("id");if(s===t){var a=document.querySelector(".channel-stats .ffz.stat"),l=o.ZREKNARF+" "+i.number_commas(n);if(a)a.innerHTML=l;else{var c=document.querySelector(".channel-stats");if(!c)return;a=document.createElement("span"),a.className="ffz stat",a.title="Viewers with FrankerFaceZ",a.innerHTML=l,c.appendChild(a),jQuery(a).tipsy()}}}},{"../constants":3,"../utils":27}],27:[function(t,n){var o=(e.FrankerFaceZ,t("./constants"),{}),i=document.createElement("span"),r=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)),o=Math.max(0,Math.min(255,e[1]-t)),i=Math.max(0,Math.min(255,e[2]-t));return[n,o,i]},a=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;t<e.length;t++)e[t]=e[t]<=.03928?e[t]/12.92:Math.pow((e[t]+.055)/1.055,2.4);return.2126*e[0]+.7152*e[1]+.0722*e[2]};n.exports={update_css:function(e,t,n){var o=e.innerHTML,i="/*BEGIN "+t+"*/",r="/*END "+t+"*/",s=o.indexOf(i),a=o.indexOf(r),l=-1!==s&&-1!==a&&a>s;(l||n)&&(l&&(o=o.substr(0,s)+o.substr(a+r.length)),n&&(o+=i+n+r),e.innerHTML=o)},get_luminance:c,brighten:s,darken:l,rgb_to_css:a,number_commas:function(e){var t=e.toString().split(".");return t[0]=t[0].replace(/\B(?=(\d{3})+(?!\d))/g,","),t.join(".")},place_string:r,placement:function(e){return"forfeit"==e.state?"Forfeit":"dq"==e.state?"DQed":e.place?r(e.place):""},sanitize:function(e){var t=o[e];return t||(i.textContent=e,t=o[e]=i.innerHTML,i.innerHTML=""),t},time_to_string:function(e){var t=e%60,n=Math.floor(e/60),o=Math.floor(n/60);return n%=60,(10>o?"0":"")+o+":"+(10>n?"0":"")+n+":"+(10>t?"0":"")+t}}},{"./constants":3}]},{},[13]),e.ffz=new FrankerFaceZ}(window);