1
0
Fork 0
mirror of https://github.com/FrankerFaceZ/FrankerFaceZ.git synced 2025-06-30 08:08:32 +00:00
FrankerFaceZ/script.min.js

7 lines
226 KiB
JavaScript
Raw Normal View History

!function(t){!function e(t,s,o){function i(a,r){if(!s[a]){if(!t[a]){var d="function"==typeof require&&require;if(!r&&d)return d(a,!0);if(n)return n(a,!0);throw new Error("Cannot find module '"+a+"'")}var u=s[a]={exports:{}};t[a][0].call(u.exports,function(e){var s=t[a][1][e];return i(s?s:e)},u,u.exports,e,t,s,o)}return s[a].exports}for(var n="function"==typeof require&&require,a=0;a<o.length;a++)i(o[a]);return i}({1:[function(e){var s=t.FrankerFaceZ,o=e("./constants"),i=e("./utils");s.settings_info.show_badges={type:"boolean",value:!0,category:"Chat Appearance",name:"Additional Badges",help:"Show additional badges for bots, FrankerFaceZ donors, and other special users."},s.settings_info.transparent_badges={type:"boolean",value:!1,category:"Chat Appearance",no_bttv:!0,name:"Transparent Badges",help:"Make chat badges transparent for a nice, clean look. On light chat, non-subscriber badges are inverted to remain visible.",on_update:function(t){this.has_bttv||document.body.classList.toggle("ffz-transparent-badges",t)}},s.prototype.setup_badges=function(){this.has_bttv||document.body.classList.toggle("ffz-transparent-badges",this.settings.transparent_badges),this.log("Preparing badge system."),this.badges={},this.log("Creating badge style element.");var t=this._badge_style=document.createElement("style");t.id="ffz-badge-css",document.head.appendChild(t),this.log("Adding legacy donor badges."),this._legacy_add_donors()},s.ws_commands.reload_badges=function(){this._legacy_load_bots(),this._legacy_load_donors()},s.ws_commands.set_badge=function(t){var e=t[0],s=t[1],o=t[2],i=this.users[e]=this.users[e]||{},n=i.badges=i.badges||{};void 0===o||null===o?delete n[s]:n[s]=o};var n=function(t){var e=".badges .ffz-badge-"+t.id+" { background-color: "+t.color+'; background-image: url("'+t.image+'"); '+(t.extra_css||"")+"}";return t.transparent_image&&(e+=".ffz-transparent-badges .badges .ffz-badge-"+t.id+' { background-image: url("'+t.transparent_image+'"); }'),e};s.prototype.bttv_badges=function(t){if(this.settings.show_badges){var e=t.sender,s=this.users[e],o=[],i=-1,n=BetterTTV.settings.get("alphaTags");if(s&&s.badges){t.badges||(t.badges=[]);for(var a=0;a<t.badges.length;a++){var r=t.badges[a];if("subscriber"==r.type||"turbo"==r.type){i=a;break}}for(var d in s.badges)if(s.badges.hasOwnProperty(d)){var r=s.badges[d],u=this.badges[r.id]||{},c=r.title||u.title,l="";if(void 0!==u.visible){var h=u.visible;if("function"==typeof h&&(h=h.bind(this)(null,e)),!h)continue}if(u.replaces){for(var f=!1,a=0;a<t.badges.length;a++){var _=t.badges[a];if(_.type===u.replaces_type){_.type="ffz-badge-replacement "+_.type,_.description+=", "+(r.title||u.title)+'" style="background-image: url(&quot;'+(r.image||u.image)+"&quot;)",f=!0;break}}if(f)continue}r.image&&(l+="background-image: url(&quot;"+r.image+"&quot;); "),r.color&&!n&&(l+="background-color: "+r.color+"; "),r.extra_css&&(l+=r.extra_css),l&&(c+='" style="'+l),o.push([(-1==i?1:-1)*d,{type:"ffz-badge-"+r.id+(n?" alpha":""),name:"",description:c}])}if(o.sort(function(t,e){return t[0]-e[0]}),-1==i)for(;o.length;)t.badges.push(o.shift()[1]);else for(;o.length;)t.badges.insertAt(i,o.shift()[1])}}},s.prototype.render_badges=function(t,e){if(!this.settings.show_badges)return e;var s=t.get("msgObject.from"),o=t.get("msgObject.room")||App.__container__.lookup("controller:chat").get("currentRoom.id"),i=this.users[s];if(!i||!i.badges)return e;for(var n in i.badges)if(i.badges.hasOwnProperty(n)){var a=i.badges[n],r=this.badges[a.id]||{},d=e[n];if(void 0!==r.visible){var u=r.visible;if("function"==typeof u&&(u=u.bind(this)(o,s,t,e)),!u)continue}if(d){var c=a.hasOwnProperty("replaces")?a.replaces:r.replaces;if(!c)continue;d.image=a.image||r.image,d.klass+=" ffz-badge-replacement",d.title+=", "+(a.title||r.title)}else e[n]={klass:"ffz-badge-"+a.id,title:a.title||r.title,image:a.image,color:a.color,extra_css:a.extra_css}}return e},s.prototype.render_badge=function(t){if(this.settings.show_badges){var e=t.get("msgObject.from"),s=App.__container__.lookup("controller:chat").get("currentRoom.id"),o=t.$(".badges"),i=
},{}],5:[function(){var e=t.FrankerFaceZ;e.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()}},e.ffz_commands.developer_mode=function(t,e){var s,e=e&&e.length?e[0].toLowerCase():null;return"y"==e||"yes"==e||"true"==e||"on"==e?s=!0:("n"==e||"no"==e||"false"==e||"off"==e)&&(s=!1),void 0===s?"Developer Mode is currently "+(this.settings.developer_mode?"enabled.":"disabled."):(this.settings.set("developer_mode",s),"Developer Mode is now "+(s?"enabled":"disabled")+". Please refresh your browser.")},e.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."},{}],6:[function(e){var s=t.FrankerFaceZ,o=e("../utils"),i=e("../constants");s.prototype.setup_channel=function(){this.log("Creating channel style element.");var t=this._channel_style=document.createElement("style");t.id="ffz-channel-css",document.head.appendChild(t),document.body.classList.toggle("ffz-hide-view-count",!this.settings.channel_views),this.log("Creating channel style element.");var t=this._channel_style=document.createElement("style");t.id="ffz-channel-css",document.head.appendChild(t),this.log("Hooking the Ember Channel Index view.");var e=App.__container__.resolve("view:channel/index"),o=this;if(e){this._modify_cindex(e);try{e.create().destroy()}catch(i){}for(var n in Ember.View.views)if(Ember.View.views.hasOwnProperty(n)){var a=Ember.View.views[n];a instanceof e&&(this.log("Manually updating Channel Index view.",a),this._modify_cindex(a),a.ffzInit())}this.log("Hooking the Ember Channel model."),e=App.__container__.resolve("model:channel"),e&&(e.reopen({ffz_host_target:void 0,setHostMode:function(t){return o.settings.hosted_channels?(this.set("ffz_host_target",t.target),this._super(t)):(this.set("ffz_host_target",void 0),this._super({target:void 0,delay:0}))}}),this.log("Hooking the Ember Channel controller."),e=App.__container__.lookup("controller:channel"),e&&(e.reopen({ffzUpdateUptime:function(){o._cindex&&o._cindex.ffzUpdateUptime()}.observes("isLive","content.id"),ffzUpdateInfo:function(){this._ffz_update_timer&&clearTimeout(this._ffz_update_timer),this.get("content.id")&&(this._ffz_update_timer=setTimeout(this.ffzCheckUpdate.bind(this),6e4))}.observes("content.id"),ffzCheckUpdate:function(){var t=this,e=t.get("content.id");e&&Twitch.api&&Twitch.api.get("streams/"+e,{},{version:3}).done(function(e){if(!e||!e.stream)return t.set("stream.created_at",null),void t.set("stream.viewers",0);t.set("stream.created_at",e.stream.created_at||null),t.set("stream.viewers",e.stream.viewers||0);var s=e.stream.game||e.stream.channel&&e.stream.channel.game;s&&(t.set("game",s),t.set("rollbackData.game",s)),e.stream.channel&&(e.stream.channel.status&&t.set("status",e.stream.channel.status),e.stream.channel.views&&t.set("views",e.stream.channel.views),e.stream.channel.followers&&t.get("content.followers.isLoaded")&&t.set("content.followers.total",e.stream.channel.followers))}).always(function(){t.ffzUpdateInfo()})},ffzUpdateTitle:function(){var t=this.get("content.name"),e=this.get("content.display_name");e&&(s.capitalization[t]=[e,Date.now()]),o._cindex&&o._cindex.ffzFixTitle()}.observes("content.status","content.id"),ffzHostTarget:function(){var t=this.get("content.hostModeTarget"),e=t&&t.get("name"),i=t&&t.get("id"),n=t&&t.get("display_name");i!==o.__old_host_target&&(o.__old_host_target&&o.ws_send("unsub_channel",o.__old_host_target),i?(o.ws_send("sub_channel",i),o.__old_host_target=i):delete o.__old_host_target),n&&(s.capitalization[e]=[n,Date.now()]),o.settings.group_tabs&&o._chatv&&o._chatv.ffzRebuildTabs(),o.settings.follow_buttons&&o
if(n){var r=o.format_unread(t===i?0:n.room.get("unreadCount"));a.querySelector("span").innerHTML=r}}}}},ffzBuildTab:function(t,n,a,r){{var d,u,c=document.createElement("span"),l="",h=n.get("id"),f=n.get("isGroupRoom"),_=n===t.get("controller.currentRoom");_||-1!==e.settings.visible_rooms.indexOf(h)}return c.setAttribute("data-room",n.id),c.className="ffz-chat-tab tooltip",c.classList.toggle("current-channel",a),c.classList.toggle("host-channel",r),c.classList.toggle("group-chat",f),c.classList.toggle("active",_),u=o.format_unread(_?0:n.get("unreadCount")),d=n.get("tmiRoom.displayName")||(f?n.get("tmiRoom.name"):s.get_capitalization(n.get("id"),function(t){u=o.format_unread(_?0:n.get("unreadCount")),c.innerHTML=l+o.sanitize(t)+"<span>"+u+"</span>"})),a?(l=i.CAMERA,c.title="Current Channel"):r?(l=i.EYE,c.title="Hosted Channel"):c.title=f?"Group Chat":"Pinned Channel",c.innerHTML=l+o.sanitize(d)+"<span>"+u+"</span>",c.addEventListener("click",function(){var e=t.get("controller");e.focusRoom(n),e.set("showList",!1)}),n._ffz_tab=c,c},ffzDisableTabs:function(){this._ffz_tabs&&(this._ffz_tabs.parentElement.removeChild(this._ffz_tabs),delete this._ffz_tabs,delete this._ffz_invite),this._ffz_host&&(-1===e.settings.pinned_rooms.indexOf(this._ffz_host)&&this._ffz_host_room&&(this.get("controller.currentRoom")===this._ffz_host_room&&this.get("controller").blurRoom(),this._ffz_host_room.destroy()),delete this._ffz_host,delete this._ffz_host_room),this.$(".chat-room").css("top",""),this.$(".chat-header").removeClass("hidden")}})},s.prototype.connect_extra_chat=function(){var t=this.get_user();if(t&&t.login&&(!this.rooms[t.login]||this.rooms[t.login].room)){var e=App.__container__.resolve("model:room");e&&e.findOne(t.login)}if(!this.has_bttv){for(var s=0;s<this.settings.pinned_rooms.length;s++)this._join_room(this.settings.pinned_rooms[s],!0);this._chatv&&(!this.has_bttv&&this.settings.group_tabs&&this._chatv.ffzRebuildTabs(),this._chatv.ffzRebuildMenu())}},s.prototype._join_room=function(t,e){var s=!1;if(-1===this.settings.pinned_rooms.indexOf(t)&&(this.settings.pinned_rooms.push(t),this.settings.set("pinned_rooms",this.settings.pinned_rooms),s=!0),this.rooms[t]&&this.rooms[t].room)return s&&!e&&!this.has_bttv&&this._chatv&&this.settings.group_tabs&&this._chatv.ffzRebuildTabs(),s;{var o=App.__container__.resolve("model:room");o&&o.findOne(t)}return!e&&!this.has_bttv&&this._chatv&&this.settings.group_tabs&&this._chatv.ffzRebuildTabs(),!e&&this._chatv&&this._chatv.ffzRebuildMenu(),s},s.prototype._leave_room=function(t,e){var s=!1;if(-1!==this.settings.pinned_rooms.indexOf(t)&&(this.settings.pinned_rooms.removeObject(t),this.settings.set("pinned_rooms",this.settings.pinned_rooms),s=!0),!this.rooms[t]||!this.rooms[t].room)return s;var o=App.__container__.lookup("controller:chat"),i=this.rooms[t].room,n=this.get_user();return!o||o.get("currentChannelRoom.id")===t||this._chatv&&this._chatv._ffz_host===t?s:(o.get("currentRoom.id")===t&&o.blurRoom(),n&&n.login===t||i.destroy(),!e&&!this.has_bttv&&this._chatv&&this.settings.group_tabs&&this._chatv.ffzRebuildTabs(),!e&&this._chatv&&this._chatv.ffzRebuildMenu(),s)},s.chat_commands.join=function(t,e){if(!e||!e.length||e.length>1)return"Join Usage: /join <channel>";var s=e[0].toLowerCase();return"#"===s.charAt(0)&&(s=s.substr(1)),this._join_room(s)?"Joining "+s+". You will always connect to this channel's chat unless you later /part from it.":"You have already joined "+s+'. Please use "/part '+s+'" to leave it.'},s.chat_commands.part=function(t,e){if(!e||!e.length||e.length>1)return"Part Usage: /part <channel>";var s=e[0].toLowerCase();return"#"===s.charAt(0)&&(s=s.substr(1)),this._leave_room(s)?"Leaving "+s+".":this.rooms[s]?"You do not have "+s+" pinned and you cannot leave the current channel or hosted channels via /part.":"You are not in "+s+"."}},{"../constants":4,"../utils":34}],9:[function(){var e=t.FrankerFaceZ;e.settings_info.swap_sidebars={type:"boolean",value:!1,category:"Appearance",no_mobile:!0,no_bttv:!0,name:"Swap Sidebar Positions",help:"Swap the positions of the left and right si
}),didInsertElement:function(){this._super(),t._card=this;try{if(u.has_bttv)return;var e,o=this.get("element"),l=this.get("controller"),h=l.get("cardInfo.user.id"),f=u.aliases[h];if(f){var m=o.querySelector("h3.name"),p=m&&m.querySelector("a");p&&(m=p),m&&(m.classList.add("ffz-alias"),m.title=i.sanitize(l.get("cardInfo.user.display_name")||h.capitalize()),jQuery(m).tipsy())}if(o.classList.add("ffz-moderation-card"),u.settings.mod_card_info){var g=document.createElement("div"),v=o.querySelector("h3.name");v&&(o.classList.add("ffz-has-info"),g.className="info channel-stats",v.parentElement.insertBefore(g,v.nextSibling),this.ffzRebuildInfo())}if(u.settings.mod_card_buttons&&u.settings.mod_card_buttons.length){e=document.createElement("div"),e.className="extra-interface interface clearfix";for(var b={},y=function(t){var e=l.get("cardInfo.user.id"),s=App.__container__.lookup("controller:chat"),o=s&&s.get("currentRoom");o&&o.send(t.replace(/{user}/g,e))},w=function(t){var e=document.createElement("button"),s=t.split(" ",1)[0],o=b[s]>1?t.split(" ",b[s]):[s];return/^[!~./]/.test(o[0])&&(o[0]=o[0].substr(1)),o=_.map(o,function(t){return t.capitalize()}).join(" "),e.className="button",e.innerHTML=i.sanitize(o),e.title=i.sanitize(t.replace(/{user}/g,l.get("cardInfo.user.id")||"{user}")),jQuery(e).tipsy(),e.addEventListener("click",y.bind(this,t)),e},b={},z=0;z<u.settings.mod_card_buttons.length;z++)b[u.settings.mod_card_buttons[z].split(" ",1)[0]]=(b[u.settings.mod_card_buttons[z].split(" ",1)[0]]||0)+1;for(var z=0;z<u.settings.mod_card_buttons.length;z++){var k=u.settings.mod_card_buttons[z],C=k.indexOf("{user}");-1===C&&(k+=" {user}"),e.appendChild(w(k))}o.appendChild(e)}if(o.setAttribute("tabindex",1),u.settings.mod_card_hotkeys&&(o.classList.add("no-mousetrap"),o.addEventListener("keyup",function(t){var e=t.keyCode||t.which,s=l.get("cardInfo.user.id"),o=l.get("cardInfo.isModeratorOrHigher"),i=App.__container__.lookup("controller:chat").get("currentRoom");if(o&&e==a.P)i.send("/timeout "+s+" 1");else if(o&&e==a.B)i.send("/ban "+s);else if(o&&e==a.T)i.send("/timeout "+s+" 600");else if(o&&e==a.U)i.send("/unban "+s);else if(e!=a.ESC)return;l.send("close")})),l.get("cardInfo.isModeratorOrHigher")){o.classList.add("ffz-is-mod"),u.settings.mod_card_hotkeys&&(o.classList.add("no-mousetrap"),o.addEventListener("keyup",function(t){var e=t.keyCode||t.which,s=l.get("cardInfo.user.id"),o=App.__container__.lookup("controller:chat").get("currentRoom");if(e==a.P)o.send("/timeout "+s+" 1");else if(e==a.B)o.send("/ban "+s);else if(e==a.T)o.send("/timeout "+s+" 600");else if(e==a.U)o.send("/unban "+s);else if(e!=a.ESC)return;l.send("close")}));var E=function(t){var e=l.get("cardInfo.user.id"),s=App.__container__.lookup("controller:chat").get("currentRoom");s.send(-1===t?"/unban "+e:"/timeout "+e+" "+t)},x=function(t){var e=document.createElement("button");return e.className="button",e.innerHTML=c(t),e.title="Timeout User for "+i.number_commas(t)+" Second"+(1!=t?"s":""),u.settings.mod_card_hotkeys&&600===t?e.title="(T)"+e.title.substr(1):u.settings.mod_card_hotkeys&&1===t&&(e.title="(P)urge - "+e.title),jQuery(e).tipsy(),e.addEventListener("click",E.bind(this,t)),e};if(u.settings.mod_card_durations&&u.settings.mod_card_durations.length){e=document.createElement("div"),e.className="extra-interface interface clearfix",e.appendChild(x(1));var T=document.createElement("span");T.className="right",e.appendChild(T);for(var z=0;z<u.settings.mod_card_durations.length;z++)T.appendChild(x(u.settings.mod_card_durations[z]));o.appendChild(e),this.$("button.timeout").remove()}var L=o.querySelector("button.ban");u.settings.mod_card_hotkeys&&L.setAttribute("title","(B)an User");var M=document.createElement("button");M.className="unban button glyph-only light",M.innerHTML=d,M.title=(u.settings.mod_card_hotkeys?"(U)":"U")+"nban User",jQuery(M).tipsy(),M.addEventListener("click",E.bind(this,-1)),jQuery(L).after(M)}var S=o.querySelector("button.mod");if(S){var A=l.get("cardInfo.isChannelOwner"),F=ffz.get_user();can_op=A||F&&F.is_admin||F&&F.is_staff,can_op||S.parent
o[t]=(o[t]||0)+(s||1),this._emote_report_scheduled||(this._emote_report_scheduled=setTimeout(this._report_emotes.bind(this),3e4))},s.prototype._report_emotes=function(){this._emote_report_scheduled&&delete this._emote_report_scheduled;var t=this.emote_usage;this.emote_usage={},this.ws_send("emoticon_uses",[t],function(){},!0)},s.prototype.check_twitch_emotes=function(){this._twitch_emote_check&&(clearTimeout(this._twitch_emote_check),delete this._twitch_emote_check);var t;if(this.rooms)for(var e in this.rooms)if(this.rooms.hasOwnProperty(e)){t=this.rooms[e];break}if(!t||!t.room||!t.room.tmiSession)return void(this._twitch_emote_check=setTimeout(this.check_twitch_emotes.bind(this),1e4));var s=t.room.tmiSession._emotesParser,o=Object.keys(s.emoticonRegexToIds).length;if(!(o>0)){var i=s.emoticonSetIds;s.emoticonSetIds="",s.updateEmoticons(i),this._twitch_emote_check=setTimeout(this.check_twitch_emotes.bind(this),1e4)}},s.prototype.getEmotes=function(t,e){var s=this.users&&this.users[t],o=this.rooms&&this.rooms[e];return _.union(s&&s.sets||[],o&&o.set&&[o.set]||[],o&&o.extra_sets||[],this.default_sets)},s.ws_commands.reload_set=function(t){this.emote_sets.hasOwnProperty(t)&&this.load_set(t)},s.ws_commands.load_set=function(t){this.load_set(t)},s.prototype._emote_tooltip=function(t){if(!t)return null;if(t._tooltip)return t._tooltip;var e=this.emote_sets[t.set_id],s=t.owner,o=e&&e.title||"Global";return t._tooltip="Emoticon: "+(t.hidden?"???":t.name)+"\nFFZ "+o+(s?"\nBy: "+s.display_name:""),t._tooltip},s.prototype.load_emoji_data=function(t,e){var s=this;jQuery.getJSON(o.SERVER+"emoji/emoji.json").done(function(e){var i={},n={};for(var a in e){var r=e[a];a=a.toLowerCase(),r.code=a,i[a]=r,n[r.short_name]=a,r.raw=_.map(r.code.split("-"),d).join(""),r.src=o.SERVER+"emoji/"+a+"-1x.png",r.srcSet=r.src+" 1x, "+o.SERVER+"emoji/"+a+"-2x.png 2x, "+o.SERVER+"emoji/"+a+"-4x.png 4x",r.token={srcSet:r.srcSet,emoticonSrc:r.src,ffzEmoji:a,altText:r.raw}}s.emoji_data=i,s.emoji_names=n,s.log("Loaded data on "+Object.keys(i).length+" emoji."),"function"==typeof t&&t(!0,e)}).fail(function(o){return 404===o.status?"function"==typeof t&&t(!1):(e=(e||0)+1,50>e?s.load_emoji(t,e):"function"==typeof t&&t(!1))})},s.prototype.load_global_sets=function(t,e){var s=this;jQuery.getJSON(((e||0)%2===0?o.API_SERVER:o.API_SERVER_2)+"v1/set/global").done(function(t){s.default_sets=t.default_sets;var e=s.global_sets=[],o=t.sets||{};s.feature_friday&&s.feature_friday.set&&(-1===s.global_sets.indexOf(s.feature_friday.set)&&s.global_sets.push(s.feature_friday.set),-1===s.default_sets.indexOf(s.feature_friday.set)&&s.default_sets.push(s.feature_friday.set));for(var i in o)if(o.hasOwnProperty(i)){var n=o[i];e.push(i),s._load_set_json(i,void 0,n)}}).fail(function(o){return 404==o.status?"function"==typeof t&&t(!1):(e=e||0,e++,50>e?s.load_global_sets(t,e):"function"==typeof t&&t(!1))})},s.prototype.load_set=function(t,e,s){var i=this;jQuery.getJSON(((s||0)%2===0?o.API_SERVER:o.API_SERVER_2)+"v1/set/"+t).done(function(s){i._load_set_json(t,e,s&&s.set)}).fail(function(o){return 404==o.status?"function"==typeof e&&e(!1):(s=s||0,s++,10>s?i.load_set(t,e,s):"function"==typeof e&&e(!1))})},s.prototype.unload_set=function(t){var e=this.emote_sets[t];e&&(this.log("Unloading emoticons for set: "+t),i.update_css(this._emote_style,t,null),delete this.emote_sets[t])},s.prototype._load_set_json=function(t,e,s){if(!s)return"function"==typeof e&&e(!1);var o=this.emote_sets[t]&&this.emote_sets[t].users||[];this.emote_sets[t]=s,s.users=o,s.count=0;var n="",a=s.emoticons;s.emoticons={};for(var d=0;d<a.length;d++){var u=a[d];u.klass="ffz-emote-"+u.id,u.set_id=t,u.srcSet=u.urls[1]+" 1x",u.urls[2]&&(u.srcSet+=", "+u.urls[2]+" 2x"),u.urls[4]&&(u.srcSet+=", "+u.urls[4]+" 4x"),u.regex="!"===u.name[u.name.length-1]?new RegExp("(^|\\W|\\b)("+u.name+")(?=\\W|$)","g"):new RegExp("(^|\\W|\\b)("+u.name+")\\b","g"),n+=r(u),s.count++,s.emoticons[u.id]=u}i.update_css(this._emote_style,t,n+(s.css||"")),this.log("Updated emoticons for set #"+t+": "+s.title,s),this._cindex&&this._cindex.ffzFixTitle(),thi
}e+="</tbody></table><hr>Total: "+i.number_commas(s.total);var a=i.parse_date(s.fetched);if(a){var r=Math.floor((a.getTime()-Date.now())/1e3);r>60&&(e+="<br><small>Data was cached "+i.time_to_string(r)+" ago.</small>")}}else if("twitch"==s.type){e="<b>Twitch: "+i.sanitize(s.display_name)+"</b><hr>";var d=i.parse_date(s.since);d&&(e+="Member Since: "+i.date_string(d)+"<br>"),e+="<nobr>Views: "+i.number_commas(s.views)+"</nobr> | <nobr>Followers: "+i.number_commas(s.followers)+"</nobr>"}else if("twitch_vod"==s.type)e="<b>Twitch "+("highlight"==s.broadcast_type?"Highlight":"Broadcast")+": "+i.sanitize(s.title)+"</b><hr>",e+="By: "+i.sanitize(s.display_name)+(s.game?" | Playing: "+i.sanitize(s.game):" | Not Playing")+"<br>",e+="Views: "+i.number_commas(s.views)+" | "+i.time_to_string(s.length);else if("twitter"==s.type)e="<b>Tweet By: "+i.sanitize(s.user)+"</b><hr>",e+=i.sanitize(s.tweet);else if("reputation"==s.type){if(e=this.settings.link_image_hover&&is_image(s.full||t,this.settings.image_hover_all_domains)?image_iframe(s.full||t):"",e+='<span style="word-wrap: break-word">'+i.sanitize(s.full.toLowerCase())+"</span>",s.trust<50||s.safety<50||s.tags&&s.tags.length>0){e+="<hr>";var u=!1;(s.trust<50||s.safety<50)&&(s.unsafe=!0,e+="<b>Potentially Unsafe Link</b><br>",e+="Trust: "+s.trust+"% | Child Safety: "+s.safety+"%",u=!0),s.tags&&s.tags.length>0&&(e+=(u?"<br>":"")+"Tags: "+s.tags.join(", ")),e+="<br>Data Source: WOT"}}else s.full&&(e=this.settings.link_image_hover&&is_image(s.full||t,this.settings.image_hover_all_domains)?image_iframe(s.full||t):"",e+='<span style="word-wrap: break-word">'+i.sanitize(s.full.toLowerCase())+"</span>");return e||(e='<span style="word-wrap: break-word">'+i.sanitize(t.toLowerCase())+"</span>"),s.tooltip=e,e},load_link_data=function(t,e,s){if(e){this._link_data[t]=s,s.unsafe=!1;var o,i=build_link_tooltip.bind(this)(t),n="/"==t.charAt(t.length-1)?t.substr(0,t.length-1):null;if(o=document.querySelectorAll(n?'span.message a[href="'+t+'"], span.message a[href="'+n+'"], span.message a[data-url="'+t+'"], span.message a[data-url="'+n+'"]':'span.message a[href="'+t+'"], span.message a[data-url="'+t+'"]'),this.settings.link_info)for(var a=0;a<o.length;a++)s.unsafe&&o[a].classList.add("unsafe-link"),o[a].classList.contains("deleted-link")||(o[a].title=i)}},o.SRC_IDS={},o.src_to_id=function(t){if(o.SRC_IDS.hasOwnProperty(t))return o.SRC_IDS[t];var e=/\/emoticons\/v1\/(\d+)\/1\.0/.exec(t),s=e?parseInt(e[1]):null;return 0/0===s&&(s=null),o.SRC_IDS[t]=s,s};var d=new Date(0).toLocaleTimeString().toUpperCase();o.settings_info.twenty_four_timestamps={type:"boolean",value:-1===d.lastIndexOf("PM")&&-1===d.lastIndexOf("AM"),category:"Chat Appearance",no_bttv:!0,name:"24hr Timestamps",help:"Display timestamps in chat in the 24 hour format rather than 12 hour."},o.settings_info.show_deleted_links={type:"boolean",value:!1,category:"Chat Moderation",no_bttv:!0,name:"Show Deleted Links",help:"Do not delete links based on room settings or link length."},o.prototype.setup_tokenization=function(){if(s=t.require&&t.require("ember-twitch-chat/helpers/chat-line-helpers"),!s)return this.log("Unable to get chat helper functions.");this.log("Hooking Ember chat line helpers.");var e=this;s.getTime=function(t){if(void 0===t||null===t)return"?:??";var s=t.getHours(),o=t.getMinutes();return s>12&&!e.settings.twenty_four_timestamps?s-=12:0!==s||e.settings.twenty_four_timestamps||(s=12),s+":"+(10>o?"0":"")+o},s.linkifyMessage=function(t,s){var o=e.settings.show_deleted_links;return _.chain(t).map(function(t){if(!_.isString(t))return t;var e=t.match(LINK);return e&&e.length?_.zip(t.split(LINK),_.map(e,function(t){var e=t.length>255;return o||!s&&!e?{isLink:!0,href:t}:{isLink:!0,isDeleted:!0,isLong:e,href:t}})):[t]}).flatten().compact().value()}},o.prototype.tokenize_chat_line=function(e,i,n){if(e.cachedTokens)return e.cachedTokens;var a=e.message,r=this.get_user(),d=e.room,u=r&&e.from===r.login,c=e.tags&&e.tags.emotes,l=[a];if(s&&s.linkifyMessage){var h=a.labels||[],f=-1!==h.indexOf("owner")||-1!==h.indexOf("staff")||-1!==h.indexOf
}this._ui_change_page(t,n,r,u,this._last_page||"channel"),this._popup=i,u.style.maxHeight=Math.max(200,t.$().height()-172)+"px",t.$(".chat-interface").append(i)},s.prototype._ui_change_page=function(t,e,o,i,n){this._last_page=n,i.innerHTML="",i.setAttribute("data-page",n);var a=document.querySelector(".app-main")||document.querySelector(".ember-chat-container");e.style.maxWidth=!s.menu_pages[n].wide||"function"==typeof s.menu_pages[n].wide&&!s.menu_pages[n].wide.bind(this)()?"":(a.offsetWidth<640?a.offsetWidth-40:600)+"px";for(var r=o.querySelectorAll("li.active"),d=0;d<r.length;d++)r[d].classList.remove("active");var u=o.querySelector("#ffz-menu-page-"+n);u?u.classList.add("active"):this.log("No matching page: "+n),s.menu_pages[n].render.bind(this)(t,i,e,o);var c=this;setTimeout(function(){c._fix_menu_position()})},s.menu_pages.channel={render:function(t,e){var o=t.get("controller.currentRoom.id"),a=this.rooms[o],r=!1;if(this.settings.replace_twitch_menu){var d=a.room.get("product");if(d&&!d.get("error")){r=!0;var u=App.__container__.resolve("model:ticket").find("user",{channel:o}),c=u?u.get("content"):!1,l=u?u.get("isLoaded"):!1,h=a.room.get("badgeSet.subscriber.image"),f=document.createElement("div"),_=document.createElement("div"),m=0;if(c=c&&c.length>0,u&&!c&&!l){var p=this;u.addObserver("isLoaded",function(){setTimeout(function(){"channel"===e.getAttribute("data-page")&&(e.innerHTML="",s.menu_pages.channel.render.bind(p)(t,e))},0)}),u.load()}f.className="emoticon-grid",_.className="heading",h&&(_.style.backgroundImage='url("'+h+'")'),_.innerHTML='<span class="right">Twitch</span>Subscriber Emoticons',f.appendChild(_);for(var g=d.get("emoticons")||[],v=0;v<g.length;v++){var b=g[v];if("active"===b.state){var y=document.createElement("span"),w=c||!b.subscriber_only,z='image-set(url("'+n+b.id+'/1.0") 1x, url("'+n+b.id+'/2.0") 2x, url("'+n+b.id+'/3.0") 4x)';y.className="emoticon tooltip"+(w?"":" locked"),y.style.backgroundImage='url("'+n+b.id+'/1.0")',y.style.backgroundImage="-webkit-"+z,y.style.backgroundImage="-moz-"+z,y.style.backgroundImage="-ms-"+z,y.style.backgroundImage=z,y.style.width=b.width+"px",y.style.height=b.height+"px",y.title=b.regex,w&&y.addEventListener("click",this._add_emote.bind(this,t,b.regex)),f.appendChild(y),m++}}if(m>0&&e.appendChild(f),m>0&&!c){var k=document.createElement("div"),C=document.createElement("div"),E=document.createElement("span"),x=document.createElement("a");k.className="subscribe-message",C.className="non-subscriber-message",k.appendChild(C),E.className="unlock-text",E.innerHTML="Subscribe to unlock Emoticons",C.appendChild(E),x.className="action subscribe-button button primary",x.href=d.get("product_url"),x.innerHTML='<span class="subscribe-text">Subscribe</span><span class="subscribe-price">'+d.get("price")+"</span>",C.appendChild(x),e.appendChild(k)}else if(m>0){var T=u.get("content");if(T=T.length>0?T[T.length-1]:void 0,T&&T.purchase_profile&&!T.purchase_profile.will_renew){var L=i.parse_date(T.access_end||"");k=document.createElement("div"),C=document.createElement("div"),E=document.createElement("span"),end_time=L?Math.floor((L.getTime()-Date.now())/1e3):null,k.className="subscribe-message",C.className="non-subscriber-message",k.appendChild(C),E.className="unlock-text",E.innerHTML="Subscription expires in "+i.time_to_string(end_time,!0,!0),C.appendChild(E),e.appendChild(k)}}}}var M=a&&a.extra_sets||[];this._emotes_for_sets(e,t,a&&a.set&&[a.set]||[],this.feature_friday||r||M.length?"Channel Emoticons":null,"http://cdn.frankerfacez.com/script/devicon.png","FrankerFaceZ");for(var v=0;v<M.length;v++){var S=this.emote_sets[M[v]],A=S?"Featured "+S.title:"Featured Channel";this._emotes_for_sets(e,t,[M[v]],A,"http://cdn.frankerfacez.com/script/devicon.png","FrankerFaceZ")}this._feature_friday_ui(o,e,t)},name:"Channel",icon:o.ZREKNARF},s.prototype._emotes_for_sets=function(t,e,s,o,i,n){var a=document.createElement("div"),r=0;if(a.className="emoticon-grid",null!=o){var d=document.createElement("div");if(d.className="heading",n){var u=document.createElement("span");u.className="rig