1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-07-02 17:18:31 +00:00
FrankerFaceZ/script.min.js

3 lines
No EOL
89 KiB
JavaScript

!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;s<a.length;s++)o(a[s]);return o}({1:[function(t){var n=e.FrankerFaceZ,a=t("./constants"),o=t("./utils");n.settings_info.bot_badges={type:"boolean",value:!0,category:"Chat",name:"Bot Badges",help:"Give special badges to known bots."},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()},n.ws_commands.reload_badges=function(){this._legacy_load_bots(),this._legacy_load_donors()},n.ws_commands.set_badge=function(e){var t=e[0],n=e[1],a=e[2],o=this.users[t]=this.users[t]||{},i=o.badges=o.badges||{};void 0===a?delete i[n]:i[n]=a};var i=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],a=[],o=-1,i=BetterTTV.settings.get("alphaTags");if(n&&n.badges){for(var s=0;s<e.badges.length;s++){var r=e.badges[s];if("subscriber"==r.type||"turbo"==r.type){o=s;break}}for(var l in n.badges)if(n.badges.hasOwnProperty(l)){var r=n.badges[l],c=this.badges[r.id]||{},u=r.title||c.title,d="";if(void 0!==c.visible){var h=c.visible;if("function"==typeof h&&(h=h.bind(this)(null,t)),!h)continue}if(c.replaces){for(var p=!1,s=0;s<e.badges.length;s++){var m=e.badges[s];if(m.type==c.replaces){m.type="ffz-badge-replacement "+m.type,m.description+=", "+(r.title||c.title)+'" style="background-image: url(&quot;'+(r.image||c.image)+"&quot;)",p=!0;break}}if(p)continue}r.image&&(d+="background-image: url(&quot;"+r.image+"&quot;); "),r.color&&!i&&(d+="background-color: "+r.color+"; "),r.extra_css&&(d+=r.extra_css),d&&(u+='" style="'+d),a.push([(-1==o?1:-1)*l,{type:"ffz-badge-"+r.id+(i?" alpha":""),name:"",description:u}])}if(a.sort(function(e,t){return e[0]-t[0]}),-1==o)for(;a.length;)e.badges.push(a.shift()[1]);else for(;a.length;)e.badges.insertAt(o,a.shift()[1])}},n.prototype.render_badge=function(e){var t=e.get("context.model.from"),n=e.get("context.parentController.content.id"),a=e.$(".badges"),o=this.users[t];if(o&&o.badges){var i=a.find(".badge").filter(function(){var e=this.title.toLowerCase();return"subscriber"==e||"turbo"==e}).first(),s=[],r=!!i.length;for(var l in o.badges)if(o.badges.hasOwnProperty(l)){var c=o.badges[l],u=this.badges[c.id]||{};if(void 0!==u.visible){var d=u.visible;if("function"==typeof d&&(d=d.bind(this)(n,t)),!d)continue}if(u.replaces){var h=a[0].querySelector(".badge."+u.replaces);if(h){h.style.backgroundImage='url("'+(c.image||u.image)+'")',h.classList.add("ffz-badge-replacement"),h.title+=", "+(c.title||u.title);continue}}var h=document.createElement("div");h.className="badge float-left tooltip ffz-badge-"+c.id,h.setAttribute("title",c.title||u.title),c.image&&(h.style.backgroundImage='url("'+c.image+'")'),c.color&&(h.style.backgroundColor=c.color),c.extra_css&&(h.style.cssText+=c.extra_css),s.push([(r?1:-1)*l,h])}if(s.sort(function(e,t){return e[0]-t[0]}),r)for(;s.length;)i.before(s.shift()[1]);else for(;s.length;)a.append(s.shift()[1])}},n.bttv_known_bots=["nightbot","moobot","sourbot","xanbot","manabot","mtgbot","ackbot","baconrobot","tardisbot","deejbot","valuebot","stahpbot"],n.prototype._legacy_add_donors=function(){this.badges[0]={id:0,title:"FFZ Developer",color:"#FAAF19",image:"//cdn.frankerfacez.com/channel/global/devicon.png"},o.update_css(this._badge_style,0,i(this.badges[0])),this.badges[1]={id:1,title:"FFZ Donor",color:"#755000",image:"//cdn.frankerfacez.com/channel/global/donoricon.png"},o.update_css(this._badge_style,1,i(this.badges[1])),this.badges[2]={id:2,title:"Bot",color:"#595959",image:"//cdn.frankerfacez.com/channel/global/boticon.png",replaces:"moderator",visible:function(e,t){return this.settings.bot_badges&&!(this.has_bttv&&-1!==n.bttv_known_bots.indexOf(t))}},o.update_css(this._badge_style,2,i(this.badges[2]));for(var e=0;e<n.bttv_known_bots.length;e++){var t=n.bttv_known_bots[e],a=this.users[t]=this.users[t]||{},s=a.badges=a.badges||{};s[0]||(s[0]={id:2})}this.users.sirstendec={badges:{1:{id:0}}},this.users.zenwan={badges:{0:{id:2,image:"//cdn.frankerfacez.com/channel/global/momiglee_badge.png",title:"WAN"}}},this.load_set(".donor"),this._legacy_load_bots(),this._legacy_load_donors()},n.prototype._legacy_load_bots=function(e){jQuery.ajax(a.SERVER+"script/bots.txt",{cache:!1,context:this}).done(function(e){this._legacy_parse_badges(e,0,2)}).fail(function(t){404!=t.status&&(e=(e||0)+1,10>e&&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;r<s.length;r++){var l=s[r],c=this.users[l]=this.users[l]||{},u=c.badges=c.badges||{},d=c.sets=c.sets||[];-1===d.indexOf(ds)&&d.push(ds),u[t]||(u[t]={id:n},i+=1)}this.log('Added "'+a+'" badge to '+o.number_commas(i)+" users.")}},{"./constants":3,"./utils":28}],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 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 <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 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 <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"/>',a="true"==localStorage.ffzDebugMode&&document.body.classList.contains("ffz-dev");t.exports={DEBUG:a,SERVER:a?"//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>",CLOCK:'<svg class="svg-glyph_views svg-clock" 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="M8,15c-3.866,0-7-3.134-7-7s3.134-7,7-7s7,3.134,7,7 S11.866,15,8,15z M8,3C5.238,3,3,5.238,3,8s2.238,5,5,5s5-2.238,5-5S10.762,3,8,3z M7.293,8.707L7,8l1-4l0.902,3.607L11,11 L7.293,8.707z"/></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(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 <nobr>(since "+i.toLocaleString()+")</nobr>",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,"&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=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;s<i.length;s++)i[s].title=o}},p=function(e){var t,n=this._link_data[e];if(!n)return"";if(n.tooltip)return n.tooltip;if("youtube"==n.type)t="<b>YouTube: "+a.sanitize(n.title)+"</b><hr>",t+="Channel: "+a.sanitize(n.channel)+" | "+a.time_to_string(n.duration)+"<br>",t+=a.number_commas(n.views||0)+" Views | &#128077; "+a.number_commas(n.likes||0)+" &#128078; "+a.number_commas(n.dislikes||0);else if("strawpoll"==n.type){t="<b>Strawpoll: "+a.sanitize(n.title)+"</b><hr><table><tbody>";for(var o in n.items){{var i=n.items[o];Math.floor(i/n.total*100)}t+='<tr><td style="text-align:left">'+a.sanitize(o)+'</td><td style="text-align:right">'+a.number_commas(i)+"</td></tr>"}t+="</tbody></table><hr>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+="<br><small>Data was cached "+a.time_to_string(r)+" ago.</small>")}}else if("twitch"==n.type){t="<b>Twitch: "+a.sanitize(n.display_name)+"</b><hr>";var l=a.parse_date(n.since);l&&(t+="Member Since: "+a.date_string(l)+"<br>"),t+="<nobr>Views: "+a.number_commas(n.views)+"</nobr> | <nobr>Followers: "+a.number_commas(n.followers)+"</nobr>"}else if("twitter"==n.type)t="<b>Tweet By: "+a.sanitize(n.user)+"</b><hr>",t+=a.sanitize(n.tweet);else if("reputation"==n.type){if(t='<span style="word-wrap: break-word">'+a.sanitize(n.full.toLowerCase())+"</span>",n.trust<50||n.safety<50||n.tags&&n.tags.length>0){t+="<hr>";var c=!1;(n.trust<50||n.safety<50)&&(n.unsafe=!0,t+="<b>Potentially Unsafe Link</b><br>",t+="Trust: "+n.trust+"% | Child Safety: "+n.safety+"%",c=!0),n.tags&&n.tags.length>0&&(t+=(c?"<br>":"")+"Tags: "+n.tags.join(", ")),t+="<br>Data Source: WOT"}}else n.full&&(t='<span style="word-wrap: break-word">'+a.sanitize(n.full.toLowerCase())+"</span>");return t||(t='<span style="word-wrap: break-word">'+a.sanitize(e.toLowerCase())+"</span>"),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;s<a.length;s++)n.unsafe&&a[s].classList.add("unsafe-link"),a[s].classList.contains("deleted-link")||(a[s].title=o)}};n.settings_info.banned_words={type:"button",value:[],category:"Chat",no_bttv:!0,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=[],a=0;a<t.length;a++)t[a]&&n.push(t[a]);1==n.length&&"disable"==n[0]&&(n=[]),this.settings.set("banned_words",n)}}},n.settings_info.keywords={type:"button",value:[],category:"Chat",no_bttv:!0,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=[],a=0;a<t.length;a++)t[a]&&n.push(t[a]);1==n.length&&"disable"==n[0]&&(n=[]),this.settings.set("keywords",n)}}},n.settings_info.fix_color={type:"boolean",value:!0,category:"Chat",no_bttv:!0,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.link_info={type:"boolean",value:!0,category:"Chat",no_bttv:!0,name:"Link Tooltips <span>Beta</span>",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<b.length;y++){var w=b[y];w.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;var a=o._link_data[n];a&&"boolean"!=typeof a&&(this.title=a.tooltip,a.unsafe&&this.classList.add("unsafe-link")),e.preventDefault()}),jQuery(w).tipsy({html:!0})}if(o.settings.link_info){for(var k=a.querySelectorAll("span.message a"),y=0;y<k.length;y++){var w=k[y],F=w.href,E=!1;w.classList.contains("deleted-link")&&(F=w.getAttribute("data-url"),E=!0);var z=o._link_data[F];z?(E||"boolean"==typeof z||(w.title=z.tooltip),z.unsafe&&w.classList.add("unsafe-link")):/^mailto:/.test(F)||(o._link_data[F]=!0,o.ws_send("get_link",F,m.bind(o,F)))}jQuery(k).tipsy({html:!0})}for(var T=a.querySelectorAll("img.emoticon"),y=0;y<T.length;y++){var C=T[y],x=C.alt,L=/\/emoticons\/v1\/(\d+)\/1\.0/.exec(C.src),A=L?parseInt(L[1]):null;if(null!==A){C.setAttribute("srcset",c(A)),C.setAttribute("emote-id",A);var S=o._twitch_emotes[A];S?"string"!=typeof S&&(C.title=S.tooltip):(o._twitch_emotes[A]=C.alt,o.ws_send("twitch_emote",A,h.bind(o,A,C.alt)))}else if(C.getAttribute("data-ffz-emote")){var M=JSON.parse(decodeURIComponent(C.getAttribute("data-ffz-emote"))),A=M&&M[0]||null,D=M&&M[1]||null,B=o.emote_sets[D],N=B?B.emotes[A]:null,R=B?B.title||B.id:"Unknown FFZ Set",O=B&&B.title?"FrankerFaceZ":"FFZ Channel";B&&o.feature_friday&&B.id==o.feature_friday.set&&(R=o.feature_friday.title+" - "+o.feature_friday.display_name),C.title=u({code:N?N.hidden?"???":N.name:x,set:R,set_type:O})}}jQuery(T).tipsy();var P=performance.now()-t;P>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<e.length;s++)e[s]&&(a+=(a?"|":"")+o(e[s]));t=n._regex_cache[e]=new RegExp("(^|.*?"+i+")("+a+")(?=$|"+i+")","ig")}return t},n.prototype._mentionize=function(e,t){var a=this.settings.keywords;if(!a||!a.length)return t;"string"==typeof t&&(t=[t]);for(var o=n._words_to_regex(a),i=[],s=0;s<t.length;s++){var r=t[s];_.isString(r)&&r.match(o)?(r=r.replace(o,function(e,t,n){return i.push(t),i.push({mentionedUser:n,own:!1}),""}),r&&i.push(r)):i.push(r)}return i},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 a=n._words_to_regex(t),o=[],i=0;i<e.length;i++){var s=e[i];o.push(_.isString(s)?s.replace(a,"$1***"):s.emoticonSrc&&a.test(s.altText)?s.altText.replace(a,"$1***"):s.isLink&&a.test(s.href)?{mentionedUser:'</span><a class="deleted-link" title="'+r(s.href.replace(a,"$1***"))+'" data-url="'+r(s.href)+'" href="#">&lt;banned link&gt;</a><span class="mentioning">',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='<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>',r='<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,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<i.length;p++)h.appendChild(d(i[p][0],i[p][1]));t.appendChild(c);var m=document.createElement("button");m.className="unban button glyph-only light",m.innerHTML=r,m.title="(U)nban User",jQuery(m).tipsy(),m.addEventListener("click",u.bind(this,-1));var _=t.querySelector("button.ban");_.setAttribute("title","(B)an User"),jQuery(_).after(m),this.$("button.timeout").remove()}var f=t.querySelector("button.mod");if(f){var g=l.get("cardInfo.isChannelOwner"),v=ffz.get_user();can_op=g||v&&v.is_admin||v&&v.is_staff,can_op||f.parentElement.removeChild(f)}var b=t.querySelector(".interface > 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;n<t.length;n++){var a=t[n];a&&e.room.send("/timeout "+a+" 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 a=t[n];a&&e.room.send("/ban "+a)}},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 a=t[n];a&&e.room.send("/unban "+a)}},n.chat_commands.u.enabled=function(){return this.settings.enhanced_moderation}},{"../utils":28}],9:[function(t){var n=e.FrankerFaceZ,a=/\.([\w\-_]+)\s*?\{content:\s*?"([^"]+)";\s*?background-image:\s*?url\("([^"]+)"\);\s*?height:\s*?(\d+)px;\s*?width:\s*?(\d+)px;\s*?margin:([^;}]+);?([^}]*)\}/gm,o=/[^\n}]*\.badges\s+\.moderator\s*{\s*background-image:\s*url\(\s*['"]([^'"]+)['"][^}]+(?:}|$)/,i=/^_([^_]+)_\d+$/,s=t("../constants"),r=t("../utils"),l=function(e){return e.moderator_badge?'.chat-line[data-room="'+e.id+'"] .badges .moderator:not(.ffz-badge-replacement) { 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__.lookup("controller:room");if(t){var n=t._actions.banUser;t._actions.banUser=function(e){n.bind(this)(e),this.get("model").clearMessages(e.user)}}var a=App.__container__.resolve("model:room");this._modify_room(a);var o=a.instances;for(var i in o)if(o.hasOwnProperty(i)){var s=o[i];this.add_room(s.id,s),this._modify_room(s)}},n.chat_commands={},n.ffz_commands={},n.prototype.room_message=function(e,t){var n=t.split("\n");if(this.has_bttv)for(var a=0;a<n.length;a++)BetterTTV.chat.handlers.onPrivmsg(e.id,{style:"admin",date:new Date,from:"jtv",message:n[a]});else for(var a=0;a<n.length;a++)e.room.addMessage({style:"ffz admin",date:new Date,from:"FFZ",message:n[a]})},n.prototype.run_command=function(e,t){var a=this.rooms[t];if(!a||!a.room)return!1;if(e){var o,i=e.split(" "),s=i.shift().substr(1).toLowerCase(),r=n.chat_commands[s];if(!r)return!1;if(r.hasOwnProperty("enabled")){var l=r.enabled;if("function"==typeof l)try{l=r.enabled.bind(this)(a,i)}catch(c){this.error('command "'+s+'" enabled: '+c),l=!1}if(!l)return!1}this.log("Received Command: "+s,i,!0);try{o=r.bind(this)(a,i)}catch(c){this.error('command "'+s+'" runner: '+c),o="There was an error running the command."}return o&&this.room_message(a,o),!0}},n.prototype.run_ffz_command=function(e,t){var a=this.rooms[t];if(a&&a.room){if(!e){var o=document.querySelector("a.ffz-ui-toggle");if(o)return o.click();e="help"}var i=e.split(" "),s=i.shift().toLowerCase();this.log("Received Command: "+s,i,!0);var r,l=n.ffz_commands[s];if(l)try{r=l.bind(this)(a,i)}catch(c){this.log("Error Running Command - "+s+": "+c,a),r="There was an error running the command."}else r='There is no "'+s+'" command.';r&&this.room_message(a,r)}},n.ffz_commands.help=function(e,t){if(t&&t.length){var a=n.ffz_commands[t[0].toLowerCase()];return a?a.help?a.help:'No help is available for the command "'+t[0]+'".':'There is no "'+t[0]+'" command.'}var o=[];for(var i in n.ffz_commands)n.ffz_commands.hasOwnProperty(i)&&o.push(i);return"The available commands are: "+o.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)&&r.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 a=t.sets[n],o=this.emote_sets[a];o&&(o.users.removeObject(e),o.global||o.users.length||this.unload_set(a))}}},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)&&r.update_css(this._room_style,e,l(n)+(n.css||""));for(var a=0;a<n.sets.length;a++){var o=n.sets[a];this.emote_sets.hasOwnProperty(o)||this.load_set(o)}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{e=_.map(e,n.get_capitalization)}catch(a){t.error("get_suggestions: "+a)}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(a){t.error("send: "+a)}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(a){return 404==a.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,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;u<e.length;u++){var d=e[u];if(d.category)i=d.category,a.push(i),o[i]=[];else{var h=d.chatter.toLowerCase();if(!h)continue;h==l?(a.unshift("Broadcaster"),o.Broadcaster=[h]):o.hasOwnProperty(i)&&o[i].push(h)}}e=[];for(var u=0;u<a.length;u++){var p=a[u],m=o[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")})}},{}],11:[function(t){var n=e.FrankerFaceZ,a=/\.([\w\-_]+)\s*?\{content:\s*?"([^"]+)";\s*?background-image:\s*?url\("([^"]+)"\);\s*?height:\s*?(\d+)px;\s*?width:\s*?(\d+)px;\s*?margin:([^;}]+);?([^}]*)\}/gm,o=/[^\n}]*\.badges\s+\.moderator\s*{\s*background-image:\s*url\(\s*['"]([^'"]+)['"][^}]+(?:}|$)/,i=t("./constants"),s=t("./utils"),r=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",r.bind(this,"global"))},n.prototype.getEmotes=function(e,t){var n=this.users[e],a=this.rooms[t];return _.union(n&&n.sets||[],a&&a.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 a=this.rooms[t.users[n]];a&&a.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 a="";for(var o in n.emotes)if(n.emotes.hasOwnProperty(o)){var i=n.emotes[o];i.klass="ffz-emote-"+i.id,i.regex="!"===i.name[i.name.length-1]?new RegExp("\\b"+i.name+"(?=\\W|$)","g"):new RegExp("\\b"+i.name+"\\b","g"),a+=d(i),n.count++}s.update_css(this._emote_style,e,a+(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(i.SERVER+"channel/"+e+".css",{cache:!1,context:this}).done(function(n){this._legacy_load_css(e,t,n)}).fail(function(a){return 404==a.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 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),'<div class="chat-line'+(e?" highlight":"")+(t?" action":"")+(o?" admin":"")+'" data-sender="'+r.sender+'" data-room="'+a+'">'+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)+"</div>"}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<l.length;c++)l[c]="string"==typeof l[c]?BetterTTV.chat.templates.bttvMessageTokenize(e,l[c]):l[c][0];t=l.join(" ")}return'<span class="message" '+(o?'style="color: '+o+'" ':"")+'data-raw="'+i+'">'+t+"</span>"}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=['<img class="emoticon" src="'+e.url+(e.hidden?"":'" alt="'+e.name+'" title="'+e.name)+'" />'],n=o;if(o=[],!n||!n.length)return o;for(var a=0;a<n.length;a++){var i=n[a];if("string"==typeof i){var s=i.split(e.regex);s.forEach(function(e,n){e&&e.length&&o.push(e),n!==s.length-1&&o.push(t)})}else o.push(i)}}),o):o},this.update_ui_link()}},{}],13:[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,a=App.__container__.lookup("controller:chat"),o=a?a.get("currentRoom.id"):null,i=this.getEmotes(n,o),s=[],r=0;r<i.length;r++){var l=this.emote_sets[i[r]];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?"FrankerFaceZ: "+d:"global"==l.id?"FrankerFaceZ Global Emotes":"globalevent"==l.id?"FrankerFaceZ Event Emotes":this.feature_friday&&l.id==this.feature_friday.set?"FrankerFaceZ "+this.feature_friday.title+": "+this.feature_friday.display_name:"FrankerFaceZ Set: "+t.get_capitalization(l.id),s.push({text:u.name,url:u.url,hidden:!1,channel:d,badge:h})}}}return s}},{}],14:[function(t){t("./shims");var n=e.FrankerFaceZ=function(){n.instance=this,this._log_data=[],this.initialize()};n.get=function(){return n.instance};var a=n.version_info={major:3,minor:3,revision:1,toString:function(){return[a.major,a.minor,a.revision].join(".")+(a.extra||"")}};n.prototype.log=function(e,t,n,a){e="FFZ: "+e+(n?" -- "+JSON.stringify(t):""),this._log_data.push(e+(!n&&a?" -- "+JSON.stringify(t):"")),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:login");return t?t.get("userData"):void 0}},t("./ui/menu"),t("./settings"),t("./socket"),t("./emoticons"),t("./badges"),t("./ember/channel"),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){if(/\/(?:settings|messages?\/)/.test(location.pathname))return void this.setup_normal(n);if(/\/[A-Za-z_-]+\/dashboard/.test(location.pathname)&&!/bookmarks$/.test(location.pathname))return void this.setup_dashboard(n);var a=void 0!=e.App&&void 0!=App.__container__&&void 0!=App.__container__.resolve("model:room");return a?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_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="<span>"+r+"</span>",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 <span>Beta</span>",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;u<o.length;u++){var d=o[u],h=a[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,a=t.type,o=e.name.toLowerCase(),i=t.name.toLowerCase();return a>n?-1:n>a?1:i>o?-1:o>i?1:0});for(var _=0;_<h.length;_++){var i=h[_][0],s=h[_][1],f=document.createElement("p"),g=this.settings.get(i);if(f.className="clearfix",this.has_bttv&&s.no_bttv){var v=document.createElement("span"),b=document.createElement("span");v.className="switch-label",v.innerHTML=s.name,b=document.createElement("span"),b.className="help",b.innerHTML="Disabled due to incompatibility with BetterTTV.",f.classList.add("disabled"),f.appendChild(v),f.appendChild(b)}else{if("boolean"==s.type){var y=document.createElement("a"),v=document.createElement("span");y.className="switch",y.classList.toggle("active",g),y.innerHTML="<span></span>",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;i<o.length;i++){var s=o[i];n.ws_send(s[0],s[1],s[2])}},e.onclose=function(e){n.log("Socket closed. (Code: "+e.code+", Reason: "+e.reason+")"),n._ws_open=!1;for(var a=0;a<t.ws_on_close.length;a++)try{t.ws_on_close[a].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 a,o,i=e.data.indexOf(" "),s=e.data.substr(i+1),r=parseInt(e.data.slice(0,i));if(i=s.indexOf(" "),-1===i&&(i=s.length),a=s.slice(0,i),s=s.substr(i+1),s&&(o=JSON.parse(s)),-1===r){var l=t.ws_commands[a];l?l.bind(n)(o):n.log("Invalid command: "+a,o,!1,!0)}else{var c="True"===a,u=n._ws_callbacks[r];c&&u||n.log("Socket Reply to "+r+" - "+(c?"SUCCESS":"FAIL"),o,!1,!0),u&&(delete n._ws_callbacks[r],u(c,o))}}},t.prototype.ws_send=function(e,t,n,a){if(!this._ws_open){if(a){var o=this._ws_pending=this._ws_pending||[];return o.push([e,t,n]),!0}return!1}var i=++this._ws_last_req;return t=void 0!==t?" "+JSON.stringify(t):"",n&&(this._ws_callbacks[i]=n),this._ws_sock.send(i+" "+e+t),i},t.ws_commands.do_authorize=function(e){var n;for(var a in this.rooms)if(this.rooms.hasOwnProperty(a)){var o=this.rooms[a];if(o&&o.room&&!o.room.get("roomProperties.eventchat")&&!o.room.get("isGroupRoom")&&o.room.tmiRoom){var i=o.room.tmiRoom._getConnection();if(i.isConnected){n=i;break}}}n?n._send("PRIVMSG #frankerfacezauthorizer :AUTH "+e):setTimeout(t.ws_commands.do_authorize.bind(this,e),5e3)}},{}],19:[function(t){var n=e.FrankerFaceZ,a=t("../constants");n.menu_pages.about={name:"About",icon:a.HEART,sort_order:1e5,render:function(e,t){var a=this.rooms[e.get("context.currentRoom.id")],o=!1,i=this;if(a&&a.sets.length)for(var s=0;s<a.sets.length;s++){var r=this.emote_sets[a.sets[s]];if(r&&r.count>0){o=!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=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='<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>',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="<span>"+(a.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(),a=t[1].toLowerCase();return a>n?1:n>a?-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,i,s,l,d)),m.appendChild(_),s.appendChild(m)}this._ui_change_page(e,i,s,l,this._last_page||"channel"),this._popup=o,l.style.maxHeight=Math.max(200,e.$().height()-172)+"px",e.$(".chat-interface").append(o)},n.prototype._ui_change_page=function(e,t,a,o,i){this._last_page=i,o.innerHTML="",o.setAttribute("data-page",i);var s=document.querySelector(".app-main")||document.querySelector(".ember-chat-container");t.style.maxWidth=!n.menu_pages[i].wide||"function"==typeof n.menu_pages[i].wide&&!n.menu_pages[i].wide.bind(this)()?"":(s.offsetWidth<640?s.offsetWidth-40:600)+"px";for(var r=a.querySelectorAll("li.active"),l=0;l<r.length;l++)r[l].classList.remove("active");var c=a.querySelector("#ffz-menu-page-"+i);c?c.classList.add("active"):this.log("No matching page: "+i),n.menu_pages[i].render.bind(this)(e,o)},n.menu_pages.channel={render:function(e,t){var n=e.get("controller.currentRoom.id"),a=this.rooms[n],s=!1;if(this.settings.replace_twitch_menu){var r=a.room.get("product");if(r&&!r.get("error")){s=!0;var l=a.room.get("channel.isSubscribed.content"),c=a.room.get("badgeSet.subscriber.image"),u=document.createElement("div"),d=document.createElement("div"),h=0;l=l&&l.length>0,u.className="emoticon-grid",d.className="heading",c&&(d.style.backgroundImage='url("'+c+'")'),d.innerHTML='<span class="right">Twitch</span>Subscriber Emoticons',u.appendChild(d);for(var p=r.get("emoticons"),m=0;m<p.length;m++){var _=p[m];if("active"===_.state){var f=document.createElement("span"),g=l||!_.subscriber_only,v='image-set(url("'+i+_.id+'/1.0") 1x, url("'+i+_.id+'/2.0") 2x, url("'+i+_.id+'/3.0") 4x)';f.className="emoticon tooltip"+(g?"":" locked"),f.style.backgroundImage='url("'+i+_.id+'/1.0")',f.style.backgroundImage="-webkit-"+v,f.style.backgroundImage="-moz-"+v,f.style.backgroundImage="-ms-"+v,f.style.backgroundImage=v,f.style.width=_.width+"px",f.style.height=_.height+"px",f.title=_.regex,g&&f.addEventListener("click",this._add_emote.bind(this,e,_.regex)),u.appendChild(f),h++}}if(h>0&&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='<span class="subscribe-text">Subscribe</span><span class="subscribe-price">'+r.get("price")+"</span>",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;u<n.length;u++){var d=this.emote_sets[n[u]];if(d&&d.emotes)for(var h in d.emotes)if(d.emotes.hasOwnProperty(h)){var p=d.emotes[h];if(d.emotes.hasOwnProperty(h)&&!p.hidden){r++;var c=document.createElement("span");c.className="emoticon tooltip",c.style.backgroundImage='url("'+p.url+'")',c.style.width=p.width+"px",c.style.height=p.height+"px",c.title=p.name,c.addEventListener("click",this._add_emote.bind(this,t,p.name)),s.appendChild(c)}}}r||(s.innerHTML+="This channel has no emoticons.",s.className="emoticon-grid ffz-no-emotes center"),e.appendChild(s)},n.prototype._add_emote=function(e,t){var n,a,o;this.has_bttv?(n=e.get("element").querySelector("textarea"),a=n.value):(o=e.get("controller.currentRoom"),a=o.get("messageToSend")||""),a+=(a&&" "!==a.substr(-1)?" ":"")+(t.name||t),n?n.value=a:o.set("messageToSend",a)}},{"../constants":3,"../utils":28}],22:[function(t){var n=e.FrankerFaceZ,a=t("../constants");n.prototype.build_ui_link=function(e){var t=document.createElement("a");return t.className="ffz-ui-toggle",t.innerHTML=a.CHAT_BUTTON,t.addEventListener("click",this.build_ui_popup.bind(this,e)),this.update_ui_link(t),t},n.prototype.update_ui_link=function(t){var n=e.App&&App.__container__.lookup("controller:chat");if(t=t||document.querySelector("a.ffz-ui-toggle"),t&&n){var a=n.get("currentRoom.id"),o=this.rooms[a],i=!1,s=this.has_bttv?BetterTTV.settings.get("darkenedMode"):!1,r=this.has_bttv?BetterTTV.settings.get("showBlueButtons"):!1,l=this.feature_friday&&this.feature_friday.live;if(o&&o.sets.length)for(var c=0;c<o.sets.length;c++){var u=this.emote_sets[o.sets[c]];if(u&&u.count>0){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","\\&lt\\;\\]":"<]","\\:-?(S|s)":":-S","\\:-?\\\\":":-\\","\\:\\&gt\\;":":>","B-?\\)":"B-)","\\:-?[z|Z|\\|]":":-Z","\\:-?\\)":":-)","\\:-?\\(":":-(","\\:-?(p|P)":":-P","\\;-?(p|P)":";-P","\\&lt\\;3":"<3","\\:-?[\\\\/]":":-/","\\;-?\\)":";-)","R-?\\)":"R-)","[o|O](_|\\.)[o|O]":"O.o","\\:-?D":":-D","\\:-?(o|O)":":-O","\\&gt\\;\\(":">(","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;o<a[0].length;o++){var r=a[0][o];l._twitch_emote_sets[r]||t.push(r)}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 a=l._twitch_emote_sets[n]=l._twitch_emote_sets[n]||{},o=t.emoticon_sets[n];o.sort(function(e,t){var e=(s[e.code]?"000"+s[e.code]:e.code).toLowerCase(),t=(s[t.code]?"000"+s[t.code]:t.code).toLowerCase();return"000grayface"==e&&(e="grayface"),"000grayface"==t&&(t="grayface"),t>e?-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;c<o.length;c++){var u=o[c];l._twitch_set_to_channel[u]?s(u,l._twitch_set_to_channel[u]):t.push(u)}t.length>0?(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;n<a[0].length;n++){var o=a[0][n];l._twitch_emote_sets[o]&&(t[o]=l._twitch_emote_sets[o])}e(t)},function(){e({})})}).then(function(i){try{if("my_emotes"!=t.getAttribute("data-page"))return;t.innerHTML="";var r=a[1],c=[];for(var u in i)if(i.hasOwnProperty(u)){var d=i[u];d.channel&&d.emotes&&d.emotes.length&&c.push([1,d.channel,d])}for(var h=0;h<r.length;h++){var u=r[h],d=l.emote_sets[u];l.feature_friday&&u==l.feature_friday.set||d.count>0&&c.push([2,d.id,d])}c.sort(function(e,t){if(e[0]<t[0])return-1;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<c.length;h++){var p,m,_,f=2===c[h][0],d=c[h][2],g=document.createElement("div"),v=document.createElement("div"),b=f?"FrankerFaceZ":d.source;if(f){_=[];for(var y in d.emotes){var w=d.emotes[y];w.hidden||_.push({code:w.name,url:w.url,width:w.width,height:w.height})}m="global"===d.id?"Global Emoticons":d.title||d.id,p=d.icon||"http://cdn.frankerfacez.com/channel/global/devicon.png"}else _=d.emotes,m="Twitch Turbo"==d.channel?d.channel:n.get_capitalization(d.channel),p=d.badge;if(_.length){g.className="heading",g.innerHTML='<span class="right">'+b+"</span>"+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 <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 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<e[0].length;o++){var i=e[0][o];this.srl_races[i]=e[1],i==n&&(a=!0)}if(e[1]){var s=e[1],r=s.twitch_entrants={};for(var l in s.entrants)s.entrants.hasOwnProperty(l)&&(s.entrants[l].channel&&(r[s.entrants[l].channel]=l),s.entrants[l].name=l)}a&&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],a=this.settings.srl_races,o=document.querySelector(".stats-and-actions .channel-actions"),i=o.querySelector("#ffz-ui-race");if(!n||!a)return i&&i.parentElement.removeChild(i),void(this._popup&&"ffz-race-popup"==this._popup.id&&(delete this._popup,this._popup_kill&&this._popup_kill(),delete this._popup_kill));if(i)return this._update_race(!0);i=document.createElement("span"),i.setAttribute("data-channel",t),i.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)),i.appendChild(s),o.appendChild(i),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 a=t.querySelector(".button"),o=a.offsetLeft+a.offsetWidth,i=t.getAttribute("data-channel"),s=this.srl_races[i],e=document.createElement("div"),r="";e.id="ffz-race-popup",e.className=(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='<div class="heading"><div></div><span></span></div>',r+='<div class="table" style="max-height:'+h+'px"><table><thead><tr><th>#</th><th>Entrant</th><th>&nbsp;</th><th>Time</th></tr></thead>',r+="<tbody></tbody></table></div>",r+='<div class="divider"></div>',r+='<iframe class="twitter_share_button" style="width:130px; height:25px" src="https://platform.twitter.com/widgets/tweet_button.html?text='+_+"%20Watch%20at&via=Twitch&url=http://www.twitch.tv/"+i+'"></iframe>',r+='<p class="right"><a target="_new" href="http://www.speedrunslive.com/race/?id='+s.id+'">SRL</a>',c&&(r+=' &nbsp; <a target="_new" href="'+l+'">Multitwitch</a>'),r+="</p>",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.name<t.name?-1:e.name>t.name?1:i>o?-1:o>i?1:void 0});for(var f=0;f<p.length;f++){var _=p[f],g='<a target="_new" href="http://www.speedrunslive.com/profiles/#!/'+a.sanitize(_.name)+'">'+_.display_name+"</a>",v=_.channel?'<a target="_new" class="twitch" href="http://www.twitch.tv/'+a.sanitize(_.channel)+'"></a>':"",b=_.hitbox?'<a target="_new" class="hitbox" href="http://www.hitbox.tv/'+a.sanitize(_.hitbox)+'"></a>':"",y=c?a.time_to_string(_.time||c):"",w=a.place_string(_.place),k=_.comment?a.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!=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='<h2 title="'+F+'">'+F+"</h2><b>Goal: </b>"+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;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]},u=/^(\d{4}|\+\d{6})(?:-?(\d{2})(?:-?(\d{2})(?:T(\d{2})(?::?(\d{2})(?::?(\d{2})(?:(?:\.|,)(\d{1,}))?)?)?(Z|([\-+])(\d{2})(?::?(\d{2}))?)?)?)?)?$/,d=function(e){var t=e.match(u);if(!t)return null;var n=Date.UTC(t[1],t[2]-1,t[3],t[4],t[5],t[6],t[7]||0);if(t[9]){var a=6e4*("-"==t[9]?1:-1)*(60*t[10]+1*t[11]);n+=a}return new Date(n)};n.exports={update_css:function(e,t,n){var a=e.innerHTML,o="/*BEGIN "+t+"*/",i="/*END "+t+"*/",s=a.indexOf(o),r=a.indexOf(i),l=-1!==s&&-1!==r&&r>s;(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);