var FFZ = window.FrankerFaceZ, constants = require('./constants'); var sanitize_el = document.createElement('span'), sanitize = function(msg) { sanitize_el.textContent = msg; return sanitize_el.innerHTML; }, escape_regex = RegExp.escape || function(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); }, R_QUOTE = /"/g, R_SQUOTE = /'/g, R_AMP = /&/g, R_LT = //g, DURATIONS = {}, quote_attr = function(msg) { return msg.replace(R_AMP, "&").replace(R_QUOTE, """).replace(R_SQUOTE, "'").replace(R_LT, "<").replace(R_GT, ">"); }, HUMAN_NUMBERS = [ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" ], number_commas = function(x) { var parts = x.toString().split("."); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ","); return parts.join("."); }, pluralize = function(value, singular, plural) { plural = plural || 's'; singular = singular || ''; return value === 1 ? singular : plural; }, place_string = function(num) { if ( num == 1 ) return '1st'; else if ( num == 2 ) return '2nd'; else if ( num == 3 ) return '3rd'; else if ( num == null ) return '---'; return num + "th"; }, date_regex = /^(\d{4}|\+\d{6})(?:-?(\d{2})(?:-?(\d{2})(?:T(\d{2})(?::?(\d{2})(?::?(\d{2})(?:(?:\.|,)(\d{1,}))?)?)?(Z|([\-+])(\d{2})(?::?(\d{2}))?)?)?)?)?$/, parse_date = function(str) { if ( typeof str === "number" ) return new Date(str); var parts = str.match(date_regex); if ( ! parts ) return null; parts[7] = (parts[7] && parts[7].length) ? parts[7].substr(0, 3) : 0; var unix = Date.UTC(parts[1], parts[2] - 1, parts[3], parts[4], parts[5], parts[6], parts[7]); // Check Offset if ( parts[9] ) { var offset = (parts[9] == "-" ? 1 : -1) * 60000 * (60*parts[10] + 1*parts[11]); unix += offset; } return new Date(unix); }, uncompressEmotes = function(value) { var output = {}, emotes = value.split("/"), i = emotes.length; while(i--) { var parts = emotes[i].split(":"); if ( parts.length !== 3 ) return {}; var emote_id = parts[0], length = parseInt(parts[1]), positions = parts[2].split(","), indices = output[emote_id] = output[emote_id] || []; for(var j=0, jl = positions.length; j < jl; j++) { var start = parseInt(positions[j]), end = start + length; for(var x=0, xl = indices.length; x < xl; x++) { if ( start < indices[x][0] ) break; } indices.splice(x, 0, [start, end]); } } return output; }, // This code borrowed from the twemoji project, with tweaks. UFE0Fg = /\uFE0F/g, U200D = String.fromCharCode(0x200D), EMOJI_CODEPOINTS = {}, emoji_to_codepoint = function(surrogates, sep) { if ( EMOJI_CODEPOINTS[surrogates] && EMOJI_CODEPOINTS[surrogates][sep] ) return EMOJI_CODEPOINTS[surrogates][sep]; var input = surrogates.indexOf(U200D) === -1 ? surrogates.replace(UFE0Fg, '') : surrogates, out = [], c = 0, p = 0, i = 0; while (i < input.length) { c = input.charCodeAt(i++); if ( p ) { out.push((0x10000 + ((p - 0xD800) << 10) + (c - 0xDC00)).toString(16)); p = 0; } else if ( 0xD800 <= c && c <= 0xDBFF ) p = c; else out.push(c.toString(16)); } var retval = EMOJI_CODEPOINTS[surrogates] = out.join('-'); return retval; }, codepoint_to_emoji = function(codepoint) { var code = typeof codepoint === 'string' ? parseInt(codepoint, 16) : codepoint; if ( code < 0x10000 ) return String.fromCharCode(code); code -= 0x10000; return String.fromCharCode( 0xD800 + (code >> 10), 0xDC00 + (code & 0x3FF) ) }, // Twitch Emote Helpers SRCSETS = {}, build_srcset = function(id) { if ( SRCSETS[id] ) return SRCSETS[id]; var out = SRCSETS[id] = constants.TWITCH_BASE + id + "/1.0 1x, " + constants.TWITCH_BASE + id + "/2.0 2x"; return out; }, // Twitch API api_call = function(method, url, data, options, token) { options = options || {}; var headers = options.headers = options.headers || {}; headers['Client-ID'] = constants.CLIENT_ID; if ( token ) headers.Authorization = 'OAuth ' + token; return Twitch.api[method].call(this, url, data, options); }, // Dialogs show_modal = function(contents, on_close, width) { var container = document.createElement('div'), subwindow = document.createElement('div'), card = document.createElement('div'), close_button = document.createElement('div'), closer = function() { container.parentElement.removeChild(container) }; container.className = 'twitch_subwindow_container'; container.id = 'ffz-modal-container'; subwindow.className = 'twitch_subwindow ffz-subwindow'; subwindow.style.width = '100%'; subwindow.style.maxWidth = (width||420) + 'px'; card.className = 'card'; close_button.className = 'modal-close-button'; close_button.innerHTML = constants.CLOSE; close_button.addEventListener('click', function() { closer(); if ( on_close ) on_close(false); }); container.appendChild(subwindow); subwindow.appendChild(card); subwindow.appendChild(close_button); card.appendChild(contents); var el = document.querySelector('app-main'); if ( el ) el.parentElement.insertBefore(container, el.nextSibling); else document.body.appendChild(container); return closer; }, ember_lookup = function(thing) { if ( ! window.App ) return; if ( App.__deprecatedInstance__ && App.__deprecatedInstance__.registry && App.__deprecatedInstance__.registry.lookup ) return App.__deprecatedInstance__.registry.lookup(thing); if ( App.__container__ && App.__container__.lookup ) return App.__container__.lookup(thing); }; module.exports = FFZ.utils = { ember_views: function() { return ember_lookup('-view-registry:main') || {}; }, ember_lookup: ember_lookup, ember_resolve: function(thing) { if ( ! window.App ) return; if ( App.__deprecatedInstance__ && App.__deprecatedInstance__.registry && App.__deprecatedInstance__.registry.resolve ) return App.__deprecatedInstance__.registry.resolve(thing); if ( App.__container__ && App.__container__.resolve ) return App.__container__.resolve(thing); }, build_srcset: build_srcset, /*build_tooltip: build_tooltip, load_emote_data: load_emote_data,*/ api: { del: function(u,d,o,t) { return api_call('del', u,d,o,t); }, get: function(u,d,o,t) { return api_call('get', u,d,o,t); }, post: function(u,d,o,t) { return api_call('post', u,d,o,t); }, put: function(u,d,o,t) { return api_call('put', u,d,o,t); } }, show_modal: show_modal, prompt: function(title, description, old_value, callback, width) { var contents = document.createElement('div'), heading = document.createElement('div'), form = document.createElement('form'), input, close_btn, okay_btn; contents.className = 'text-content'; heading.className = 'content-header'; heading.innerHTML = '
' + description + '
' : '') + '