From 89573b8d4884076e1c4a85d11ceec1b001bc7cac Mon Sep 17 00:00:00 2001 From: Zack Rauen Date: Tue, 18 Jun 2019 22:28:48 -0400 Subject: [PATCH] fixes #212, fixes #210, fixes #187 --- .eslintrc | 4 +- js/main.js | 169 +++++++++++++++++++++++++++++++--------------- js/main.min.js | 4 +- package-lock.json | 41 ++++++++--- 4 files changed, 151 insertions(+), 67 deletions(-) diff --git a/.eslintrc b/.eslintrc index 20410b7a..d8916aec 100644 --- a/.eslintrc +++ b/.eslintrc @@ -38,6 +38,8 @@ "_bdhash": true, "ace": false, "Reflect": false, - "DiscordNative": false + "DiscordNative": false, + "self": "off", + "name": "off" } } \ No newline at end of file diff --git a/js/main.js b/js/main.js index e14b89b6..6168e1ee 100644 --- a/js/main.js +++ b/js/main.js @@ -328,8 +328,6 @@ Core.prototype.init = async function() { if (settingsCookie["bda-dc-0"]) document.querySelector(".btn.btn-disconnect").click(); }); - publicServersModule.initialize(); - emoteModule.autoCapitalize(); Utils.log("Startup", "Removing Loading Icon"); @@ -829,25 +827,26 @@ EmoteModule.prototype.isCacheValid = function() { }; EmoteModule.prototype.loadEmoteData = async function(emoteInfo) { - const _fs = require("fs"); + const fs = require("fs"); const emoteFile = "emote_data.json"; const file = bdConfig.dataPath + emoteFile; - const exists = _fs.existsSync(file); + const exists = await new Promise(r => fs.exists(file, r)); if (exists && this.isCacheValid()) { if (settingsCookie["fork-ps-2"]) mainCore.showToast("Loading emotes from cache.", {type: "info"}); Utils.log("Emotes", "Loading emotes from local cache."); const data = await new Promise(resolve => { - _fs.readFile(file, "utf8", (err, data) => { - Utils.log("Emotes", "Emotes loaded from cache."); + fs.readFile(file, "utf8", (err, data) => { + Utils.log("Emotes", "Emote file read."); if (err) data = {}; resolve(data); }); }); - let isValid = Utils.testJSON(data); - if (isValid) window.bdEmotes = JSON.parse(data); + const parsed = Utils.testJSON(data); + let isValid = !!parsed; + if (isValid) window.bdEmotes = parsed; for (const e in emoteInfo) { isValid = Object.keys(window.bdEmotes[emoteInfo[e].variable]).length > 0; @@ -859,7 +858,7 @@ EmoteModule.prototype.loadEmoteData = async function(emoteInfo) { } Utils.log("Emotes", "Cache was corrupt, downloading..."); - _fs.unlinkSync(file); + await new Promise(r => fs.unlink(file, r)); } if (!settingsCookie["fork-es-3"]) return; @@ -873,7 +872,7 @@ EmoteModule.prototype.loadEmoteData = async function(emoteInfo) { if (settingsCookie["fork-ps-2"]) mainCore.showToast("All emotes successfully downloaded.", {type: "success"}); - try { _fs.writeFileSync(file, JSON.stringify(window.bdEmotes), "utf8"); } + try { await new Promise(r => fs.writeFile(file, JSON.stringify(window.bdEmotes), "utf8", r)); } catch (err) { Utils.err("Emotes", "Could not save emote data.", err); } }; @@ -881,13 +880,14 @@ EmoteModule.prototype.downloadEmotes = function(emoteMeta) { let request = require("request"); let options = { url: emoteMeta.url, - timeout: emoteMeta.timeout ? emoteMeta.timeout : 5000 + timeout: emoteMeta.timeout ? emoteMeta.timeout : 5000, + json: true }; Utils.log("Emotes", `Downloading: ${emoteMeta.variable} (${emoteMeta.url})`); return new Promise((resolve, reject) => { - request(options, (error, response, body) => { + request(options, (error, response, parsedData) => { if (error) { Utils.err("Emotes", "Could not download " + emoteMeta.variable, error); if (emoteMeta.backup) { @@ -899,20 +899,6 @@ EmoteModule.prototype.downloadEmotes = function(emoteMeta) { return reject({}); } - let parsedData = {}; - try { - parsedData = JSON.parse(body); - } - catch (err) { - Utils.err("Emotes", "Could not download " + emoteMeta.variable, err); - if (emoteMeta.backup) { - emoteMeta.url = emoteMeta.backup; - emoteMeta.backup = null; - if (emoteMeta.backupParser) emoteMeta.parser = emoteMeta.backupParser; - return resolve(this.downloadEmotes(emoteMeta)); - } - return reject({}); - } if (typeof(emoteMeta.parser) === "function") parsedData = emoteMeta.parser(parsedData); for (let emote in parsedData) { @@ -1209,7 +1195,7 @@ var Utils = class { } static escapeID(id) { - return id.replace(/^[^a-z]+|[^\w-]+/gi, ""); + return id.replace(/^[^a-z]+|[^\w-]+/gi, "-"); } static log(moduleName, message) { @@ -1235,14 +1221,23 @@ var Utils = class { static testJSON(data) { try { - JSON.parse(data); - return true; + return JSON.parse(data); } catch (err) { return false; } } + static isEmpty(obj) { + if (obj == null || obj == undefined || obj == "") return true; + if (typeof(obj) !== "object") return false; + if (Array.isArray(obj)) return obj.length == 0; + for (const key in obj) { + if (obj.hasOwnProperty(key)) return false; + } + return true; + } + static suppressErrors(method, message) { return (...params) => { try { return method(...params); } @@ -1359,7 +1354,8 @@ var ContentManager = (() => { } const originalJSRequire = Module._extensions[".js"]; const originalCSSRequire = Module._extensions[".css"] ? Module._extensions[".css"] : () => {return null;}; - + const splitRegex = /[^\S\r\n]*?\n[^\S\r\n]*?\*[^\S\r\n]?/; + const escapedAtRegex = /^\\@/; return new class ContentManager { @@ -1413,15 +1409,47 @@ var ContentManager = (() => { } extractMeta(content) { + const firstLine = content.split("\n")[0]; + const hasOldMeta = firstLine.includes("//META"); + if (hasOldMeta) return this.parseOldMeta(content); + const hasNewMeta = firstLine.includes("/**"); + if (hasNewMeta) return this.parseNewMeta(content); + throw new MetaError("META was not found."); + } + + parseOldMeta(content) { const meta = content.split("\n")[0]; const rawMeta = meta.substring(meta.lastIndexOf("//META") + 6, meta.lastIndexOf("*//")); if (meta.indexOf("META") < 0) throw new MetaError("META was not found."); - if (!Utils.testJSON(rawMeta)) throw new MetaError("META could not be parsed."); - - const parsed = JSON.parse(rawMeta); + const parsed = Utils.testJSON(rawMeta); + if (!parsed) throw new MetaError("META could not be parsed."); if (!parsed.name) throw new MetaError("META missing name data."); return parsed; } + + parseNewMeta(content) { + const block = content.split("/**", 2)[1].split("*/", 1)[0]; + const out = {}; + let field = ""; + let accum = ""; + for (const line of block.split(splitRegex)) { + if (line.length === 0) continue; + if (line.charAt(0) === "@" && line.charAt(1) !== " ") { + out[field] = accum; + const l = line.indexOf(" "); + field = line.substr(1, l - 1); + accum = line.substr(l + 1); + } + else { + accum += " " + line.replace("\\n", "\n").replace(escapedAtRegex, "@"); + } + } + out[field] = accum.trim(); + delete out[""]; + return out; + } + + getContentRequire(type) { const isPlugin = type === "plugin"; @@ -1441,7 +1469,16 @@ var ContentManager = (() => { content = `module.exports = ${JSON.stringify(meta)};`; } if (isPlugin) { - content += `\nmodule.exports = ${JSON.stringify(meta)};\nmodule.exports.type = ${meta.name};`; + module._compile(content, module.filename); + const didExport = !Utils.isEmpty(module.exports); + if (didExport) { + meta.type = module.exports; + module.exports = meta; + content = ""; + } + else { + content += `\nmodule.exports = ${JSON.stringify(meta)};\nmodule.exports.type = ${meta.exports || meta.name};`; + } } module._compile(content, filename); }; @@ -1469,6 +1506,7 @@ var ContentManager = (() => { try {require(path.resolve(baseFolder, filename));} catch (error) {return {name: filename, file: filename, message: "Could not be compiled.", error: {message: error.message, stack: error.stack}};} const content = require(path.resolve(baseFolder, filename)); + content.id = Utils.escapeID(content.name); if (isPlugin) { if (!content.type) return; try { @@ -1600,7 +1638,7 @@ PluginModule.prototype.startPlugin = function(plugin, reload = false) { if (settingsCookie["fork-ps-2"] && !reload) mainCore.showToast(`${bdplugins[plugin].plugin.getName()} v${bdplugins[plugin].plugin.getVersion()} could not be started.`, {type: "error"}); pluginCookie[plugin] = false; this.savePluginData(); - Utils.err("Plugins", name + " could not be started.", err); + Utils.err("Plugins", plugin + " could not be started.", err); } }; @@ -1758,9 +1796,9 @@ ThemeModule.prototype.loadThemes = function () { var themes = Object.keys(bdthemes); for (var i = 0; i < themes.length; i++) { - var name = bdthemes[themes[i]].name; - if (!themeCookie[name]) themeCookie[name] = false; - if (themeCookie[name]) $("head").append($(""),$("#customcss").text(this.editor.session.getValue()).detach().appendTo(document.head)}saveCss(){DataStore.setBDData("bdcustomcss",btoa(this.editor.session.getValue()))}}class V2C_CssEditor extends BDV2.reactComponent{constructor(e){super(e);let t=this;t.props.lines=0,t.setInitialState(),t.attach=t.attach.bind(t),t.detachedEditor=BDV2.react.createElement(V2C_CssEditorDetached,{attach:t.attach}),t.onClick=t.onClick.bind(t),t.updateCss=t.updateCss.bind(t),t.saveCss=t.saveCss.bind(t),t.detach=t.detach.bind(t)}setInitialState(){this.state={detached:this.props.detached||BDV2.editorDetached}}componentDidMount(){this.editor=ace.edit("bd-customcss-editor"),this.editor.setTheme("ace/theme/monokai"),this.editor.session.setMode("ace/mode/css"),this.editor.setShowPrintMargin(!1),this.editor.setFontSize(14),this.editor.on("change",()=>{settingsCookie["bda-css-0"]&&(this.saveCss(),this.updateCss())})}componentWillUnmount(){this.editor.destroy()}componentDidUpdate(e,t){let a=this;t.detached&&!a.state.detached&&BDV2.reactDom.unmountComponentAtNode(a.detachedRoot)}codeMirror(){}get options(){return{lineNumbers:!0,mode:"css",indentUnit:4,theme:"material",scrollbarStyle:"simple"}}get css(){let e=DataStore.getBDData("bdcustomcss"),t="";return e&&""!==e&&(t=atob(e)),t}updateLineCount(){let e=this.refs.editor.value.split("\n").length;e==this.props.lines||(this.refs.lines.textContent=Array.from(Array(e),(e,t)=>t+1).join(".\n")+".",this.props.lines=e)}render(){let e=this,{detached:t}=e.state;return BDV2.react.createElement("div",{className:"contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default",style:{padding:"60px 40px 0px"}},t&&BDV2.react.createElement("div",{id:"editor-detached"},BDV2.react.createElement(V2Components.SettingsTitle,{text:"Custom CSS Editor"}),BDV2.react.createElement("h3",null,"Editor Detached"),BDV2.react.createElement("button",{className:"btn btn-primary",onClick:()=>{e.attach()}},"Attach")),!t&&BDV2.react.createElement("div",null,BDV2.react.createElement(V2Components.SettingsTitle,{text:"Custom CSS Editor"}),BDV2.react.createElement("div",{className:"editor-wrapper"},BDV2.react.createElement("div",{id:"bd-customcss-editor",className:"editor",ref:"editor"},e.css)),BDV2.react.createElement("div",{id:"bd-customcss-attach-controls"},BDV2.react.createElement("ul",{className:"checkbox-group"},BDV2.react.createElement(V2Components.Checkbox,{id:"live-update",text:"Live Update",onChange:this.onChange,checked:settingsCookie["bda-css-0"]})),BDV2.react.createElement("div",{id:"bd-customcss-detach-controls-button"},BDV2.react.createElement("button",{style:{borderRadius:"3px 0 0 3px",borderRight:"1px solid #3f4146"},className:"btn btn-primary",onClick:()=>{e.onClick("update")}},"Update"),BDV2.react.createElement("button",{style:{borderRadius:"0",borderLeft:"1px solid #2d2d2d",borderRight:"1px solid #2d2d2d"},className:"btn btn-primary",onClick:()=>{e.onClick("save")}},"Save"),BDV2.react.createElement("button",{style:{borderRadius:"0 3px 3px 0",borderLeft:"1px solid #3f4146"},className:"btn btn-primary",onClick:()=>{e.onClick("detach")}},"Detach"),BDV2.react.createElement("span",{style:{fontSize:"10px",marginLeft:"5px"}},"Unsaved changes are lost on detach"),BDV2.react.createElement("div",{className:"help-text"},"Press ",BDV2.react.createElement("code",{className:"inline"},"ctrl"),"+",BDV2.react.createElement("span",{className:"inline"},",")," with the editor focused to access the editor's settings.")))))}onClick(e){let t=this;"update"===e?t.updateCss():"save"===e?t.saveCss():"detach"===e?t.detach():void 0}onChange(e,t){"live-update"===e?(settingsCookie["bda-css-0"]=t,mainCore.saveSettings()):void 0}updateCss(){0==$("#customcss").length&&$("head").append(""),$("#customcss").text(this.editor.session.getValue()).detach().appendTo(document.head)}saveCss(){DataStore.setBDData("bdcustomcss",btoa(this.editor.session.getValue()))}detach(){let e=this;e.setState({detached:!0});let t=e.detachedRoot;return t?void BDV2.reactDom.render(e.detachedEditor,t):void console.log("FAILED TO INJECT ROOT: .app")}get detachedRoot(){let e=$("#bd-customcss-detach-container");return e.length?e[0]:this.injectDetachedRoot()?this.detachedRoot:null}injectDetachedRoot(){return!!$(".app, .app-2rEoOp").length&&($("
",{id:"bd-customcss-detach-container"}).insertAfter($(".app, .app-2rEoOp")),!0)}attach(){let e=this;e.setState({detached:!1})}}class V2C_List extends BDV2.reactComponent{constructor(e){super(e)}render(){return BDV2.react.createElement("ul",{className:this.props.className},this.props.children)}}class V2C_ContentColumn extends BDV2.reactComponent{constructor(e){super(e)}render(){return BDV2.react.createElement("div",{className:"contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default"},BDV2.react.createElement("h2",{className:"ui-form-title h2 margin-reset margin-bottom-20"},this.props.title),this.props.children)}}class V2C_PluginCard extends BDV2.reactComponent{constructor(e){super(e);let t=this;t.onChange=t.onChange.bind(t),t.showSettings=t.showSettings.bind(t),t.setInitialState(),t.hasSettings="function"==typeof t.props.plugin.getSettingsPanel,t.settingsPanel="",this.reload=this.reload.bind(this),this.onReload=this.onReload.bind(this)}setInitialState(){this.state={checked:pluginCookie[this.props.plugin.getName()],settings:!1,reloads:0}}onReload(e){e!==this.props.plugin.getName()||this.setState({reloads:this.state.reloads+1})}componentDidUpdate(){if(this.state.settings){if("object"==typeof this.settingsPanel&&this.refs.settingspanel.appendChild(this.settingsPanel),!settingsCookie["fork-ps-3"])return;var e=(e,t)=>{let a=e.scrollTop,n=a+e.clientHeight,o=t.offsetTop,s=o+t.clientHeight;return on};let t=$(BDV2.reactDom.findDOMNode(this)),a=t.parents(".scroller");if(!e(a[0],t[0]))return;a.animate({scrollTop:t.offset().top-a.offset().top+a.scrollTop()-30},300)}}reload(){const e=this.props.plugin.getName();pluginModule.reloadPlugin(e),this.props.plugin=bdplugins[e].plugin,this.onReload(this.props.plugin.getName())}getString(e){return"string"==typeof e?e:e.toString()}render(){let e=this,{plugin:t}=this.props,a=this.getString(t.getName()),n=this.getString(t.getAuthor()),o=this.getString(t.getDescription()),s=this.getString(t.getVersion()),r=bdplugins[a].website,i=bdplugins[a].source;if(this.state.settings){try{e.settingsPanel=t.getSettingsPanel()}catch(e){Utils.err("Plugins","Unable to get settings panel for "+t.getName()+".",e)}return BDV2.react.createElement("li",{className:"settings-open ui-switch-item"},BDV2.react.createElement("div",{style:{float:"right",cursor:"pointer"},onClick:()=>{this.refs.settingspanel.innerHTML="",e.setState({settings:!1})}},BDV2.react.createElement(V2Components.XSvg,null)),"object"==typeof e.settingsPanel&&BDV2.react.createElement("div",{id:`plugin-settings-${a}`,className:"plugin-settings",ref:"settingspanel"}),"object"!=typeof e.settingsPanel&&BDV2.react.createElement("div",{id:`plugin-settings-${a}`,className:"plugin-settings",ref:"settingspanel",dangerouslySetInnerHTML:{__html:e.settingsPanel}}))}return BDV2.react.createElement("li",{"data-name":a,"data-version":s,className:"settings-closed ui-switch-item"},BDV2.react.createElement("div",{className:"bda-header"},BDV2.react.createElement("span",{className:"bda-header-title"},BDV2.react.createElement("span",{className:"bda-name"},a)," v",BDV2.react.createElement("span",{className:"bda-version"},s)," by ",BDV2.react.createElement("span",{className:"bda-author"},n)),BDV2.react.createElement("div",{className:"bda-controls"},!settingsCookie["fork-ps-5"]&&BDV2.react.createElement(V2Components.TooltipWrap(V2Components.ReloadIcon,{color:"black",side:"top",text:"Reload"}),{className:"bd-reload-card",onClick:this.reload}),BDV2.react.createElement("label",{className:"ui-switch-wrapper ui-flex-child",style:{flex:"0 0 auto"}},BDV2.react.createElement("input",{checked:this.state.checked,onChange:this.onChange,className:"ui-switch-checkbox",type:"checkbox"}),BDV2.react.createElement("div",{className:this.state.checked?"ui-switch checked":"ui-switch"})))),BDV2.react.createElement("div",{className:"bda-description-wrap scroller-wrap fade"},BDV2.react.createElement("div",{className:"bda-description scroller"},o)),(r||i||this.hasSettings)&&BDV2.react.createElement("div",{className:"bda-footer"},BDV2.react.createElement("span",{className:"bda-links"},r&&BDV2.react.createElement("a",{className:"bda-link bda-link-website",href:r,target:"_blank"},"Website"),r&&i&&" | ",i&&BDV2.react.createElement("a",{className:"bda-link bda-link-source",href:i,target:"_blank"},"Source")),this.hasSettings&&BDV2.react.createElement("button",{onClick:this.showSettings,className:"bda-settings-button",disabled:!this.state.checked},"Settings")))}onChange(){this.setState({checked:!this.state.checked}),pluginModule.togglePlugin(this.props.plugin.getName())}showSettings(){this.hasSettings&&this.setState({settings:!0})}}class V2C_ThemeCard extends BDV2.reactComponent{constructor(e){super(e),this.setInitialState(),this.onChange=this.onChange.bind(this),this.reload=this.reload.bind(this)}setInitialState(){this.state={checked:themeCookie[this.props.theme.name],reloads:0}}onReload(e){e!==this.props.theme.name||this.setState({reloads:this.state.reloads+1})}reload(){const e=this.props.theme.name,t=themeModule.reloadTheme(e);t?mainCore.showToast(`Could not reload ${bdthemes[e].name}. Check console for details.`,{type:"error"}):mainCore.showToast(`${bdthemes[e].name} v${bdthemes[e].version} has been reloaded.`,{type:"success"}),this.props.theme=bdthemes[e],this.onReload(this.props.theme.name)}render(){let{theme:e}=this.props,t=e.name,a=e.description,n=e.version,o=e.author,s=bdthemes[t].website,r=bdthemes[t].source;return BDV2.react.createElement("li",{"data-name":t,"data-version":n,className:"settings-closed ui-switch-item"},BDV2.react.createElement("div",{className:"bda-header"},BDV2.react.createElement("span",{className:"bda-header-title"},BDV2.react.createElement("span",{className:"bda-name"},t)," v",BDV2.react.createElement("span",{className:"bda-version"},n)," by ",BDV2.react.createElement("span",{className:"bda-author"},o)),BDV2.react.createElement("div",{className:"bda-controls"},!settingsCookie["fork-ps-5"]&&BDV2.react.createElement(V2Components.TooltipWrap(V2Components.ReloadIcon,{color:"black",side:"top",text:"Reload"}),{className:"bd-reload-card",onClick:this.reload}),BDV2.react.createElement("label",{className:"ui-switch-wrapper ui-flex-child",style:{flex:"0 0 auto"}},BDV2.react.createElement("input",{checked:this.state.checked,onChange:this.onChange,className:"ui-switch-checkbox",type:"checkbox"}),BDV2.react.createElement("div",{className:this.state.checked?"ui-switch checked":"ui-switch"})))),BDV2.react.createElement("div",{className:"bda-description-wrap scroller-wrap fade"},BDV2.react.createElement("div",{className:"bda-description scroller"},a)),(s||r)&&BDV2.react.createElement("div",{className:"bda-footer"},BDV2.react.createElement("span",{className:"bda-links"},s&&BDV2.react.createElement("a",{className:"bda-link",href:s,target:"_blank"},"Website"),s&&r&&" | ",r&&BDV2.react.createElement("a",{className:"bda-link",href:r,target:"_blank"},"Source"))))}onChange(){this.setState({checked:!this.state.checked}),themeModule.toggleTheme(this.props.theme.name)}}class V2Cs_TabBar{static get Item(){return V2C_TabBarItem}static get Header(){return V2C_TabBarHeader}static get Separator(){return V2C_TabBarSeparator}}class V2Components{static get SettingsGroup(){return V2C_SettingsGroup}static get SectionedSettingsPanel(){return V2C_SectionedSettingsPanel}static get SettingsPanel(){return V2C_SettingsPanel}static get Switch(){return V2C_Switch}static get Scroller(){return V2C_Scroller}static get TabBar(){return V2Cs_TabBar}static get SideBar(){return V2C_SideBar}static get Tools(){return V2C_Tools}static get SettingsTitle(){return V2C_SettingsTitle}static get CssEditor(){return V2C_CssEditor}static get Checkbox(){return V2C_Checkbox}static get List(){return V2C_List}static get PluginCard(){return V2C_PluginCard}static get ThemeCard(){return V2C_ThemeCard}static get ContentColumn(){return V2C_ContentColumn}static get ReloadIcon(){return V2C_ReloadIcon}static get XSvg(){return V2C_XSvg}static get Layer(){return V2C_Layer}static get SidebarView(){return V2C_SidebarView}static get ServerCard(){return V2C_ServerCard}static TooltipWrap(e,t){const{style:a="black",side:n="top",text:o=""}=t,s=BDV2.KeyGenerator();return class extends BDV2.reactComponent{constructor(e){super(e),this.onMouseEnter=this.onMouseEnter.bind(this),this.onMouseLeave=this.onMouseLeave.bind(this)}componentDidMount(){this.node=BDV2.reactDom.findDOMNode(this),this.node.addEventListener("mouseenter",this.onMouseEnter),this.node.addEventListener("mouseleave",this.onMouseLeave)}componentWillUnmount(){this.node.removeEventListener("mouseenter",this.onMouseEnter),this.node.removeEventListener("mouseleave",this.onMouseLeave)}onMouseEnter(){if(!BDV2.Tooltips)return;const{left:e,top:t,width:r,height:i}=this.node.getBoundingClientRect();BDV2.Tooltips.show(s,{position:n,text:o,color:a,targetWidth:r,targetHeight:i,windowWidth:Utils.screenWidth,windowHeight:Utils.screenHeight,x:e,y:t});const l=new MutationObserver(e=>{e.forEach(e=>{const t=Array.from(e.removedNodes),a=-1e.contains(this.node));(a||n)&&(this.onMouseLeave(),l.disconnect())})});l.observe(document.body,{subtree:!0,childList:!0})}onMouseLeave(){BDV2.Tooltips&&BDV2.Tooltips.hide(s)}render(){return BDV2.react.createElement(e,this.props)}}}}class V2_SettingsPanel_Sidebar{constructor(e){this.onClick=e}get items(){return[{text:"Settings",id:"core"},{text:"Emotes",id:"emotes"},{text:"Plugins",id:"plugins"},{text:"Themes",id:"themes"},{text:"Custom CSS",id:"customcss"}]}get component(){return BDV2.react.createElement("span",null,BDV2.react.createElement(V2Components.SideBar,{onClick:this.onClick,headerText:"Bandaged BD",items:this.items}),BDV2.react.createElement("div",{style:{fontSize:"12px",fontWeight:"600",color:"#72767d",padding:"2px 10px"}},`BD v${bdConfig.version} by `,BDV2.react.createElement("a",{href:"https://github.com/Jiiks/",target:"_blank"},"Jiiks")),BDV2.react.createElement("div",{style:{fontSize:"12px",fontWeight:"600",color:"#72767d",padding:"2px 10px"}},`BBD v${bbdVersion} by `,BDV2.react.createElement("a",{href:"https://github.com/rauenzi/",target:"_blank"},"Zerebos")))}get root(){let e=$("#bd-settings-sidebar");return e.length?e[0]:this.injectRoot()?this.root:null}injectRoot(){let e=$("[class*='side-'] > [class*='item-']:not([class*=Danger])").last();return!!e.length&&($("",{id:"bd-settings-sidebar"}).insertBefore(e.prev()),!0)}render(){let e=this.root;return e?void(BDV2.reactDom.render(this.component,e),Utils.onRemoved(e,()=>{BDV2.reactDom.unmountComponentAtNode(e)})):void console.log("FAILED TO LOCATE ROOT: [class*='side-'] > [class*='item-']:not([class*=Danger])")}}class V2_SettingsPanel{constructor(){let e=this;e.sideBarOnClick=e.sideBarOnClick.bind(e),e.onChange=e.onChange.bind(e),e.updateSettings=this.updateSettings.bind(e),e.sidebar=new V2_SettingsPanel_Sidebar(e.sideBarOnClick)}get root(){let e=$("#bd-settingspane-container");return e.length?e[0]:this.injectRoot()?this.root:null}injectRoot(){if(!$(".layer-3QrUeG .standardSidebarView-3F1I7i, .layer-3QrUeG .ui-standard-sidebar-view").length)return!1;const e=$("
",{class:"contentRegion-3nDuYy content-region",id:"bd-settingspane-container"});return $(".layer-3QrUeG .standardSidebarView-3F1I7i, .layer-3QrUeG .ui-standard-sidebar-view").append(e),Utils.onRemoved(e[0],()=>{BDV2.reactDom.unmountComponentAtNode(e[0])}),!0}get coreSettings(){const e=this.getSettings("core"),t=[...new Set(e.map(e=>e.category))],a=t.map(t=>({title:t,settings:e.filter(e=>e.category==t)}));return a}get emoteSettings(){return this.getSettings("emote")}getSettings(e){return Object.keys(settings).reduce((t,a)=>{let n=settings[a];return n.cat===e&&n.implemented&&!n.hidden&&(n.text=a,t.push(n)),t},[])}sideBarOnClick(e){let t=this;$(".contentRegion-3nDuYy, .content-region").first().hide(),$(t.root).show();"core"===e?t.renderCoreSettings():"emotes"===e?t.renderEmoteSettings():"customcss"===e?t.renderCustomCssEditor():"plugins"===e?t.renderPluginPane():"themes"===e?t.renderThemePane():void 0}onClick(){}onChange(e,t){this.updateSettings(e,t)}updateSettings(e,t){settingsCookie[e]=t,"bda-es-0"==e&&(t?$("#twitchcord-button-container").show():$("#twitchcord-button-container").hide()),"bda-gs-2"==e&&(t?$("body").addClass("bd-minimal"):$("body").removeClass("bd-minimal")),"bda-gs-3"==e&&(t?$("body").addClass("bd-minimal-chan"):$("body").removeClass("bd-minimal-chan")),"bda-gs-1"==e&&(t?$("#bd-pub-li").show():$("#bd-pub-li").hide()),"bda-gs-4"==e&&(t?voiceMode.enable():voiceMode.disable()),"bda-gs-5"==e&&(t?$("#app-mount").addClass("bda-dark"):$("#app-mount").removeClass("bda-dark")),t&&"bda-gs-6"==e&&mainCore.inject24Hour(),"bda-gs-7"==e&&(t?mainCore.injectColoredText():mainCore.removeColoredText()),"bda-es-4"==e&&(t?emoteModule.autoCapitalize():emoteModule.disableAutoCapitalize()),"fork-ps-4"==e&&(t?ClassNormalizer.start():ClassNormalizer.stop()),"fork-ps-5"==e&&(t?(ContentManager.watchContent("plugin"),ContentManager.watchContent("theme")):(ContentManager.unwatchContent("plugin"),ContentManager.unwatchContent("theme"))),"fork-wp-1"==e&&(BdApi.setWindowPreference("transparent",t),t?BdApi.setWindowPreference("backgroundColor",null):BdApi.setWindowPreference("backgroundColor","#2f3136")),"bda-gs-8"==e&&(t?dMode.enable(settingsCookie["fork-dm-1"]):dMode.disable()),mainCore.saveSettings()}initializeSettings(){settingsCookie["bda-es-0"]&&$("#twitchcord-button-container").show(),settingsCookie["bda-gs-2"]&&$("body").addClass("bd-minimal"),settingsCookie["bda-gs-3"]&&$("body").addClass("bd-minimal-chan"),settingsCookie["bda-gs-1"]&&$("#bd-pub-li").show(),settingsCookie["bda-gs-4"]&&voiceMode.enable(),settingsCookie["bda-gs-5"]&&$("#app-mount").addClass("bda-dark"),settingsCookie["bda-gs-6"]&&mainCore.inject24Hour(),settingsCookie["bda-gs-7"]&&mainCore.injectColoredText(),settingsCookie["bda-es-4"]&&emoteModule.autoCapitalize(),settingsCookie["fork-ps-4"]&&ClassNormalizer.start(),settingsCookie["fork-ps-5"]&&(ContentManager.watchContent("plugin"),ContentManager.watchContent("theme")),settingsCookie["bda-gs-8"]&&dMode.enable(settingsCookie["fork-dm-1"]),mainCore.saveSettings()}renderSidebar(){let e=this;$("[class*='side-'] > [class*='item-']").off("click.v2settingspanel").on("click.v2settingspanel",()=>{BDV2.reactDom.unmountComponentAtNode(e.root),$(e.root).hide(),$(".contentRegion-3nDuYy, .content-region").first().show()}),e.sidebar.render()}get coreComponent(){return BDV2.react.createElement(V2Components.Scroller,{contentColumn:!0,fade:!0,dark:!0,children:[BDV2.react.createElement(V2Components.SectionedSettingsPanel,{key:"cspanel",onChange:this.onChange,sections:this.coreSettings}),BDV2.react.createElement(V2Components.Tools,{key:"tools"})]})}get emoteComponent(){return BDV2.react.createElement(V2Components.Scroller,{contentColumn:!0,fade:!0,dark:!0,children:[BDV2.react.createElement(V2Components.SettingsPanel,{key:"espanel",title:"Emote Settings",onChange:this.onChange,settings:this.emoteSettings,button:{title:"Clear Emote Cache",onClick:()=>{emoteModule.clearEmoteData(),emoteModule.init(),quickEmoteMenu.init()}}}),BDV2.react.createElement(V2Components.Tools,{key:"tools"})]})}get customCssComponent(){return BDV2.react.createElement(V2Components.Scroller,{contentColumn:!0,fade:!0,dark:!0,children:[BDV2.react.createElement(V2Components.CssEditor,{key:"csseditor"}),BDV2.react.createElement(V2Components.Tools,{key:"tools"})]})}contentComponent(e){const t="plugins"==e?this.pluginsComponent:this.themesComponent,a=e.replace("s",""),n=this;class ContentList extends BDV2.react.Component{constructor(e){super(e),this.onChange=this.onChange.bind(this)}componentDidMount(){BDEvents.on(`${a}-reloaded`,this.onChange),BDEvents.on(`${a}-loaded`,this.onChange),BDEvents.on(`${a}-unloaded`,this.onChange)}componentWillUnmount(){BDEvents.off(`${a}-reloaded`,this.onChange),BDEvents.off(`${a}-loaded`,this.onChange),BDEvents.off(`${a}-unloaded`,this.onChange)}onChange(){n.sideBarOnClick(e)}render(){return t}}return BDV2.react.createElement(ContentList)}get pluginsComponent(){let e=Object.keys(bdplugins).sort((e,t)=>e.toLowerCase().localeCompare(t.toLowerCase())).reduce((e,t)=>(e.push(BDV2.react.createElement(V2Components.PluginCard,{key:t,plugin:bdplugins[t].plugin})),e),[]),t=BDV2.react.createElement(V2Components.List,{key:"plugin-list",className:"bda-slist",children:e}),a=!settingsCookie["fork-ps-5"]&&BDV2.react.createElement(V2Components.TooltipWrap(V2Components.ReloadIcon,{color:"black",side:"top",text:"Reload Plugin List"}),{className:"bd-reload-header",size:"18px",onClick:async()=>{pluginModule.updatePluginList(),this.sideBarOnClick("plugins")}}),n=BDV2.react.createElement("button",{key:"folder-button",className:"bd-pfbtn",onClick:()=>{require("electron").shell.openItem(ContentManager.pluginsFolder)}},"Open Plugin Folder"),o=BDV2.react.createElement(V2Components.ContentColumn,{key:"pcolumn",title:"Plugins",children:[a,n,t]});return BDV2.react.createElement(V2Components.Scroller,{contentColumn:!0,fade:!0,dark:!0,children:[o,BDV2.react.createElement(V2Components.Tools,{key:"tools"})]})}get themesComponent(){let e=Object.keys(bdthemes).sort((e,t)=>e.toLowerCase().localeCompare(t.toLowerCase())).reduce((e,t)=>(e.push(BDV2.react.createElement(V2Components.ThemeCard,{key:t,theme:bdthemes[t]})),e),[]),t=BDV2.react.createElement(V2Components.List,{key:"theme-list",className:"bda-slist",children:e}),a=!settingsCookie["fork-ps-5"]&&BDV2.react.createElement(V2Components.TooltipWrap(V2Components.ReloadIcon,{color:"black",side:"top",text:"Reload Theme List"}),{className:"bd-reload-header",size:"18px",onClick:async()=>{themeModule.updateThemeList(),this.sideBarOnClick("themes")}}),n=BDV2.react.createElement("button",{key:"folder-button",className:"bd-pfbtn",onClick:()=>{require("electron").shell.openItem(ContentManager.themesFolder)}},"Open Theme Folder"),o=BDV2.react.createElement(V2Components.ContentColumn,{key:"tcolumn",title:"Themes",children:[a,n,t]});return BDV2.react.createElement(V2Components.Scroller,{contentColumn:!0,fade:!0,dark:!0,children:[o,BDV2.react.createElement(V2Components.Tools,{key:"tools"})]})}renderCoreSettings(){let e=this.root;return e?void BDV2.reactDom.render(this.coreComponent,e):void console.log("FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i")}renderEmoteSettings(){let e=this.root;return e?void BDV2.reactDom.render(this.emoteComponent,e):void console.log("FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i")}renderCustomCssEditor(){let e=this.root;return e?void BDV2.reactDom.render(this.customCssComponent,e):void console.log("FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i")}renderPluginPane(){let e=this.root;return e?void BDV2.reactDom.render(this.contentComponent("plugins"),e):void console.log("FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i")}renderThemePane(){let e=this.root;return e?void BDV2.reactDom.render(this.contentComponent("themes"),e):void console.log("FAILED TO LOCATE ROOT: .layer-3QrUeG .standardSidebarView-3F1I7i")}}class V2C_Layer extends BDV2.reactComponent{constructor(e){super(e)}componentDidMount(){$(window).on(`keyup.${this.props.id}`,t=>{27===t.which&&BDV2.reactDom.unmountComponentAtNode(this.refs.root.parentNode)}),$(`#${this.props.id}`).animate({opacity:1},{step:function(e){$(this).css("transform",`scale(${1.1-.1*e}) translateZ(0px)`)},duration:200,done:()=>{$(`#${this.props.id}`).css("opacity","").css("transform","")}})}componentWillUnmount(){$(window).off(`keyup.${this.props.id}`),$(`#${this.props.id}`).animate({opacity:0},{step:function(e){$(this).css("transform",`scale(${1.1-.1*e}) translateZ(0px)`)},duration:200,done:()=>{$(`#${this.props.rootId}`).remove()}}),$("[class*=\"layer-\"]").removeClass("publicServersOpen").animate({opacity:1},{step:function(e){$(this).css("transform",`scale(${.07*e+.93}) translateZ(0px)`)},duration:200,done:()=>{$("[class*=\"layer-\"]").css("opacity","").css("transform","")}})}componentWillMount(){$("[class*=\"layer-\"]").addClass("publicServersOpen").animate({opacity:0},{step:function(e){$(this).css("transform",`scale(${.07*e+.93}) translateZ(0px)`)},duration:200})}render(){return BDV2.react.createElement("div",{className:"layer bd-layer layer-3QrUeG",id:this.props.id,ref:"root",style:{opacity:0,transform:"scale(1.1) translateZ(0px)"}},this.props.children)}}class V2C_SidebarView extends BDV2.reactComponent{constructor(e){super(e)}render(){let{sidebar:e,content:t,tools:a}=this.props.children;return BDV2.react.createElement("div",{className:"standardSidebarView-3F1I7i ui-standard-sidebar-view"},BDV2.react.createElement("div",{className:"sidebarRegion-VFTUkN sidebar-region"},BDV2.react.createElement(V2Components.Scroller,{key:"sidebarScroller",ref:"sidebarScroller",sidebar:!0,fade:e.fade||!0,dark:e.dark||!0,children:e.component})),BDV2.react.createElement("div",{className:"contentRegion-3nDuYy content-region"},BDV2.react.createElement("div",{className:"contentTransitionWrap-3hqOEW content-transition-wrap"},BDV2.react.createElement("div",{className:"scrollerWrap-2lJEkd firefoxFixScrollFlex-cnI2ix contentRegionScrollerWrap-3YZXdm content-region-scroller-wrap scrollerThemed-2oenus themeGhost-28MSn0 scrollerTrack-1ZIpsv"},BDV2.react.createElement("div",{className:"scroller-2FKFPG firefoxFixScrollFlex-cnI2ix contentRegionScroller-26nc1e content-region-scroller scroller",ref:"contentScroller"},BDV2.react.createElement("div",{className:"contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default"},t.component),a.component)))))}}class V2_PublicServers{constructor(){}get component(){return BDV2.react.createElement(V2Components.Layer,{rootId:"pubslayerroot",id:"pubslayer",children:BDV2.react.createElement(V2C_PublicServers,{rootId:"pubslayerroot"})})}get root(){let e=document.getElementById("pubslayerroot");return e?e:this.injectRoot()?this.root:null}injectRoot(){return!!$(".layers, .layers-3iHuyZ").length&&($(".layers, .layers-3iHuyZ").append($("
",{id:"pubslayerroot"})),!0)}render(){let e=this.root;return e?void BDV2.reactDom.render(this.component,e):void console.log("FAILED TO LOCATE ROOT: .layers")}get button(){let e=$("
",{class:BDV2.guildClasses.listItem,id:"bd-pub-li",style:settingsCookie["bda-gs-1"]?"":"display: none;"}).append($("
",{class:"wrapper-25eVIn "+BDV2.guildClasses.circleButtonMask,text:"public",id:"bd-pub-button",click:()=>{this.render()}}));return e}initialize(){const e=BDV2.guildClasses.wrapper.split(" ")[0],t=$(`.${e} .scroller-2FKFPG >:first-child`);t.after(this.button)}}class V2C_ServerCard extends BDV2.reactComponent{constructor(e){super(e),this.props.server.iconUrl||(this.props.server.iconUrl=this.props.fallback),this.state={imageError:!1,joined:this.props.guildList.includes(this.props.server.identifier)}}render(){let{server:e}=this.props;return BDV2.react.createElement("div",{className:`card-3Qj_Yx cardPrimary-1Hv-to marginBottom8-AtZOdT bd-server-card${e.pinned?" bd-server-card-pinned":""}`},BDV2.react.createElement("img",{ref:"img",className:"bd-server-image",src:e.iconUrl,onError:this.handleError.bind(this)}),BDV2.react.createElement("div",{className:"flexChild-faoVW3 bd-server-content"},BDV2.react.createElement("div",{className:"flex-1xMQg5 flex-1O1GKY horizontal-1ae9ci horizontal-2EEEnY directionRow-3v3tfG noWrap-3jynv6 bd-server-header"},BDV2.react.createElement("h5",{className:"h5-18_1nd defaultColor-1_ajX0 margin-reset bd-server-name"},e.name),BDV2.react.createElement("h5",{className:"h5-18_1nd defaultColor-1_ajX0 margin-reset bd-server-member-count"},e.members," Members")),BDV2.react.createElement("div",{className:"flex-1xMQg5 flex-1O1GKY horizontal-1ae9ci horizontal-2EEEnY directionRow-3v3tfG noWrap-3jynv6"},BDV2.react.createElement("div",{className:"scrollerWrap-2lJEkd scrollerThemed-2oenus themeGhostHairline-DBD-2d scrollerFade-1Ijw5y bd-server-description-container"},BDV2.react.createElement("div",{className:"scroller-2FKFPG scroller bd-server-description"},e.description))),BDV2.react.createElement("div",{className:"flex-1xMQg5 flex-1O1GKY horizontal-1ae9ci horizontal-2EEEnY directionRow-3v3tfG noWrap-3jynv6 bd-server-footer"},BDV2.react.createElement("div",{className:"flexChild-faoVW3 bd-server-tags",style:{flex:"1 1 auto"}},e.categories.join(", ")),this.state.joined&&BDV2.react.createElement("button",{type:"button",className:"button-38aScr lookFilled-1Gx00P colorBrand-3pXr91 sizeMin-1mJd1x grow-q77ONN colorGreen-29iAKY",style:{minHeight:"12px",marginTop:"4px",backgroundColor:"#3ac15c"}},BDV2.react.createElement("div",{className:"ui-button-contents"},"Joined")),e.error&&BDV2.react.createElement("button",{type:"button",className:"button-38aScr lookFilled-1Gx00P colorBrand-3pXr91 sizeMin-1mJd1x grow-q77ONN disabled-9aF2ug",style:{minHeight:"12px",marginTop:"4px",backgroundColor:"#c13a3a"}},BDV2.react.createElement("div",{className:"ui-button-contents"},"Error")),!e.error&&!this.state.joined&&BDV2.react.createElement("button",{type:"button",className:"button-38aScr lookFilled-1Gx00P colorBrand-3pXr91 sizeMin-1mJd1x grow-q77ONN",style:{minHeight:"12px",marginTop:"4px"},onClick:()=>{this.join()}},BDV2.react.createElement("div",{className:"ui-button-contents"},"Join")))))}handleError(){this.props.server.iconUrl=this.props.fallback,this.setState({imageError:!0})}join(){this.props.join(this)}}class V2C_PublicServers extends BDV2.reactComponent{constructor(e){super(e),this.setInitialState(),this.close=this.close.bind(this),this.changeCategory=this.changeCategory.bind(this),this.search=this.search.bind(this),this.searchKeyDown=this.searchKeyDown.bind(this),this.checkConnection=this.checkConnection.bind(this),this.join=this.join.bind(this),this.connect=this.connect.bind(this),this.GuildStore=BDV2.WebpackModules.findByUniqueProperties(["getGuilds"]),this.AvatarDefaults=BDV2.WebpackModules.findByUniqueProperties(["getUserAvatarURL","DEFAULT_AVATARS"]),this.InviteActions=BDV2.WebpackModules.findByUniqueProperties(["acceptInvite"]),this.SortedGuildStore=BDV2.WebpackModules.findByUniqueProperties(["getSortedGuilds"])}componentDidMount(){this.checkConnection()}setInitialState(){this.state={selectedCategory:-1,title:"Loading...",loading:!0,servers:[],next:null,connection:{state:0,user:null}}}close(){BDV2.reactDom.unmountComponentAtNode(document.getElementById(this.props.rootId))}search(e,t){let a=this;$.ajax({method:"GET",url:`${a.endPoint}${e}${e?"&schema=new":"?schema=new"}`,success:e=>{let n=e.results.reduce((e,t)=>(t.joined=!1,e.push(t),e),[]);t||(n=a.state.servers.concat(n));let o=e.size+e.from;e.next=`?from=${o}`,a.state.term&&(e.next+=`&term=${a.state.term}`),a.state.selectedCategory&&(e.next+=`&category=${a.categoryButtons[a.state.selectedCategory]}`),o>=e.total&&(o=e.total,e.next=null);let s=`Showing 1-${o} of ${e.total} results in ${a.categoryButtons[a.state.selectedCategory]}`;a.state.term&&(s+=` for ${a.state.term}`),a.setState({loading:!1,title:s,servers:n,next:e.next}),t&&(a.refs.sbv.refs.contentScroller.scrollTop=0)},error:()=>{a.setState({loading:!1,title:"Failed to load servers. Check console for details"})}})}join(e){return e.props.pinned?this.InviteActions.acceptInvite(e.props.invite_code):void $.ajax({method:"GET",url:`${this.joinEndPoint}/${e.props.server.identifier}`,headers:{Accept:"application/json;","Content-Type":"application/json;","x-discord-token":this.state.connection.user.accessToken},crossDomain:!0,xhrFields:{withCredentials:!0},success:()=>{e.setState({joined:!0})}})}connect(){var e=Math.round;let t=this,a=t.windowOptions;a.x=e(window.screenX+window.innerWidth/2-a.width/2),a.y=e(window.screenY+window.innerHeight/2-a.height/2),t.joinWindow=new(window.require("electron").remote.BrowserWindow)(a);t.joinWindow.webContents.on("did-navigate",(e,a)=>{"https://auth.discordservers.com/info"!=a||(t.joinWindow.close(),t.checkConnection())}),t.joinWindow.loadURL("https://auth.discordservers.com/connect?scopes=guilds.join&previousUrl=https://auth.discordservers.com/info")}get windowOptions(){return{width:500,height:550,backgroundColor:"#282b30",show:!0,resizable:!1,maximizable:!1,minimizable:!1,alwaysOnTop:!0,frame:!1,center:!1,webPreferences:{nodeIntegration:!1}}}get bdServer(){let e=this.SortedGuildStore.guildPositions,t=this.AvatarDefaults.DEFAULT_AVATARS;return BDV2.react.createElement(V2Components.ServerCard,{server:{name:"BetterDiscord",online:"7500+",members:"20000+",categories:["community","programming","support"],description:"Official BetterDiscord server for support etc",identifier:"86004744966914048",iconUrl:"https://cdn.discordapp.com/icons/86004744966914048/292e7f6bfff2b71dfd13e508a859aedd.webp",nativejoin:!0,invite_code:"0Tmfo5ZbORCRqbAd",pinned:!0},pinned:!0,join:this.join,guildList:e,fallback:t[Math.floor(5*Math.random())]})}get endPoint(){return"https://search.discordservers.com"}get joinEndPoint(){return"https://j.discordservers.com"}get connectEndPoint(){return"https://join.discordservers.com/connect"}checkConnection(){let e=this;try{$.ajax({method:"GET",url:`https://auth.discordservers.com/info`,headers:{Accept:"application/json;","Content-Type":"application/json;"},crossDomain:!0,xhrFields:{withCredentials:!0},success:t=>{e.setState({selectedCategory:0,connection:{state:2,user:t}}),e.search("",!0)},error:()=>{e.setState({title:"Not connected to discordservers.com!",loading:!0,selectedCategory:-1,connection:{state:1,user:null}})}})}catch(t){e.setState({title:"Not connected to discordservers.com!",loading:!0,selectedCategory:-1,connection:{state:1,user:null}})}}render(){return BDV2.react.createElement(V2Components.SidebarView,{ref:"sbv",children:this.component})}get component(){return{sidebar:{component:this.sidebar},content:{component:this.content},tools:{component:BDV2.react.createElement(V2Components.Tools,{key:"pt",ref:"tools",onClick:this.close})}}}get sidebar(){return BDV2.react.createElement("div",{className:"sidebar",key:"ps"},BDV2.react.createElement("div",{className:"ui-tab-bar SIDE"},BDV2.react.createElement("div",{className:"ui-tab-bar-header",style:{fontSize:"16px"}},"Public Servers"),BDV2.react.createElement(V2Components.TabBar.Separator,null),this.searchInput,BDV2.react.createElement(V2Components.TabBar.Separator,null),BDV2.react.createElement(V2Components.TabBar.Header,{text:"Categories"}),this.categoryButtons.map((e,t)=>BDV2.react.createElement(V2Components.TabBar.Item,{id:t,onClick:this.changeCategory,key:t,text:e,selected:this.state.selectedCategory===t})),BDV2.react.createElement(V2Components.TabBar.Separator,null),this.footer,this.connection))}get searchInput(){return BDV2.react.createElement("div",{className:"ui-form-item"},BDV2.react.createElement("div",{className:"ui-text-input flex-vertical",style:{width:"172px",marginLeft:"10px"}},BDV2.react.createElement("input",{ref:"searchinput",onKeyDown:this.searchKeyDown,onChange:()=>{},type:"text",className:"input default",placeholder:"Search...",maxLength:"50"})))}searchKeyDown(t){let e=this;if(e.state.loading||13!==t.which)return;e.setState({loading:!0,title:"Loading...",term:t.target.value});let a=`?term=${t.target.value}`;0!==e.state.selectedCategory&&(a+=`&category=${e.categoryButtons[e.state.selectedCategory]}`),e.search(a,!0)}get categoryButtons(){return["All","FPS Games","MMO Games","Strategy Games","MOBA Games","RPG Games","Tabletop Games","Sandbox Games","Simulation Games","Music","Community","Language","Programming","Other"]}changeCategory(e){let t=this;if(!t.state.loading)return t.refs.searchinput.value="",t.setState({loading:!0,selectedCategory:e,title:"Loading...",term:null}),0===e?void t.search("",!0):void t.search(`?category=${t.categoryButtons[e]}`,!0)}get content(){var e=Math.floor;let t=this,a=this.SortedGuildStore.guildPositions,n=this.AvatarDefaults.DEFAULT_AVATARS;return 1===t.state.connection.state?t.notConnected:[BDV2.react.createElement("div",{ref:"content",key:"pc",className:"contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default"},BDV2.react.createElement(V2Components.SettingsTitle,{text:t.state.title}),t.bdServer,t.state.servers.map(o=>BDV2.react.createElement(V2Components.ServerCard,{key:o.identifier,server:o,join:t.join,guildList:a,fallback:n[e(5*Math.random())]})),t.state.next&&BDV2.react.createElement("button",{type:"button",onClick:()=>{t.state.loading||(t.setState({loading:!0}),t.search(t.state.next,!1))},className:"ui-button filled brand small grow",style:{width:"100%",marginTop:"10px",marginBottom:"10px"}},BDV2.react.createElement("div",{className:"ui-button-contents"},t.state.loading?"Loading":"Load More")),0`),o=[a(e),a(t)];n.find(".tab-bar-item").on("click",t=>{t.preventDefault(),n.find(".tab-bar-item").removeClass("selected"),$(t.target).addClass("selected"),n.find(".scroller").empty().append(o[$(t.target).index()])}),n.find(".footer button").on("click",()=>{n.addClass("closing"),setTimeout(()=>{n.remove()},300)}),n.find(".bd-backdrop").on("click",()=>{n.addClass("closing"),setTimeout(()=>{n.remove()},300)}),n.appendTo("#app-mount"),e.length?n.find(".tab-bar-item")[0].click():n.find(".tab-bar-item")[1].click()},Core.prototype.showToast=function(e,t={}){if(!bdConfig.deferLoaded)return;if(!document.querySelector(".bd-toasts")){let e=document.createElement("div");e.classList.add("bd-toasts");let t=document.querySelector(".chat-3bRxxu form, #friends, .noChannel-Z1DQK7, .activityFeed-28jde9");e.style.setProperty("left",t?t.getBoundingClientRect().left+"px":"0px"),e.style.setProperty("width",t?t.offsetWidth+"px":"100%"),e.style.setProperty("bottom",(document.querySelector(".chat-3bRxxu form")?document.querySelector(".chat-3bRxxu form").offsetHeight:80)+"px"),document.querySelector(".app, .app-2rEoOp").appendChild(e)}const{type:a="",icon:n=!0,timeout:o=3e3}=t;let s=document.createElement("div");s.classList.add("bd-toast"),a&&s.classList.add("toast-"+a),a&&n&&s.classList.add("icon"),s.innerText=e,document.querySelector(".bd-toasts").appendChild(s),setTimeout(()=>{s.classList.add("closing"),setTimeout(()=>{s.remove(),document.querySelectorAll(".bd-toasts .bd-toast").length||document.querySelector(".bd-toasts").remove()},300)},o)},window.emotesFfz={},window.emotesBTTV={},window.emotesBTTV2={},window.emotesTwitch={},window.subEmotesTwitch={},window.bdEmotes={TwitchGlobal:{},TwitchSubscriber:{},BTTV:{},FrankerFaceZ:{},BTTV2:{}},window.bdEmoteSettingIDs={TwitchGlobal:"bda-es-7",TwitchSubscriber:"bda-es-7",BTTV:"bda-es-2",FrankerFaceZ:"bda-es-1",BTTV2:"bda-es-2"};function EmoteModule(){Object.defineProperty(this,"categories",{get:function(){const e=[];for(const t in window.bdEmoteSettingIDs)settingsCookie[window.bdEmoteSettingIDs[t]]&&e.push(t);return e}})}EmoteModule.prototype.init=async function(){this.modifiers=["flip","spin","pulse","spin2","spin3","1spin","2spin","3spin","tr","bl","br","shake","shake2","shake3","flap"],this.overrides=["twitch","bttv","ffz"];let e={TwitchGlobal:{url:"https://twitchemotes.com/api_cache/v3/global.json",backup:`https://rauenzi.github.io/BetterDiscordApp/data/emotedata_twitch_global.json`,variable:"TwitchGlobal",oldVariable:"emotesTwitch",getEmoteURL:t=>`https://static-cdn.jtvnw.net/emoticons/v1/${t.id}/1.0`,getOldData:(e,t)=>({id:e.match(/\/([0-9]+)\//)[1],code:t,emoticon_set:0,description:null})},TwitchSubscriber:{url:`https://rauenzi.github.io/BetterDiscordApp/data/emotedata_twitch_subscriber.json`,variable:"TwitchSubscriber",oldVariable:"subEmotesTwitch",getEmoteURL:t=>`https://static-cdn.jtvnw.net/emoticons/v1/${t}/1.0`,getOldData:e=>e.match(/\/([0-9]+)\//)[1]},FrankerFaceZ:{url:`https://rauenzi.github.io/BetterDiscordApp/data/emotedata_ffz.json`,variable:"FrankerFaceZ",oldVariable:"emotesFfz",getEmoteURL:t=>`https://cdn.frankerfacez.com/emoticon/${t}/1`,getOldData:e=>e.match(/\/([0-9]+)\//)[1]},BTTV:{url:"https://api.betterttv.net/emotes",variable:"BTTV",oldVariable:"emotesBTTV",parser:t=>{let a={};for(let n,o=0,e=t.emotes.length;o`${t}`,getOldData:e=>e},BTTV2:{url:`https://rauenzi.github.io/BetterDiscordApp/data/emotedata_bttv.json`,variable:"BTTV2",oldVariable:"emotesBTTV2",getEmoteURL:t=>`https://cdn.betterttv.net/emote/${t}/1x`,getOldData:e=>e.match(/emote\/(.+)\//)[1]}};for(await this.getBlacklist(),await this.loadEmoteData(e);!BDV2.MessageContentComponent;)await new Promise(e=>setTimeout(e,100));this.cancelEmoteRender||(this.cancelEmoteRender=Utils.monkeyPatch(BDV2.MessageContentComponent.prototype,"render",{after:({returnValue:e})=>{Utils.monkeyPatch(e.props,"children",{silent:!0,after:({returnValue:e})=>{if(0!=this.categories.length){const t=e.props.children[1];if(t.props.children){const e=t.props.children[1];if(e&&e.length){for(let t=0;ti.length||bemotes.includes(i))continue;this.modifiers.includes(l)&&settingsCookie["bda-es-8"]||(l=""),this.overrides.includes(d)?l=d:d="";let c=this.categories[a];if("twitch"===d?window.bdEmotes.TwitchGlobal[i]?c="TwitchGlobal":window.bdEmotes.TwitchSubscriber[i]&&(c="TwitchSubscriber"):"bttv"===d?window.bdEmotes.BTTV[i]?c="BTTV":window.bdEmotes.BTTV2[i]&&(c="BTTV2"):"ffz"===d&&window.bdEmotes.FrankerFaceZ[i]&&(c="FrankerFaceZ"),!window.bdEmotes[c][i]||!settingsCookie[window.bdEmoteSettingIDs[c]])continue;const p=e[t].match(new RegExp(`([\\s]|^)${Utils.escape(l?i+":"+l:i)}([\\s]|$)`));if(!p)continue;const m=e[t].substring(0,p.index+p[1].length),u=e[t].substring(p.index+p[0].length-p[2].length);e[t]=m;const g=BDV2.react.createElement(BDEmote,{name:i,url:window.bdEmotes[c][i],modifier:l});e.splice(t+1,0,u),e.splice(t+1,0,g)}}const t=e.every(e=>"string"==typeof e&&""==e.replace(/\s*/,"")||!!(e.type&&"BDEmote"==e.type.name)||!!(e.props&&e.props.children&&e.props.children.props&&e.props.children.props.emojiName));if(t)for(let t of e)"object"==typeof t&&("BDEmote"==t.type.name?t.props.jumboable=!0:t.props&&t.props.children&&t.props.children.props&&t.props.children.props.emojiName&&(t.props.children.props.jumboable=!0))}}}}})}}))},EmoteModule.prototype.disable=function(){this.disableAutoCapitalize();this.cancelEmoteRender||(this.cancelEmoteRender(),this.cancelEmoteRender=null)},EmoteModule.prototype.clearEmoteData=async function(){let e=require("fs"),t=bdConfig.dataPath+"emote_data.json",a=e.existsSync(t);a&&e.unlinkSync(t),DataStore.setBDData("emoteCacheDate",new Date().toJSON()),window.bdEmotes={TwitchGlobal:{},TwitchSubscriber:{},BTTV:{},FrankerFaceZ:{},BTTV2:{}}},EmoteModule.prototype.goBack=async function(t){for(let a in t)for(let e in window.bdEmotes[t[a].variable])window[t[a].oldVariable][e]=t[a].getOldData(window.bdEmotes[t[a].variable][e],e)},EmoteModule.prototype.isCacheValid=function(){const e=DataStore.getBDData("emoteCacheDays")||DataStore.setBDData("emoteCacheDays",7)||7,t=new Date(DataStore.getBDData("emoteCacheDate")||null),a=new Date,n=Math.round(Math.abs((a.getTime()-t.getTime())/86400000));return!(n>e)||(DataStore.setBDData("emoteCacheDate",a.toJSON()),!1)},EmoteModule.prototype.loadEmoteData=async function(t){const a=require("fs"),e=bdConfig.dataPath+"emote_data.json",n=await new Promise(t=>a.exists(e,t));if(n&&this.isCacheValid()){settingsCookie["fork-ps-2"]&&mainCore.showToast("Loading emotes from cache.",{type:"info"}),Utils.log("Emotes","Loading emotes from local cache.");const n=await new Promise(t=>{a.readFile(e,"utf8",(e,a)=>{Utils.log("Emotes","Emote file read."),e&&(a={}),t(a)})}),o=Utils.testJSON(n);let s=!!o;for(const a in s&&(window.bdEmotes=o),t)s=0a.unlink(e,t))}if(settingsCookie["fork-es-3"]){for(let a in settingsCookie["fork-ps-2"]&&mainCore.showToast("Downloading emotes in the background do not reload.",{type:"info"}),t){await new Promise(e=>setTimeout(e,1e3));let e=await this.downloadEmotes(t[a]);window.bdEmotes[t[a].variable]=e}settingsCookie["fork-ps-2"]&&mainCore.showToast("All emotes successfully downloaded.",{type:"success"});try{await new Promise(t=>a.writeFile(e,JSON.stringify(window.bdEmotes),"utf8",t))}catch(e){Utils.err("Emotes","Could not save emote data.",e)}}},EmoteModule.prototype.downloadEmotes=function(e){let t=require("request"),a={url:e.url,timeout:e.timeout?e.timeout:5e3,json:!0};return Utils.log("Emotes",`Downloading: ${e.variable} (${e.url})`),new Promise((n,o)=>{t(a,(t,a,s)=>{if(t)return Utils.err("Emotes","Could not download "+e.variable,t),e.backup?(e.url=e.backup,e.backup=null,e.backupParser&&(e.parser=e.backupParser),n(this.downloadEmotes(e))):o({});for(let n in"function"==typeof e.parser&&(s=e.parser(s)),s){if(4>n.length||bemotes.includes(n)){delete s[n];continue}s[n]=e.getEmoteURL(s[n])}n(s),Utils.log("Emotes","Downloaded: "+e.variable)})})},EmoteModule.prototype.getBlacklist=function(){return new Promise(e=>{$.getJSON(`https://rauenzi.github.io/BetterDiscordApp/data/emotefilter.json`,function(t){e(bemotes=t.blacklist)})})};var bemotes=[];EmoteModule.prototype.autoCapitalize=function(){!settingsCookie["bda-es-4"]||this.autoCapitalizeActive||($("body").on("keyup.bdac change.bdac paste.bdac",$(".channelTextArea-1LDbYG textarea:first"),()=>{var e=$(".channelTextArea-1LDbYG textarea:first").val();if(null!=e){var t=e.split(" ").pop();if(3",t+=" ",t+=" ",t+="
",this.qmeHeader=t;var a="";a+="
",a+="
",a+="
",a+="
";var n="";for(let e in window.bdEmotes.TwitchGlobal)window.bdEmotes.TwitchGlobal.hasOwnProperty(e)&&(n=window.bdEmotes.TwitchGlobal[e],a+="
",a+=" \"\"",a+=" ",a+="
");a+="
",a+="
",a+="
",a+="
",this.teContainer=a;var o="";for(let e in o+="
",o+="
",o+="
",o+="
",this.favoriteEmotes)n=this.favoriteEmotes[e],o+="
",o+=" \"\"",o+=" ",o+="
";o+="
",o+="
",o+="
",o+="
",this.faContainer=o},QuickEmoteMenu.prototype.favContext=function(t,e){t.stopPropagation();var a=$("
",{id:"removemenu","data-emoteid":$(e).prop("title"),text:"Remove",class:"bd-context-menu context-menu theme-dark"});return a.css({top:t.pageY-$("#bda-qem-favourite-container").offset().top,left:t.pageX-$("#bda-qem-favourite-container").offset().left}),$(e).parent().append(a),a.on("click",function(t){return t.preventDefault(),t.stopPropagation(),$(this).remove(),delete quickEmoteMenu.favoriteEmotes[$(this).data("emoteid")],quickEmoteMenu.updateFavorites(),!1}),!1},QuickEmoteMenu.prototype.switchHandler=function(t){this.switchQem($(t).attr("id"))},QuickEmoteMenu.prototype.switchQem=function(e){var t=$("#bda-qem-twitch"),a=$("#bda-qem-favourite"),n=$("#bda-qem-emojis");t.removeClass("active"),a.removeClass("active"),n.removeClass("active"),$(".emojiPicker-3m1S-j").hide(),$("#bda-qem-favourite-container").hide(),$("#bda-qem-twitch-container").hide();"bda-qem-twitch"===e?(t.addClass("active"),$("#bda-qem-twitch-container").show()):"bda-qem-favourite"===e?(a.addClass("active"),$("#bda-qem-favourite-container").show()):"bda-qem-emojis"===e?(n.addClass("active"),$(".emojiPicker-3m1S-j").show(),$(".emojiPicker-3m1S-j .search-bar-inner input, .emojiPicker-3m1S-j .search-bar-inner input").focus()):void 0;this.lastTab=e;var o=$(".emote-icon");o.off(),o.on("click",function(){var e=$(this).attr("title"),t=Utils.getTextArea();Utils.insertText(t[0]," "==t.val().slice(-1)?t.val()+e:t.val()+" "+e)})},QuickEmoteMenu.prototype.obsCallback=function(t){if(this.initialized){var a=$(t);settingsCookie["bda-es-9"]?a.removeClass("bda-qme-hidden"):a.addClass("bda-qme-hidden"),settingsCookie["bda-es-0"]&&(a.prepend(this.qmeHeader),a.append(this.teContainer),a.append(this.faContainer),null==this.lastTab&&(this.lastTab="bda-qem-emojis"),this.switchQem(this.lastTab))}},QuickEmoteMenu.prototype.favorite=function(e,t){this.favoriteEmotes.hasOwnProperty(e)||(this.favoriteEmotes[e]=t),this.updateFavorites()},QuickEmoteMenu.prototype.updateFavorites=function(){var e="";for(var t in e+="
",e+="
",e+="
",e+="
",this.favoriteEmotes){var a=this.favoriteEmotes[t];e+="
",e+=" \"\"",e+=" ",e+="
"}e+="
",e+="
",e+="
",e+="
",this.faContainer=e,$("#bda-qem-favourite-container").replaceWith(e),DataStore.setBDData("bdfavemotes",btoa(JSON.stringify(this.favoriteEmotes)))};var Utils=class{static get screenWidth(){return Math.max(document.documentElement.clientWidth,window.innerWidth||0)}static get screenHeight(){return Math.max(document.documentElement.clientHeight,window.innerHeight||0)}static stripBOM(e){return 65279===e.charCodeAt(0)&&(e=e.slice(1)),e}static getTextArea(){return $(".channelTextArea-1LDbYG textarea")}static insertText(e,t){e.focus(),e.selectionStart=0,e.selectionEnd=e.value.length,document.execCommand("insertText",!1,t)}static injectCss(e){$("",{type:"text/css",rel:"stylesheet",href:e}).appendTo($("head"))}static injectJs(e){return new Promise(t=>{$("