// ==UserScript==
// @name DH2 Fixed
// @namespace FileFace
// @description Improve Diamond Hunt 2
// @version 0.140.1
// @author Zorbing
// @license ISC; http://opensource.org/licenses/ISC
// @grant none
// @run-at document-start
// @include http://www.diamondhunt.co/game.php
// ==/UserScript==
/**
* ISC License (ISC)
*
* Copyright (c) 2017, Martin Boekhoff
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby
* granted, provided that the above copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* Source: http://opensource.org/licenses/ISC
*/
(function ()
{
'use strict';
var version = '0.140.1';
/**
* observer
*/
var observer;
(function (observer)
{
var observedKeys = new Map();
function add(key, fn)
{
if (key instanceof Array)
{
for (var _i = 0, key_1 = key; _i < key_1.length; _i++)
{
var k = key_1[_i];
add(k, fn);
}
}
else
{
if (!observedKeys.has(key))
{
observedKeys.set(key, new Set());
}
observedKeys.get(key).add(fn);
}
return fn;
}
observer.add = add;
function notify(key, oldValue)
{
var newValue = getGameValue(key);
window[key] = newValue;
if (observedKeys.has(key))
{
observedKeys.get(key).forEach(function (fn)
{
return fn(key, oldValue, newValue);
});
}
}
observer.notify = notify;
function remove(key, fn)
{
if (key instanceof Array)
{
var ret = [];
for (var _i = 0, key_2 = key; _i < key_2.length; _i++)
{
var k = key_2[_i];
ret.push(remove(k, fn));
}
return ret;
}
if (!observedKeys.has(key))
{
return false;
}
return observedKeys.get(key).delete(fn);
}
observer.remove = remove;
})(observer || (observer = {}));
/**
* global constants
*/
var TIER_LEVELS = ['empty', 'sapphire', 'emerald', 'ruby', 'diamond'];
var TIER_NAMES = ['Standard', 'Sapphire', 'Emerald', 'Ruby', 'Diamond'];
var TIER_ITEMS = ['pickaxe', 'shovel', 'hammer', 'axe', 'rake', 'fishingRod', 'chisel'];
var FURNACE_LEVELS = ['stone', 'bronze', 'iron', 'silver', 'gold'];
var OVEN_LEVELS = ['bronze', 'iron', 'silver', 'gold'];
/** /
function calcSize(level: number)
{
if (level == 1)
{
return 10e3;
}
const r = 10e3 * Math.exp(0.805 * level);
const f = Math.pow(10, Math.floor(Math.log10(r)));
return Math.round(r / f) * f;
}
/**/
/**
* next values may be:
* - level 6: 1,000,000
* - level 7: 3,000,000
* - level 8: 6,000,000
* - level 9: 10,000,000
* - level 10: 30,000,000
*/
var OIL_STORAGE_SIZES = [10e3, 50e3, 100e3, 300e3, 600e3, 1e6, 3e6];
var HIDE_RECIPES = {
'drills':
{
max: 10
}
, 'crushers':
{
max: 10
}
, 'giantDrills':
{
max: 10
}
, 'excavators':
{
max: 10
}
, 'oilPipe':
{
max: 1
}
, 'pumpjacks':
{
max: 10
}
, 'rowBoat':
{
max: 1
}
, 'canoe':
{
max: 1
}
// thanks aguyd
, 'bonemealBin':
{
extraKeys: ['boundFilledBonemealBin']
, max: 1
}
, 'oilFactory':
{
max: 1
}
};
var SMELTING_REQUIREMENTS = {
'glass':
{
sand: 1
, oil: 10
}
, 'bronzeBar':
{
copper: 1
, tin: 1
, oil: 10
}
, 'ironBar':
{
iron: 1
, oil: 100
}
, 'silverBar':
{
silver: 1
, oil: 300
}
, 'goldBar':
{
gold: 1
, oil: 1e3
}
};
var SEED_NAME = {
'1': 'Dark Mushrooms'
, '2': 'Red Mushrooms'
, '3': 'Dotted Green Leafs'
, '4': 'Green Leafs'
, '5': 'Lime Leafs'
, '6': 'Gold Leafs'
, '7': 'Striped Gold Leafs'
, '8': 'Crystal Leafs'
, '9': 'Striped Crystal Leafs'
, '10': 'Blewit Mushrooms'
, '11': 'Snapegrass'
, '12': 'Tree'
, '13': 'Oak Tree'
, '14': 'Wheat'
, '15': 'Willow Tree'
, '16': 'Grass'
, '17': 'Maple Tree'
, '18': 'Stardust Tree'
};
var SKILL_LIST = ['mining', 'crafting', 'woodcutting', 'farming', 'brewing', 'combat', 'fishing', 'cooking', 'magic'];
var AREA_LIST = ['fields', 'forests', 'caves', 'volcano'];
var SMELTING_TIME = {
'glass': 1
, 'bronzeBar': 1
, 'ironBar': 5
, 'silverBar': 10
, 'goldBar': 30
};
var FISH_XP = {
'rawShrimp': 50
, 'rawSardine': 500
, 'rawTuna': 3e3
, 'rawSwordfish': 5e3
, 'rawShark': 12e3
};
var BOAT_LIST = ['rowBoat', 'canoe'];
var format;
(function (format)
{
var TIME_STEPS = [
{
threshold: 1
, name: 'second'
, short: 'sec'
, padp: 0
}
, {
threshold: 60
, name: 'minute'
, short: 'min'
, padp: 0
}
, {
threshold: 3600
, name: 'hour'
, short: 'h'
, padp: 1
}
, {
threshold: 86400
, name: 'day'
, short: 'd'
, padp: 2
}];
function zeroPadLeft(num)
{
return (num < 10 ? '0' : '') + num;
}
function number(num)
{
return (typeof num === 'number' ? num : Number(num)).toLocaleString('en');
}
format.number = number;
function numbersInText(text)
{
return text.replace(/\d(?:[\d',\.]*\d)?/g, function (numStr)
{
return number(Number(numStr.replace(/\D/g, '')));
});
}
format.numbersInText = numbersInText;
// use time format established in DHQoL (https://greasyfork.org/scripts/16041-dhqol)
function timer(timer, shorten)
{
if (shorten === void 0)
{
shorten = true;
}
if (typeof timer === 'string')
{
timer = parseInt(timer, 10);
}
timer = Math.max(timer, 0);
var hours = Math.floor(timer / 3600);
var minutes = Math.floor((timer % 3600) / 60);
var seconds = timer % 60;
return (shorten && hours === 0 ? '' : zeroPadLeft(hours) + ':')
+ zeroPadLeft(minutes) + ':'
+ zeroPadLeft(seconds);
}
format.timer = timer;
function time2NearestUnit(time, long)
{
if (long === void 0)
{
long = false;
}
var step = TIME_STEPS[0];
for (var i = TIME_STEPS.length - 1; i > 0; i--)
{
if (time >= TIME_STEPS[i].threshold)
{
step = TIME_STEPS[i];
break;
}
}
var factor = Math.pow(10, step.padp);
var num = Math.round(time / step.threshold * factor) / factor;
var unit = long ? step.name + (num === 1 ? '' : 's') : step.short;
return num + ' ' + unit;
}
format.time2NearestUnit = time2NearestUnit;
function min2Str(minutes)
{
if (typeof minutes === 'string')
{
minutes = parseInt(minutes, 10);
}
var m = minutes % 60;
var h = Math.floor(minutes / 60);
return (h > 0 ? h + ' hour' + (h == 1 ? '' : 's') + ' and ' : '')
+ m + ' minute' + (m == 1 ? '' : 's');
}
format.min2Str = min2Str;
})(format || (format = {}));
/**
* general functions
*/
function addStyle(styleCode, elId)
{
var id = elId != null ? 'style-' + elId : null;
var styleElement = id != null ? document.getElementById(id) : null;
if (styleElement == null)
{
styleElement = document.createElement('style');
if (id != null)
{
styleElement.id = id;
}
styleElement.type = 'text/css';
document.head.appendChild(styleElement);
}
styleElement.innerHTML += styleCode;
}
function capitalize(str)
{
return str[0].toUpperCase() + str.substr(1);
}
function key2Name(key, lowerCase)
{
if (lowerCase === void 0)
{
lowerCase = false;
}
var name = key.replace(/[A-Z]/g, function (c)
{
return ' ' + (lowerCase ? c.toLowerCase() : c);
});
return lowerCase ? name : capitalize(name);
}
function split2Words(str, char)
{
if (char === void 0)
{
char = ' ';
}
return str.replace(/[A-Z]/g, char + '$&');
}
function getBoundKey(key)
{
return 'bound' + capitalize(key);
}
function getTierKey(key, tierLevel)
{
return TIER_LEVELS[tierLevel] + capitalize(key);
}
function now()
{
return (new Date()).getTime();
}
function ensureTooltip(id, target)
{
var tooltipId = 'tooltip-' + id;
var tooltipEl = document.getElementById(tooltipId);
if (!tooltipEl)
{
tooltipEl = document.createElement('div');
tooltipEl.id = tooltipId;
tooltipEl.style.display = 'none';
var tooltipList = document.getElementById('tooltip-list');
tooltipList.appendChild(tooltipEl);
}
// ensure binded events to show the tooltip
if (target.dataset.tooltipId == null)
{
target.dataset.tooltipId = tooltipId;
window.$(target).bind(
{
mousemove: window.changeTooltipPosition
, mouseenter: window.showTooltip
, mouseleave: window.hideTooltip
});
}
return tooltipEl;
}
var timeStr2Sec = (function ()
{
var unitFactors = {
'd': 24 * 60 * 60
, 'h': 60 * 60
, 'm': 60
, 's': 1
};
return function timeStr2Sec(str)
{
return str
.replace(/(\d+)([hms])/g, function (wholeMatch, num, unit)
{
return parseInt(num) * (unitFactors[unit] || 1) + '+';
})
.split('+')
.map(function (s)
{
return parseInt(s, 10);
})
.filter(function (n)
{
return !isNaN(n);
})
.reduce(function (p, c)
{
return p + c;
}, 0);
};
})();
function getGameValue(key)
{
return window[key];
}
function getFurnaceLevel()
{
for (var i = FURNACE_LEVELS.length - 1; i >= 0; i--)
{
if (getGameValue(getBoundKey(FURNACE_LEVELS[i] + 'Furnace')) > 0)
{
return i;
}
}
return -1;
}
function getFurnaceLevelName()
{
return FURNACE_LEVELS[getFurnaceLevel()] || '';
}
function getPrice(item)
{
var price = window.getPrice(item);
if (typeof price === 'number')
{
return price;
}
var match = price.match(/(\d+)([kM])/);
if (!match)
{
return parseInt(price, 10);
}
var FACTORS = {
'k': 1e3
, 'M': 1e6
};
return parseInt(match[1], 10) * (FACTORS[match[2]] || 1);
}
/**
* persistence store
*/
var store;
(function (store)
{
var storePrefix = 'dh2-';
function get(key)
{
var value = localStorage.getItem(storePrefix + key);
if (value != null)
{
try
{
return JSON.parse(value);
}
catch (e)
{}
}
return value;
}
store.get = get;
function has(key)
{
return localStorage.hasOwnProperty(storePrefix + key);
}
store.has = has;
function remove(key)
{
localStorage.removeItem(storePrefix + key);
}
store.remove = remove;
function set(key, value)
{
localStorage.setItem(storePrefix + key, JSON.stringify(value));
}
store.set = set;
})(store || (store = {}));
var settings;
(function (settings)
{
settings.name = 'settings';
var KEY;
(function (KEY)
{
KEY[KEY["hideCraftingRecipes"] = 0] = "hideCraftingRecipes";
KEY[KEY["hideUselessItems"] = 1] = "hideUselessItems";
KEY[KEY["useNewChat"] = 2] = "useNewChat";
KEY[KEY["colorizeChat"] = 3] = "colorizeChat";
KEY[KEY["intelligentScrolling"] = 4] = "intelligentScrolling";
KEY[KEY["showTimestamps"] = 5] = "showTimestamps";
KEY[KEY["showIcons"] = 6] = "showIcons";
KEY[KEY["showTags"] = 7] = "showTags";
KEY[KEY["showNotifications"] = 8] = "showNotifications";
})(KEY = settings.KEY || (settings.KEY = {}));;
var CFG = (_a = {}
, _a[KEY.hideCraftingRecipes] = {
name: 'Hide crafting recipes of finished items'
, description: "Hides crafting recipes of:\n\t\t\t\t<ul style=\"margin: .5rem 0 0;\">\n\t\t\t\t\t<li>furnace, oil storage and oven recipes if they aren't better than the current level</li>\n\t\t\t\t\t<li>machines if the user has the maximum amount of this type (counts bound and unbound items)</li>\n\t\t\t\t\t<li>non-stackable items which the user already owns (counts bound and unbound items)</li>\n\t\t\t\t</ul>"
, defaultValue: true
, special: true
}
, _a[KEY.hideUselessItems] = {
name: 'Hide useless items'
, description: "Hides <em>unbound</em> items which may has been crafted accidentially and are of no use for the player:\n\t\t\t\t<ul style=\"margin: .5rem 0 0;\">\n\t\t\t\t\t<li>furnace, oil storage and oven recipes if they aren't better than the current level</li>\n\t\t\t\t\t<li>machines if the user has already bound the maximum amount of this type</li>\n\t\t\t\t\t<li>non-stackable items which the user has already bound</li>\n\t\t\t\t</ul>"
, defaultValue: false
, special: true
}
, _a[KEY.useNewChat] = {
name: 'Use the new chat'
, description: "Enables using the completely new chat with pm tabs, clickable links, clickable usernames to send a pm, intelligent scrolling and suggesting commands while typing"
, defaultValue: true
, special: true
}
, _a[KEY.colorizeChat] = {
name: 'Colorize chat messages'
, description: "Colorize chat messages according to a unique color for each user"
, defaultValue: false
, special: true
}
, _a[KEY.intelligentScrolling] = {
name: 'Intelligent scrolling'
, description: "Autoscroll gets disabled when you scroll up and gets enabled again when you scroll all the way down to the bottom of the chat."
, defaultValue: true
, special: true
}
, _a[KEY.showTimestamps] = {
name: 'Show timestamps'
, description: "Enables showing timestamps in chat"
, defaultValue: true
, special: true
}
, _a[KEY.showIcons] = {
name: 'Show user-icons'
, description: "Enables showing icons (formerly sigils) for each user in chat"
, defaultValue: true
, special: true
}
, _a[KEY.showTags] = {
name: 'Show user-tags'
, description: "Enables showing tags (Dev, Mod, Contributor) and colors for messages in chat"
, defaultValue: true
, special: true
}
, _a[KEY.showNotifications] = {
name: 'Show browser notifications'
, description: "Shows browser notifications for the following events:\n\t\t\t<ul style=\"margin: .5rem 0 0;\">\n\t\t\t\t<li>Smelting finished</li>\n\t\t\t\t<li>Tree fully grown</li>\n\t\t\t\t<li>Plant ready for harvest</li>\n\t\t\t\t<li>Potion effect has ended for: (super) stardust, bar and seed potions</li>\n\t\t\t\t<li>Boat returned (either the row boat or the canoe)</li>\n\t\t\t\t<li>Hero fully recoverd and able to fight again</li>\n\t\t\t\t<li>Items sold on the market</li>\n\t\t\t\t<li>Private chat messages (pms)</li>\n\t\t\t\t<li>Server messages (like <em>Server is restarting...</em>)</li>\n\t\t\t</ul>"
, defaultValue: true
}
, _a);
var SETTINGS_TABLE_ID = 'd2h-settings';
var SETTING_ID_PREFIX = 'dh2-setting-';
/**
* settings
*/
function toName(key)
{
return typeof key === 'string' ? key : KEY[key];
}
function getStoreKey(key)
{
return 'setting.' + toName(key);
}
var observedSettings = new Map();
function observe(key, fn)
{
var n = toName(key);
if (!observedSettings.has(n))
{
observedSettings.set(n, new Set());
}
observedSettings.get(n).add(fn);
}
settings.observe = observe;
function unobserve(key, fn)
{
var n = toName(key);
if (!observedSettings.has(n))
{
return false;
}
return observedSettings.get(n).delete(fn);
}
settings.unobserve = unobserve;
var settingsProxies = new Map();
function get(key)
{
if (!CFG.hasOwnProperty(key))
{
return false;
}
if (settingsProxies.has(key))
{
var proxy = settingsProxies.get(key);
return proxy.get(key);
}
var name = getStoreKey(key);
return store.has(name) ? store.get(name) : CFG[key].defaultValue;
}
settings.get = get;
function set(key, newValue)
{
if (!CFG.hasOwnProperty(key))
{
return;
}
var oldValue = get(key);
var n = toName(key);
if (settingsProxies.has(key))
{
var proxy = settingsProxies.get(key);
proxy.set(key, oldValue, newValue);
}
else
{
store.set(getStoreKey(key), newValue);
}
if (oldValue !== newValue && observedSettings.has(n))
{
observedSettings.get(n).forEach(function (fn)
{
return fn(key, oldValue, newValue);
});
}
}
settings.set = set;
function initSettingsStyle()
{
addStyle("\ntable.table-style1 tr:not([onclick])\n{\n\tcursor: initial;\n}\n#tab-container-profile h2.section-title\n{\n\tcolor: orange;\n\tline-height: 1.2rem;\n\tmargin-top: 2rem;\n}\n#tab-container-profile h2.section-title > span.note\n{\n\tfont-size: 0.9rem;\n}\n#" + SETTINGS_TABLE_ID + " tr.reload td:first-child::after\n{\n\tcontent: '*';\n\tfont-weight: bold;\n\tmargin-left: 3px;\n}\n\n.settings-container\n{\n\tlist-style: none;\n\tmargin: 5px 2.5%;\n\tpadding: 0;\n}\n.settings-container > li.setting\n{\n\tbackground-color: silver;\n\tborder: 1px solid black;\n\tborder-top-width: 0;\n}\n.settings-container > li.setting:first-child\n{\n\tborder-top-width: 1px;\n}\n.settings-container > li.setting,\n.settings-container > li.setting *\n{\n\tcursor: pointer;\n\t-webkit-user-select: none;\n\t-moz-user-select: none;\n\t-ms-user-select: none;\n\tuser-select: none;\n}\n.settings-container > li.setting:hover\n{\n\tbackground-color: gray;\n}\n.settings-container > li.setting > input[type=\"checkbox\"]\n{\n\tdisplay: none;\n}\n.settings-container > li.setting > label\n{\n\tdisplay: block;\n\tpadding: .25rem .5rem;\n}\n.settings-container > li.setting > input + label::before\n{\n\tbackground-image: url(images/icons/x.png);\n\tbackground-size: 20px;\n\tcontent: '';\n\tdisplay: inline-block;\n\theight: 20px;\n\tmargin: 0 .25rem;\n\twidth: 20px;\n\tvertical-align: middle;\n}\n.settings-container > li.setting > input:checked + label::before\n{\n\tbackground-image: url(images/icons/check.png);\n}\n\t\t");
}
function initSettingTable()
{
function insertAfter(newChild, oldChild)
{
var parent = oldChild.parentElement;
if (oldChild.nextElementSibling == null)
{
parent.appendChild(newChild);
}
else
{
parent.insertBefore(newChild, oldChild.nextElementSibling);
}
}
function getCheckImageSrc(value)
{
return 'images/icons/' + (value ? 'check' : 'x') + '.png';
}
var profileTable = document.getElementById('profile-toggleTable');
if (!profileTable)
{
return;
}
var settingsHeader = document.createElement('h2');
settingsHeader.className = 'section-title';
settingsHeader.innerHTML = "Userscript \"DH2 Fixed\"<br>\n\t\t\t<span class=\"note\" style=\"display: none;\">(* changes require reloading the tab)</span>";
var requiresReloadNote = settingsHeader.querySelector('.note');
insertAfter(settingsHeader, profileTable);
var settingsTable = document.createElement('table');
settingsTable.id = SETTINGS_TABLE_ID;
settingsTable.className = 'table-style1';
settingsTable.width = '40%';
settingsTable.innerHTML = "\n\t\t<tr style=\"background-color:grey;\">\n\t\t\t<th>Setting</th>\n\t\t\t<th>Enabled</th>\n\t\t</tr>\n\t\t";
function addRowClickListener(row, key, settingId)
{
row.addEventListener('click', function ()
{
var newValue = !get(key);
set(key, newValue);
document.getElementById(settingId).src = getCheckImageSrc(newValue);
});
}
for (var k in CFG)
{
// convert it into a KEY
var key = parseInt(k, 10);
var setting = CFG[key];
if (setting == null)
{
console.error('missing setting entry:', key, toName(key));
continue;
}
if (setting.special)
{
continue;
}
var settingId = SETTING_ID_PREFIX + toName(key);
var row = settingsTable.insertRow(-1);
row.classList.add('setting');
if (setting.requiresReload)
{
row.classList.add('reload');
requiresReloadNote.style.display = '';
}
row.setAttribute('onclick', '');
row.innerHTML = "\n\t\t\t<td>" + setting.name + "</td>\n\t\t\t<td><img src=\"" + getCheckImageSrc(get(key)) + "\" id=\"" + settingId + "\" class=\"image-icon-20\"></td>\n\t\t\t";
var tooltipEl = ensureTooltip(settingId, row);
tooltipEl.innerHTML = setting.description;
if (setting.requiresReload)
{
tooltipEl.innerHTML += "<span style=\"color: hsla(20, 100%, 50%, 1); font-size: .9rem; display: block; margin-top: 0.5rem;\">You have to reload the browser tab to apply changes to this setting.</span>";
}
addRowClickListener(row, key, settingId);
}
insertAfter(settingsTable, settingsHeader);
}
function initProxies()
{
var row = document.querySelector('tr[data-tooltip-id="tooltip-profile-removeCraftingFilter"]');
if (row)
{
settingsProxies.set(KEY.hideCraftingRecipes
, {
get: function (key)
{
return getGameValue('profileRemoveCraftingFilter') != 1;
}
, set: function (key, oldValue, newValue)
{
if (oldValue != newValue)
{
row.click();
}
}
});
observer.add('profileRemoveCraftingFilter', function ()
{
set(KEY.hideCraftingRecipes, getGameValue('profileRemoveCraftingFilter') != 1);
});
}
}
function createSettingsContainer(settingList)
{
var settingsContainer = document.createElement('ul');
settingsContainer.className = 'settings-container';
for (var _i = 0, settingList_1 = settingList; _i < settingList_1.length; _i++)
{
var key = settingList_1[_i];
var settingId = 'setting-' + split2Words(KEY[key], '-');
var setting = CFG[key];
var listEl = document.createElement('li');
listEl.classList.add('setting');
if (setting.requiresReload)
{
listEl.classList.add('reload');
}
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = settingId;
checkbox.checked = get(key);
var label = document.createElement('label');
label.htmlFor = settingId;
label.textContent = setting.name;
(function (key, checkbox)
{
checkbox.addEventListener('change', function ()
{
set(key, checkbox.checked);
});
})(key, checkbox);
listEl.appendChild(checkbox);
listEl.appendChild(label);
settingsContainer.appendChild(listEl);
var tooltipEl = ensureTooltip(settingId, listEl);
tooltipEl.innerHTML = setting.description;
if (setting.requiresReload)
{
tooltipEl.innerHTML += "<span style=\"color: hsla(20, 100%, 50%, 1); font-size: .9rem; display: block; margin-top: 0.5rem;\">You have to reload the browser tab to apply changes to this setting.</span>";
}
}
return settingsContainer;
}
function initCraftingSettings()
{
var craftingItems = document.getElementById('tab-sub-container-crafting');
if (!craftingItems)
{
return;
}
var br = craftingItems.nextElementSibling;
var after = br.nextElementSibling;
var parent = after.parentElement;
var settingList = [KEY.hideCraftingRecipes, KEY.hideUselessItems];
var settingsContainer = createSettingsContainer(settingList);
parent.insertBefore(settingsContainer, after);
}
function initChatSettings()
{
var controlDiv = document.querySelector('#div-chat > div:first-child');
if (!controlDiv)
{
return;
}
var btn = document.createElement('button');
btn.textContent = 'Chat Settings';
controlDiv.appendChild(btn);
var dialog = document.createElement('div');
dialog.id = 'dialog-chat-settings';
dialog.style.display = 'none';
dialog.innerHTML = "<h2 style=\"margin-top: 0\">Chat Settings</h2>";
var settingList = [KEY.useNewChat, KEY.colorizeChat, KEY.intelligentScrolling, KEY.showTimestamps, KEY.showIcons, KEY.showTags];
var settingsContainer = createSettingsContainer(settingList);
dialog.appendChild(settingsContainer);
document.body.appendChild(dialog);
btn.addEventListener('click', function ()
{
window.$(dialog).dialog();
});
}
function init()
{
initProxies();
initSettingsStyle();
initSettingTable();
initCraftingSettings();
initChatSettings();
}
settings.init = init;
var _a;
})(settings || (settings = {}));
/**
* Code from https://github.com/davidmerfield/randomColor
*/
var colorGenerator;
(function (colorGenerator)
{
// seed to get repeatable colors
var seed = null;
var COLOR_NOT_FOUND = {
hueRange: []
, lowerBounds: []
, saturationRange: []
, brightnessRange: []
};
var COLOR_BOUNDS = {
'monochrome':
{
hueRange: []
, lowerBounds: [
[0, 0]
, [100, 0]
]
}
, 'red':
{
hueRange: [-26, 18]
, lowerBounds: [
[20, 100]
, [30, 92]
, [40, 89]
, [50, 85]
, [60, 78]
, [70, 70]
, [80, 60]
, [90, 55]
, [100, 50]
]
}
, 'orange':
{
hueRange: [19, 46]
, lowerBounds: [
[20, 100]
, [30, 93]
, [40, 88]
, [50, 86]
, [60, 85]
, [70, 70]
, [100, 70]
]
}
, 'yellow':
{
hueRange: [47, 62]
, lowerBounds: [
[25, 100]
, [40, 94]
, [50, 89]
, [60, 86]
, [70, 84]
, [80, 82]
, [90, 80]
, [100, 75]
]
}
, 'green':
{
hueRange: [63, 178]
, lowerBounds: [
[30, 100]
, [40, 90]
, [50, 85]
, [60, 81]
, [70, 74]
, [80, 64]
, [90, 50]
, [100, 40]
]
}
, 'blue':
{
hueRange: [179, 257]
, lowerBounds: [
[20, 100]
, [30, 86]
, [40, 80]
, [50, 74]
, [60, 60]
, [70, 52]
, [80, 44]
, [90, 39]
, [100, 35]
]
}
, 'purple':
{
hueRange: [258, 282]
, lowerBounds: [
[20, 100]
, [30, 87]
, [40, 79]
, [50, 70]
, [60, 65]
, [70, 59]
, [80, 52]
, [90, 45]
, [100, 42]
]
}
, 'pink':
{
hueRange: [283, 334]
, lowerBounds: [
[20, 100]
, [30, 90]
, [40, 86]
, [60, 84]
, [80, 80]
, [90, 75]
, [100, 73]
]
}
};
// shared color dictionary
var colorDictionary = {};
function defineColor(name, hueRange, lowerBounds)
{
var _a = lowerBounds[0]
, sMin = _a[0]
, bMax = _a[1];
var _b = lowerBounds[lowerBounds.length - 1]
, sMax = _b[0]
, bMin = _b[1];
colorDictionary[name] = {
hueRange: hueRange
, lowerBounds: lowerBounds
, saturationRange: [sMin, sMax]
, brightnessRange: [bMin, bMax]
};
}
function loadColorBounds()
{
for (var name_1 in COLOR_BOUNDS)
{
defineColor(name_1, COLOR_BOUNDS[name_1].hueRange, COLOR_BOUNDS[name_1].lowerBounds);
}
}
function randomWithin(min, max)
{
if (min === void 0)
{
min = 0;
}
if (max === void 0)
{
max = 0;
}
if (seed === null)
{
return Math.floor(min + Math.random() * (max + 1 - min));
}
else
{
// seeded random algorithm from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
seed = (seed * 9301 + 49297) % 233280;
var rnd = seed / 233280.0;
return Math.floor(min + rnd * (max - min));
}
}
function getColorInfo(hue)
{
// maps red colors to make picking hue easier
if (hue >= 334 && hue <= 360)
{
hue -= 360;
}
for (var colorName in colorDictionary)
{
var color = colorDictionary[colorName];
if (color.hueRange.length > 0
&& hue >= color.hueRange[0]
&& hue <= color.hueRange[1])
{
return colorDictionary[colorName];
}
}
return COLOR_NOT_FOUND;
}
function getHueRange(colorInput)
{
var number = typeof colorInput === 'undefined' ? Number.NaN : colorInput;
if (typeof number === 'string')
{
number = parseInt(number, 10);
}
if (colorInput && isNaN(number) && colorDictionary.hasOwnProperty(colorInput))
{
var color = colorDictionary[colorInput];
if (color.hueRange.length > 0)
{
return color.hueRange;
}
}
else if (!isNaN(number) && number < 360 && number > 0)
{
return [number, number];
}
return [0, 360];
}
function pickHue(options)
{
var hueRange = getHueRange(options.hue);
var hue = randomWithin(hueRange[0], hueRange[1]);
// instead of storing red as two seperate ranges, we group them, using negative numbers
if (hue < 0)
{
return 360 + hue;
}
return hue;
}
function getSaturationRange(hue)
{
return getColorInfo(hue).saturationRange;
}
function pickSaturation(hue, options)
{
if (options.luminosity === 'random')
{
return randomWithin(0, 100);
}
if (options.hue === 'monochrome')
{
return 0;
}
var _a = getSaturationRange(hue)
, sMin = _a[0]
, sMax = _a[1];
switch (options.luminosity)
{
case 'bright':
sMin = 55;
break;
case 'dark':
sMin = sMax - 10;
break;
case 'light':
sMax = 55;
break;
}
return randomWithin(sMin, sMax);
}
function getMinimumBrightness(H, S)
{
var lowerBounds = getColorInfo(H).lowerBounds;
for (var i = 0; i < lowerBounds.length - 1; i++)
{
var _a = lowerBounds[i]
, s1 = _a[0]
, v1 = _a[1];
var _b = lowerBounds[i + 1]
, s2 = _b[0]
, v2 = _b[1];
if (S >= s1 && S <= s2)
{
var m = (v2 - v1) / (s2 - s1);
var b = v1 - m * s1;
return m * S + b;
}
}
return 0;
}
function pickBrightness(H, S, options)
{
var bMin = getMinimumBrightness(H, S);
var bMax = 100;
switch (options.luminosity)
{
case 'dark':
bMax = bMin + 20;
break;
case 'light':
bMin = (bMax + bMin) / 2;
break;
case 'random':
bMin = 0;
bMax = 100;
break;
}
return randomWithin(bMin, bMax);
}
function HSVtoHSL(hsv)
{
var h = hsv[0];
var s = hsv[1] / 100;
var v = hsv[2] / 100;
var k = (2 - s) * v;
return [
h
, Math.round(s * v / (k < 1 ? k : 2 - k) * 10000) / 100
, k / 2 * 100
];
}
function HSVtoRGB(hsv)
{
// this doesn't work for the values of 0 and 360 here's the hacky fix
var h = Math.min(Math.max(hsv[0], 1), 359);
// Rebase the h,s,v values
h = h / 360;
var s = hsv[1] / 100;
var v = hsv[2] / 100;
var h_i = Math.floor(h * 6);
var f = h * 6 - h_i;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
var r = 256;
var g = 256;
var b = 256;
switch (h_i)
{
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
case 5:
r = v;
g = p;
b = q;
break;
}
return [Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)];
}
function HSVtoHex(hsv)
{
function componentToHex(c)
{
var hex = c.toString(16);
return hex.length == 1 ? '0' + hex : hex;
}
var rgb = HSVtoRGB(hsv);
return '#' + componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);
}
function setFormat(hsv, options)
{
switch (options.format)
{
case 'hsvArray':
return hsv;
case 'hslArray':
return HSVtoHSL(hsv);
case 'hsl':
var hsl = HSVtoHSL(hsv);
return 'hsl(' + hsl[0] + ', ' + hsl[1] + '%, ' + hsl[2] + '%)';
case 'hsla':
var hslColor = HSVtoHSL(hsv);
var alpha = options.alpha || Math.random();
return 'hsla(' + hslColor[0] + ', ' + hslColor[1] + '%, ' + hslColor[2] + '%, ' + alpha + ')';
case 'rgbArray':
return HSVtoRGB(hsv);
case 'rgb':
var rgb = HSVtoRGB(hsv);
return 'rgb(' + rgb.join(', ') + ')';
case 'rgba':
var rgbColor = HSVtoRGB(hsv);
var alpha = options.alpha || Math.random();
return 'rgba(' + rgbColor.join(', ') + ', ' + alpha + ')';
case 'hex':
default:
return HSVtoHex(hsv);
}
}
function generateColor(options)
{
// pick a hue (H)
var H = pickHue(options);
// use H to determine saturation (S)
var S = pickSaturation(H, options);
// use S and H to determine brightness (B)
var B = pickBrightness(H, S, options);
// return the HSB color in the desired format
return setFormat([H, S, B], options);
}
function getRandom(options)
{
options = options ||
{};
seed = options.seed == null ? null : options.seed;
// check if we need to generate multiple colors
if (options.count !== null && options.count !== undefined)
{
var totalColors = options.count;
var colors = [];
options.count = null;
while (totalColors > colors.length)
{
// Since we're generating multiple colors, the seed has to be incrememented.
// Otherwise we'd just generate the same color each time...
if (seed !== null)
{
seed += 1;
}
colors.push(generateColor(options));
}
options.count = totalColors;
return colors;
}
return generateColor(options);
}
colorGenerator.getRandom = getRandom;
var ColorInterval = (function ()
{
function ColorInterval(start, end)
{
this.start = start;
this.end = end;
this.left = null;
this.right = null;
this.value = null;
}
ColorInterval.prototype.getNextValue = function ()
{
if (this.value == null)
{
this.value = (this.start + this.end) / 2;
return this.value;
}
if (this.left == null)
{
this.left = new ColorInterval(this.start, this.value);
return this.left.getNextValue();
}
if (this.right == null)
{
this.right = new ColorInterval(this.value, this.end);
return this.right.getNextValue();
}
if (this.left.getHeight() <= this.right.getHeight())
{
return this.left.getNextValue();
}
else
{
return this.right.getNextValue();
}
};
ColorInterval.prototype.getHeight = function ()
{
return 1
+ (this.left == null ? 0 : this.left.getHeight())
+ (this.right == null ? 0 : this.right.getHeight());
};
return ColorInterval;
}());
var rootInterval = new ColorInterval(0, 360);
function getEquallyDistributed()
{
return 'hsl(' + rootInterval.getNextValue() + ', 100%, 80%)';
}
colorGenerator.getEquallyDistributed = getEquallyDistributed;
// populate the color dictionary
loadColorBounds();
})(colorGenerator || (colorGenerator = {}));
/**
* notifications
*/
var notifications;
(function (notifications)
{
notifications.name = 'notifications';
function event(title, options)
{
if ((!options || options.whenActive !== true) && !document.hidden && document.hasFocus())
{
return;
}
if (!settings.get(settings.KEY.showNotifications))
{
// notifications disabled: return stub notification
return Promise.resolve(
{
close: function () {}
});
}
if (!("Notification" in window))
{
return Promise.reject('Your browser does not support notifications.');
}
return Notification.requestPermission()
.then(function (permission)
{
if (permission === 'granted')
{
var n_1 = new Notification(title, options);
n_1.onclick = function (event)
{
if (options && options.autoFocus !== false)
{
window.focus();
}
if (options && options.autoClose !== false)
{
n_1.close();
}
if (options && options.onclick)
{
options.onclick(n_1, event);
}
};
return Promise.resolve(n_1);
}
else
{
return Promise.reject('Notification permission denied');
}
});
}
notifications.event = event;
function requestPermission()
{
if (settings.get(settings.KEY.showNotifications))
{
Notification.requestPermission();
}
}
function init()
{
requestPermission();
settings.observe(settings.KEY.showNotifications, function ()
{
return requestPermission();
});
}
notifications.init = init;
})(notifications || (notifications = {}));
/**
* game events
*/
var gameEvents;
(function (gameEvents)
{
gameEvents.name = 'gameEvents';
// min time difference between two notifications with the same title (10 seconds)
var MIN_TIME_DIFFERENCE = 10;
gameEvents.enabled = {
smelting: true
, chopping: true
, harvest: true
, boat: true
, battle: true
, brewing: true
, market: true
};
var lastTimestamp = new Map();
function notifyTabClickable(title, body, icon, tabName)
{
var now = (new Date).getTime();
var timeDiff = now - (lastTimestamp.get(title) || 0);
if (timeDiff < MIN_TIME_DIFFERENCE * 1e3)
{
return;
}
if (document.hidden || !document.hasFocus())
{
lastTimestamp.set(title, now);
notifications.event(title
, {
body: body
, icon: 'images/' + icon
, onclick: function ()
{
window.openTab(tabName);
}
});
}
}
function observeTimer(k, fn)
{
observer.add(k, function (key, oldValue, newValue)
{
if (oldValue > 0 && newValue == 0)
{
fn(key, oldValue, newValue);
}
});
}
function smelting()
{
observeTimer('smeltingPercD', function (key, oldValue, newValue)
{
if (!gameEvents.enabled.smelting)
{
return;
}
notifyTabClickable('Hot topic', 'Your smelting has finished.', getFurnaceLevelName() + 'Furnace.png', 'crafting');
});
}
function chopping()
{
observer.add([
'treeStage1'
, 'treeStage2'
, 'treeStage3'
, 'treeStage4'
, 'treeStage5'
, 'treeStage6'
], function (key, oldValue, newValue)
{
if (!gameEvents.enabled.chopping)
{
return;
}
if (newValue == 4)
{
notifyTabClickable('Wood you be mine?', 'One or more of your trees are fully grown and can be chopped.', 'icons/woodcutting.png', 'woodcutting');
}
});
}
function harvest()
{
observer.add([
'farmingPatchStage1'
, 'farmingPatchStage2'
, 'farmingPatchStage3'
, 'farmingPatchStage4'
, 'farmingPatchStage5'
, 'farmingPatchStage6'
], function (key, oldValue, newValue)
{
if (!gameEvents.enabled.harvest)
{
return;
}
if (newValue == 4)
{
notifyTabClickable('Green thumb', 'One or more of your crops is ready for harvest.', 'icons/watering-can.png', 'farming');
}
else if (newValue > 4)
{
notifyTabClickable('I didn\'t plant this', 'One or more of your crops died.', 'icons/watering-can.png', 'farming');
}
});
}
function boat()
{
observeTimer([
'rowBoatTimer'
, 'canoeTimer'
], function (k, oldValue, newValue)
{
if (!gameEvents.enabled.boat)
{
return;
}
var key = k.replace(/Timer$/, '');
notifyTabClickable('Fishy business', 'Your ' + split2Words(key).toLowerCase() + ' returned from its trip.', key + '.png', 'combat');
});
}
function battle()
{
observeTimer('combatGlobalCooldown', function (key, oldValue, newValue)
{
if (!gameEvents.enabled.battle)
{
return;
}
notifyTabClickable('Ready to work', 'Your hero is eager to fight.', 'icons/combat.png', 'combat');
});
}
function brewing()
{
observeTimer([
'barPotionTimer'
, 'seedPotionTimer'
, 'stardustPotionTimer'
, 'superStardustPotionTimer'
], function (key, oldValue, newValue)
{
if (!gameEvents.enabled.brewing)
{
return;
}
var potionKey = key.replace(/Timer$/, '');
if (getGameValue(potionKey) > 0)
{
notifyTabClickable('Cheers!', 'You can drink another ' + split2Words(potionKey) + '.', key.replace(/Timer$/, '') + '.png', 'brewing');
}
});
}
function market()
{
var _refreshMarketSlot = window.refreshMarketSlot;
window.refreshMarketSlot = function (offerId, itemName, amount, price, collectText, slotId, timeLeft)
{
if (gameEvents.enabled.market && collectText > 0)
{
notifyTabClickable('Ka-ching', 'You\'ve sold ' + (amount > 0 ? 'some' : 'all') + ' ' + split2Words(itemName).toLowerCase() + ' to the market.', 'icons/shop.png', 'playermarket');
}
_refreshMarketSlot(offerId, itemName, amount, price, collectText, slotId, timeLeft);
};
}
function gameValues()
{
observer.add('treasureMap', function (key, oldValue, newValue)
{
if (oldValue > newValue)
{
notifyTabClickable('Arrrr!', 'Your pirate found a treasure map.', 'treasureMap.png', 'items');
}
});
}
function init()
{
smelting();
chopping();
harvest();
boat();
battle();
brewing();
market();
gameValues();
}
gameEvents.init = init;
})(gameEvents || (gameEvents = {}));
/**
* hide crafting recipes of lower tiers or of maxed machines
*/
var hideCraftedRecipes;
(function (hideCraftedRecipes)
{
hideCraftedRecipes.name = 'hideCraftedRecipes';
function setRecipeVisibility(key, visible)
{
var recipeRow = document.getElementById('crafting-' + key);
if (recipeRow)
{
recipeRow.style.display = (!settings.get(settings.KEY.hideCraftingRecipes) || visible) ? '' : 'none';
}
}
function hideLeveledRecipes(max, getKey, init)
{
if (init === void 0)
{
init = false;
}
var keys2Observe = [];
var maxLevel = 0;
for (var i = max - 1; i >= 0; i--)
{
var level = i + 1;
var key = getKey(i);
var boundKey = getBoundKey(key);
keys2Observe.push(key);
keys2Observe.push(boundKey);
if (getGameValue(key) > 0 || getGameValue(boundKey) > 0)
{
maxLevel = Math.max(maxLevel, level);
}
setRecipeVisibility(key, level > maxLevel);
}
if (init)
{
observer.add(keys2Observe, function ()
{
return hideLeveledRecipes(max, getKey, false);
});
}
}
function hideToolRecipe(key, init)
{
if (init === void 0)
{
init = false;
}
var emptyKey = getTierKey(key, 0);
var keys2Observe = [emptyKey];
var hasTool = getGameValue(emptyKey) > 0;
for (var i = 0; i < TIER_LEVELS.length; i++)
{
var boundKey = getBoundKey(getTierKey(key, i));
hasTool = hasTool || getGameValue(boundKey) > 0;
keys2Observe.push(boundKey);
}
setRecipeVisibility(emptyKey, !hasTool);
if (init)
{
observer.add(keys2Observe, function ()
{
return hideToolRecipe(key, false);
});
}
}
function hideRecipe(key, hideInfo, init)
{
if (init === void 0)
{
init = false;
}
var maxValue = typeof hideInfo.max === 'function' ? hideInfo.max() : hideInfo.max;
var boundKey = getBoundKey(key);
var unbound = getGameValue(key);
var bound = getGameValue(boundKey);
var extra = (hideInfo.extraKeys || []).map(function (k)
{
return getGameValue(k);
}).reduce(function (p, c)
{
return p + c;
}, 0);
setRecipeVisibility(key, (bound + unbound + extra) < maxValue);
if (init)
{
observer.add([key, boundKey], function ()
{
return hideRecipe(key, hideInfo, false);
});
}
}
function init()
{
function processRecipes(init)
{
if (init === void 0)
{
init = false;
}
// furnace
hideLeveledRecipes(FURNACE_LEVELS.length, function (i)
{
return FURNACE_LEVELS[i] + 'Furnace';
}, init);
// oil storage
hideLeveledRecipes(OIL_STORAGE_SIZES.length, function (i)
{
return 'oilStorage' + (i + 1);
}, init);
// oven recipes
hideLeveledRecipes(OVEN_LEVELS.length, function (i)
{
return OVEN_LEVELS[i] + 'Oven';
}, init);
// tools
for (var _i = 0, TIER_ITEMS_1 = TIER_ITEMS; _i < TIER_ITEMS_1.length; _i++)
{
var tool = TIER_ITEMS_1[_i];
hideToolRecipe(tool, init);
}
// other stuff
for (var key in HIDE_RECIPES)
{
hideRecipe(key, HIDE_RECIPES[key], init);
}
if (init)
{
settings.observe(settings.KEY.hideCraftingRecipes, function ()
{
return processRecipes(false);
});
}
}
processRecipes(true);
var _processCraftingTab = window.processCraftingTab;
window.processCraftingTab = function ()
{
var reinit = !!window.refreshLoadCraftingTable;
_processCraftingTab();
if (reinit)
{
processRecipes(false);
}
};
}
hideCraftedRecipes.init = init;
})(hideCraftedRecipes || (hideCraftedRecipes = {}));
/**
* hide useless items
*/
var hideUselessItems;
(function (hideUselessItems)
{
hideUselessItems.name = 'hideUselessItems';
function setItemVisibility(key, visible)
{
var itemBox = document.getElementById('item-box-' + key);
if (itemBox)
{
itemBox.style.display = getGameValue(key) > 0 && (!settings.get(settings.KEY.hideUselessItems) || visible) ? '' : 'none';
}
}
function hideLeveledItems(max, getKey, init)
{
if (init === void 0)
{
init = false;
}
var keys2Observe = [];
var maxLevel = 0;
for (var i = max - 1; i >= 0; i--)
{
var level = i + 1;
var key = getKey(i);
var boundKey = getBoundKey(key);
keys2Observe.push(key);
keys2Observe.push(boundKey);
if (getGameValue(boundKey) > 0)
{
maxLevel = Math.max(maxLevel, level);
}
setItemVisibility(key, level > maxLevel);
}
if (init)
{
observer.add(keys2Observe, function ()
{
return hideLeveledItems(max, getKey, false);
});
}
}
function hideItem(key, hideInfo, init)
{
if (init === void 0)
{
init = false;
}
var maxValue = typeof hideInfo.max === 'function' ? hideInfo.max() : hideInfo.max;
var boundKey = getBoundKey(key);
var bound = getGameValue(boundKey);
var extra = (hideInfo.extraKeys || []).map(function (k)
{
return getGameValue(k);
}).reduce(function (p, c)
{
return p + c;
}, 0);
setItemVisibility(key, (bound + extra) < maxValue);
if (init)
{
observer.add([key, boundKey], function ()
{
return hideItem(key, hideInfo, false);
});
}
}
function init()
{
function processItems(init)
{
if (init === void 0)
{
init = false;
}
// furnace
hideLeveledItems(FURNACE_LEVELS.length, function (i)
{
return FURNACE_LEVELS[i] + 'Furnace';
}, init);
// oil storage
hideLeveledItems(OIL_STORAGE_SIZES.length, function (i)
{
return 'oilStorage' + (i + 1);
}, init);
// oven recipes
hideLeveledItems(OVEN_LEVELS.length, function (i)
{
return OVEN_LEVELS[i] + 'Oven';
}, init);
// other stuff
for (var key in HIDE_RECIPES)
{
hideItem(key, HIDE_RECIPES[key], init);
}
if (init)
{
settings.observe(settings.KEY.hideUselessItems, function ()
{
return processItems(false);
});
}
}
processItems(true);
}
hideUselessItems.init = init;
})(hideUselessItems || (hideUselessItems = {}));
/**
* improve item boxes
*/
var improveItemBoxes;
(function (improveItemBoxes)
{
improveItemBoxes.name = 'improveItemBoxes';
function hideNumberInItemBox(key, setVisibility)
{
if (setVisibility === void 0)
{
setVisibility = false;
}
var itemBox = document.getElementById('item-box-' + key);
if (!itemBox)
{
return;
}
var numberElement = itemBox.lastElementChild;
if (!numberElement)
{
return;
}
if (setVisibility)
{
numberElement.style.visibility = 'hidden';
}
else
{
numberElement.style.display = 'none';
}
}
function addSpan2ItemBox(key)
{
hideNumberInItemBox(key);
var itemBox = document.getElementById('item-box-' + key);
if (!itemBox)
{
return;
}
var span = document.createElement('span');
itemBox.appendChild(span);
return span;
}
function setOilPerSecond(span, oil)
{
span.innerHTML = "+ " + format.number(oil) + " L/s <img src=\"images/oil.png\" class=\"image-icon-20\" style=\"margin-top: -2px;\">";
}
// show capacity of furnace
function addFurnaceCaption()
{
for (var i = 0; i < FURNACE_LEVELS.length; i++)
{
var key = FURNACE_LEVELS[i] + 'Furnace';
var boundKey = getBoundKey(key);
var capacitySpan = addSpan2ItemBox(boundKey);
if (capacitySpan)
{
capacitySpan.className = 'capacity';
capacitySpan.textContent = 'Capacity: ' + format.number(window.getFurnaceCapacity(boundKey));
}
}
}
// show oil cap of oil storage
function addOilStorageCaption()
{
for (var i = 0; i < OIL_STORAGE_SIZES.length; i++)
{
var key = 'oilStorage' + (i + 1);
var capSpan = addSpan2ItemBox(getBoundKey(key));
if (capSpan)
{
capSpan.className = 'oil-cap';
capSpan.textContent = 'Oil cap: ' + format.number(OIL_STORAGE_SIZES[i]);
}
}
}
// show oil per second
function addOilCaption()
{
var handheldOilSpan = addSpan2ItemBox('handheldOilPump');
if (handheldOilSpan)
{
setOilPerSecond(handheldOilSpan, 1 * window.miner);
observer.add('miner', function ()
{
return setOilPerSecond(handheldOilSpan, 1 * window.miner);
});
}
var oilPipeSpan = addSpan2ItemBox('boundOilPipe');
if (oilPipeSpan)
{
setOilPerSecond(oilPipeSpan, 50);
}
// add number of workers as caption to oil factory
var workerSpan = addSpan2ItemBox('boundOilFactory');
if (workerSpan)
{
var setCaption_1 = function ()
{
return workerSpan.textContent = 'Workers: ' + window.oilFactoryWorkers;
};
setCaption_1();
observer.add('oilFactoryWorkers', function ()
{
return setCaption_1;
});
}
}
function hideNumberCaption()
{
hideNumberInItemBox('emptyAnvil', true);
hideNumberInItemBox('tap', true);
hideNumberInItemBox('farmer', true);
hideNumberInItemBox('planter', true);
hideNumberInItemBox('cooksBook', true);
hideNumberInItemBox('cooksPage', true);
hideNumberInItemBox('combatDropTable', true);
}
// show current tier
function addTierCaption()
{
for (var _i = 0, TIER_ITEMS_2 = TIER_ITEMS; _i < TIER_ITEMS_2.length; _i++)
{
var tierItem = TIER_ITEMS_2[_i];
for (var i = 0; i < TIER_LEVELS.length; i++)
{
var key = getTierKey(tierItem, i);
var toolKey = tierItem == 'rake' ? key : getBoundKey(key);
var tierSpan = addSpan2ItemBox(toolKey);
if (tierSpan)
{
tierSpan.className = 'tier';
tierSpan.textContent = TIER_NAMES[i];
}
}
}
}
var boatKeys = ['rowBoat', 'canoe'];
var boatTimerKeys = boatKeys.map(function (k)
{
return k + 'Timer';
});
function checkBoat(span, timerKey, init)
{
if (init === void 0)
{
init = false;
}
var isInTransit = getGameValue(timerKey) > 0;
var otherInTransit = boatTimerKeys.some(function (k)
{
return k != timerKey && getGameValue(k) > 0;
});
span.textContent = isInTransit ? 'In transit' : 'Ready';
span.style.visibility = otherInTransit ? 'hidden' : '';
if (init)
{
observer.add(boatTimerKeys, function ()
{
return checkBoat(span, timerKey, false);
});
}
}
// show boat progress
function addBoatCaption()
{
for (var i = 0; i < boatKeys.length; i++)
{
var span = addSpan2ItemBox(getBoundKey(boatKeys[i]));
if (span)
{
checkBoat(span, boatTimerKeys[i], true);
}
}
}
// show bonemeal
function addBonemealCaption()
{
var noBonemealSpan = addSpan2ItemBox('boundBonemealBin');
if (!noBonemealSpan)
{
return;
}
noBonemealSpan.textContent = 'Bonemeal: 0';
var bonemealSpan = addSpan2ItemBox('boundFilledBonemealBin');
if (!bonemealSpan)
{
return;
}
bonemealSpan.dataset.itemDisplay = 'bonemeal';
bonemealSpan.textContent = format.number(window.bonemeal);
var captionSpan = document.createElement('span');
captionSpan.textContent = 'Bonemeal: ';
bonemealSpan.parentElement.insertBefore(captionSpan, bonemealSpan);
}
function warningBeforeSellingGems()
{
var _sellNPCItemDialogue = window.sellNPCItemDialogue;
window.sellNPCItemDialogue = function (item, amount)
{
if (item == 'sapphire' || item == 'emerald' || item == 'ruby' || item == 'diamond' || item == 'bloodDiamond')
{
var itemName = key2Name(amount == 1 ? item : item.replace(/y$/, 'ie') + 's', true);
if (amount == 0
|| !window.confirm('Gems are precious and rare. Please consider carefully:\nDo you really want to sell ' + amount + ' ' + itemName + '?'))
{
return;
}
}
else if (item == 'logs' || item == 'oakLogs' || item == 'willowLogs' || item == 'mapleLogs' || item == 'stardustLogs' || item == 'ancientLogs')
{
var itemName = key2Name(amount == 1 ? item.replace(/s$/, '') : item, true);
if (amount == 0
|| !window.confirm('Logs are time consuming to collect. Please consider carefully:\nDo you really want to sell ' + amount + ' ' + itemName + '?'))
{
return;
}
}
_sellNPCItemDialogue(item, amount);
};
}
function init()
{
addFurnaceCaption();
addOilStorageCaption();
addOilCaption();
hideNumberCaption();
addTierCaption();
addBoatCaption();
addBonemealCaption();
warningBeforeSellingGems();
}
improveItemBoxes.init = init;
})(improveItemBoxes || (improveItemBoxes = {}));
/**
* add new chat
*/
var chat;
(function (chat)
{
chat.name = 'chat';
var KEYWORD_LIST_KEY = 'keywordList';
var keywordList = store.get(KEYWORD_LIST_KEY) || [];
var CHAT_HISTORY_KEY = 'chatHistory';
var MAX_CHAT_HISTORY_LENGTH = 100;
var Type;
(function (Type)
{
Type[Type["reload"] = -1] = "reload";
Type[Type["normal"] = 0] = "normal";
Type[Type["pmReceived"] = 1] = "pmReceived";
Type[Type["pmSent"] = 2] = "pmSent";
Type[Type["serverMsg"] = 3] = "serverMsg";
})(Type || (Type = {}));;
var Tag;
(function (Tag)
{
Tag[Tag["none"] = 0] = "none";
Tag[Tag["donor"] = 1] = "donor";
Tag[Tag["contributor"] = 2] = "contributor";
Tag[Tag["mod"] = 3] = "mod";
Tag[Tag["dev"] = 4] = "dev";
Tag[Tag["server"] = 5] = "server";
})(Tag || (Tag = {}));;
/**
* The chunk hiding starts with at least 10 chunks.
* So there are at least
* (chunkHidingMinChunks-1) * msgChunkSize + 1 = 9 * 100 + 1 = 901
* messages before the chunk hiding mechanism starts.
*/
var CHUNK_HIDING_MIN_CHUNKS = 10;
var MSG_CHUNK_SIZE = 100;
var RELOADED_CHAT_DATA = {
timestamp: 0
, username: ''
, userlevel: 0
, icon: 0
, tag: 0
, type: Type.reload
, msg: '[...]'
};
var CHAT_BOX_ID = 'div-chat';
var DEFAULT_CHAT_DIV_ID = 'div-chat-area';
var GENERAL_CHAT_DIV_ID = 'div-chat-general';
var PM_CHAT_TAB_PREFIX = 'tab-chat-pm-';
var PM_CHAT_DIV_PREFIX = 'div-chat-pm-';
var CHAT_TABS_ID = 'chat-tabs';
var CHAT_INPUT_ID = 'chat-input-text';
var CHAT_CLASS = 'div-chat-area';
var COLORIZE_CLASS = 'colorize';
var SpecialTab;
(function (SpecialTab)
{
SpecialTab[SpecialTab["default"] = 0] = "default";
SpecialTab[SpecialTab["general"] = 1] = "general";
SpecialTab[SpecialTab["filler"] = 2] = "filler";
})(SpecialTab || (SpecialTab = {}));;
var CHAT_SPECIAL_TAB_ID = (_a = {}
, _a[SpecialTab.default] = 'tab-chat-default'
, _a[SpecialTab.general] = 'tab-chat-general'
, _a[SpecialTab.filler] = 'tab-chat-filler'
, _a);
var CONTEXTMENU_ID = 'player-contextmenu';
var CHAT_ICONS = [
null
, {
key: 'halloween2015'
, title: 'Halloween 2015'
}
, {
key: 'christmas2015'
, title: 'Chirstmas 2015'
}
, {
key: 'easter2016'
, title: 'Holiday'
}
, {
key: 'halloween2016'
, title: 'Halloween 2016'
}
, {
key: 'christmas2016'
, title: 'Chirstmas 2016'
}
, {
key: 'dh1Max'
, title: 'Max Level in DH1'
}
, {
key: 'hardcore'
, title: 'Hardcore Account'
}
, {
key: 'quest'
, title: 'Questmaster'
}
];
var CHAT_TAGS = [
null
, {
key: 'donor'
, name: ''
}
, {
key: 'contributor'
, name: 'Contributor'
}
, {
key: 'mod'
, name: 'Moderator'
}
, {
key: 'dev'
, name: 'Dev'
}
, {
key: 'yell'
, name: 'Server Message'
}
];
var LOCALE = 'en-US';
var LOCALE_OPTIONS = {
hour12: false
, year: 'numeric'
, month: 'long'
, day: 'numeric'
, hour: '2-digit'
, minute: '2-digit'
, second: '2-digit'
};
var TUTORIAL_CMD = 'tutorial';
var KEYWORD_ADD_CMD = 'keyword add';
var KEYWORD_REMOVE_CMD = 'keyword remove';
// load chat history
var chatHistory = store.get(CHAT_HISTORY_KEY) || [];
// find index of last message which is not a pm
var isLastMsgNotReload = false;
for (var i = chatHistory.length - 1; i >= 0; i--)
{
if (!isDataPM(chatHistory[i]))
{
isLastMsgNotReload = chatHistory[i].type != Type.reload;
break;
}
}
// insert a placeholder for a reloaded chat
if (isLastMsgNotReload)
{
RELOADED_CHAT_DATA.timestamp = (new Date()).getTime();
chatHistory.push(RELOADED_CHAT_DATA);
}
// store chat colors for each user
var user2Color = new Map();
var usedColors = new Set();
// reserve color for special messages (e.g. server messages): white
usedColors.add('#ffffff');
function isMuted(user)
{
// ATTENTION: this will filter all people who are named similar to one of the muted people!
return window.mutedPeople.some(function (name)
{
return user.indexOf(name) > -1;
});
// return window.mutedPeople.indexOf(user) !== -1;
}
function isSpam(data)
{
// allow all messages from contributors, mods, devs and all server messages
if (data.tag != Tag.none)
{
return false;
}
/**
* get last message of current user
*/
var isThisPm = isDataPM(data);
var msgUsername = data.type === Type.pmSent ? window.username : data.username;
var historyIndex = chatHistory.indexOf(data);
if (historyIndex == -1)
{
historyIndex = chatHistory.length;
}
var lastData = null;
for (var i = historyIndex - 1; i >= 0 && (lastData === null); i--)
{
var dataBefore = chatHistory[i];
if (isThisPm === isDataPM(dataBefore))
{
var beforeUsername = dataBefore.type == Type.pmSent ? window.username : dataBefore.username;
if (beforeUsername === msgUsername)
{
lastData = dataBefore;
}
}
}
/**
* compare message and don't allow the same message twice
*/
if (lastData
&& lastData.msg === data.msg
&& (data.timestamp - lastData.timestamp) < 10e3)
{
return true;
}
return false;
}
function handleScrolling(chatbox)
{
if (window.isAutoScrolling)
{
setTimeout(function ()
{
return chatbox.scrollTop = chatbox.scrollHeight;
});
}
}
// for chat messages which arrive before DOMContentLoaded and can not be displayed since the DOM isn't ready
var chatInitialized = false;
function processChatData(username, iconString, tagString, msg, isPM)
{
var tag = parseInt(tagString, 10);
var userlevel = 0;
var type = Type.normal;
if (isPM == 1)
{
var match = msg.match(/^\s*\[(.+) ([A-Za-z0-9 ]+)\]: (.+?)\s*$/) || ['', '', username, msg];
type = match[1] == 'Sent to' ? Type.pmSent : Type.pmReceived;
username = match[2];
msg = match[3];
}
else if (tag == Tag.server)
{
type = Type.serverMsg;
}
else
{
var match = msg.match(/^\s*\((\d+)\): (.+?)\s*$/);
if (match)
{
userlevel = parseInt(match[1], 10);
msg = match[2];
}
else
{
userlevel = window.getGlobalLevel();
}
}
// unlinkify when using DH2QoL to store the plain message
if (window.addToChatBox.toString().includes('linkify(arguments[3])'))
{
msg = msg.replace(/<a href='([^']+)' target='_blank'>\1<\/a>/ig, '$1');
}
if (type == Type.pmSent)
{
// turn some critical characters into HTML entities
msg = msg.replace(/[<>]/g, function (char)
{
return '&#' + char.charCodeAt(0) + ';';
});
}
return {
timestamp: now()
, username: username
, userlevel: userlevel
, icon: parseInt(iconString, 10)
, tag: tag
, type: type
, msg: msg
};
}
function add2ChatHistory(data)
{
chatHistory.push(data);
chatHistory = chatHistory.slice(-MAX_CHAT_HISTORY_LENGTH);
store.set(CHAT_HISTORY_KEY, chatHistory);
}
function username2Id(username)
{
return username.replace(/[ \+]/g, '_');
}
function getChatTab(username, specialTab)
{
var id = (specialTab != null)
? CHAT_SPECIAL_TAB_ID[specialTab]
: PM_CHAT_TAB_PREFIX + username2Id(username);
var tab = document.getElementById(id);
if (!tab)
{
tab = document.createElement('div');
tab.className = 'chat-tab';
if (specialTab != null)
{
tab.classList.add(SpecialTab[specialTab]);
}
tab.id = id;
tab.dataset.username = username;
tab.dataset.new = '0';
if (username.length > 2)
{
tab.textContent = username;
// thanks /u/Spino-Prime for pointing out this was missing
var closeSpan = document.createElement('span');
closeSpan.className = 'close';
tab.appendChild(closeSpan);
}
var chatTabs = document.getElementById(CHAT_TABS_ID);
var filler = chatTabs.querySelector('.filler');
if (filler)
{
chatTabs.insertBefore(tab, filler);
}
else
{
chatTabs.appendChild(tab);
}
}
return tab;
}
function getChatDiv(username)
{
var id = username == '' ? GENERAL_CHAT_DIV_ID : PM_CHAT_DIV_PREFIX + username2Id(username);
var div = document.getElementById(id);
if (!div)
{
div = document.createElement('div');
div.setAttribute('disabled', 'disabled');
div.id = id;
div.className = CHAT_CLASS;
var defaultChat = document.getElementById(DEFAULT_CHAT_DIV_ID);
var height = defaultChat.style.height;
div.style.height = height;
var chatDiv = defaultChat.parentElement;
chatDiv.insertBefore(div, defaultChat);
}
return div;
}
function changeChatTab(oldTab, newTab)
{
if (oldTab)
{
oldTab.classList.remove('selected');
var oldChatDiv = void 0;
if (oldTab.classList.contains('default'))
{
oldChatDiv = document.getElementById(DEFAULT_CHAT_DIV_ID);
}
else
{
oldChatDiv = getChatDiv(oldTab.dataset.username || '');
}
oldChatDiv.classList.remove('selected');
}
newTab.classList.add('selected');
newTab.dataset.new = '0';
var newChatDiv;
if (newTab.classList.contains('default'))
{
newChatDiv = document.getElementById(DEFAULT_CHAT_DIV_ID);
}
else
{
newChatDiv = getChatDiv(newTab.dataset.username || '');
}
newChatDiv.classList.add('selected');
var toUsername = newTab.dataset.username;
var newTextPlaceholder = toUsername == '' ? window.username + ':' : 'PM to ' + toUsername + ':';
document.getElementById(CHAT_INPUT_ID).placeholder = newTextPlaceholder;
if (window.isAutoScrolling)
{
setTimeout(function ()
{
return newChatDiv.scrollTop = newChatDiv.scrollHeight;
});
}
}
function closeChatTab(username)
{
// TODO: maybe delete pms stored for that user?
var oldTab = document.querySelector('#' + CHAT_TABS_ID + ' .chat-tab.selected');
var tab2Close = getChatTab(username, null);
if (oldTab.dataset.username == username)
{
var generalTab = getChatTab('', SpecialTab.general);
changeChatTab(tab2Close, generalTab);
}
var tabContainer = tab2Close.parentElement;
tabContainer.removeChild(tab2Close);
}
function isDataPM(data)
{
return data.type === Type.pmSent || data.type === Type.pmReceived;
}
var msgChunkMap = new Map();
var chatboxFragments = new Map();
function colorizeMsg(username)
{
if (username == '')
{
return null;
}
if (!user2Color.has(username))
{
var color = void 0;
do {
// color = colorGenerator.getRandom({ luminosity: 'light' });
color = colorGenerator.getEquallyDistributed();
} while (usedColors.has(color));
user2Color.set(username, color);
usedColors.add(color);
addStyle("\n#" + CHAT_BOX_ID + "." + COLORIZE_CLASS + " .chat-msg[data-username=\"" + username + "\"]\n{\n\tbackground-color: " + color + ";\n}\n\t\t\t", 'name-color');
}
return user2Color.get(username);
}
function createMessageSegment(data)
{
var isThisPm = isDataPM(data);
var msgUsername = data.type === Type.pmSent ? window.username : data.username;
var historyIndex = chatHistory.indexOf(data);
var isSameUser = null;
var isSameTime = null;
for (var i = historyIndex - 1; i >= 0 && (isSameUser === null || isSameTime === null); i--)
{
var dataBefore = chatHistory[i];
if (isThisPm === isDataPM(dataBefore))
{
if (isSameUser === null)
{
var beforeUsername = dataBefore.type == Type.pmSent ? window.username : dataBefore.username;
isSameUser = beforeUsername === msgUsername;
}
if (dataBefore.type != Type.reload)
{
isSameTime = Math.floor(data.timestamp / 1000 / 60) - Math.floor(dataBefore.timestamp / 1000 / 60) === 0;
}
}
}
var d = new Date(data.timestamp);
var hour = (d.getHours() < 10 ? '0' : '') + d.getHours();
var minute = (d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
var icon = CHAT_ICONS[data.icon] ||
{
key: ''
, title: ''
};
var tag = CHAT_TAGS[data.tag] ||
{
key: ''
, name: ''
};
var formattedMsg = data.msg
.replace(/<a href='(.+?)' target='_blank'>\1<\/a>/g, '$1')
.replace(/(https?:\/\/[^\s"<>]+)/g, '<a target="_blank" href="$1">$1</a>');
colorizeMsg(msgUsername);
var msgTitle = data.type == Type.reload ? 'Chat loaded on ' + d.toLocaleString(LOCALE, LOCALE_OPTIONS) : '';
var user = data.type === Type.serverMsg ? 'Server Message' : msgUsername;
var levelAppendix = data.type == Type.normal ? ' (' + data.userlevel + ')' : '';
var userTitle = data.tag != Tag.server ? tag.name : '';
return "<span class=\"chat-msg\" data-type=\"" + data.type + "\" data-tag=\"" + tag.key + "\" data-username=\"" + msgUsername + "\">"
+ ("<span\n\t\t\t\tclass=\"timestamp\"\n\t\t\t\tdata-timestamp=\"" + data.timestamp + "\"\n\t\t\t\tdata-same-time=\"" + isSameTime + "\">" + hour + ":" + minute + "</span>")
+ ("<span class=\"user\" data-name=\"" + msgUsername + "\" data-same-user=\"" + isSameUser + "\">")
+ ("<span class=\"icon " + icon.key + "\" title=\"" + icon.title + "\"></span>")
+ ("<span class=\"name chat-tag-" + tag.key + "\" title=\"" + userTitle + "\">" + user + levelAppendix + ":</span>")
+ "</span>"
+ ("<span class=\"msg\" title=\"" + msgTitle + "\">" + formattedMsg + "</span>")
+ "</span>";
}
function add2Chat(data)
{
if (!chatInitialized)
{
return;
}
var isThisPm = isDataPM(data);
// don't mute pms (you can just ignore pm-tab if you like)
if (!isThisPm && isMuted(data.username))
{
return;
}
var userKey = isThisPm ? data.username : '';
var chatTab = getChatTab(userKey, isThisPm ? null : SpecialTab.general);
if (!chatTab.classList.contains('selected'))
{
chatTab.dataset.new = (parseInt(chatTab.dataset.new || '0', 10) + 1).toString();
}
if (isThisPm)
{
window.lastPMUser = data.username;
}
// username is 3-12 characters long
var chatbox = getChatDiv(userKey);
var msgChunk = msgChunkMap.get(userKey);
if (!msgChunk || msgChunk.children.length >= MSG_CHUNK_SIZE)
{
msgChunk = document.createElement('div');
msgChunk.className = 'msg-chunk';
msgChunkMap.set(userKey, msgChunk);
if (chatboxFragments != null)
{
if (!chatboxFragments.has(userKey))
{
chatboxFragments.set(userKey, document.createDocumentFragment());
}
chatboxFragments.get(userKey).appendChild(msgChunk);
}
else
{
chatbox.appendChild(msgChunk);
}
}
var tmp = document.createElement('templateWrapper');
tmp.innerHTML = createMessageSegment(data);
msgChunk.appendChild(tmp.children[0]);
handleScrolling(chatbox);
}
function applyChatStyle()
{
addStyle("\nspan.chat-msg\n{\n\tdisplay: flex;\n\tpadding: 1px 0;\n}\n#" + CHAT_BOX_ID + ":not(." + COLORIZE_CLASS + ") span.chat-msg:nth-child(2n)\n{\n\tbackground-color: hsla(0, 0%, 90%, 1);\n}\n.chat-msg[data-type=\"" + Type.reload + "\"]\n{\n\tfont-size: 0.8rem;\n}\n.chat-msg .timestamp\n{\n\tdisplay: none;\n}\n#" + CHAT_BOX_ID + ".showTimestamps .chat-msg:not([data-type=\"" + Type.reload + "\"]) .timestamp\n{\n\tcolor: hsla(0, 0%, 50%, 1);\n\tdisplay: inline-block;\n\tfont-size: .9rem;\n\tmargin: 0;\n\tmargin-right: 5px;\n\tposition: relative;\n\twidth: 2.5rem;\n}\n.chat-msg .timestamp[data-same-time=\"true\"]\n{\n\tcolor: hsla(0, 0%, 50%, .1);\n}\n.chat-msg:not([data-type=\"" + Type.reload + "\"]) .timestamp:hover::after\n{\n\tbackground-color: hsla(0, 0%, 12%, 1);\n\tborder-radius: .2rem;\n\tcontent: attr(data-fulltime);\n\tcolor: hsla(0, 0%, 100%, 1);\n\tline-height: 1.35rem;\n\tpadding: .4rem .8rem;\n\tpointer-events: none;\n\tposition: absolute;\n\tleft: 2.5rem;\n\ttop: -0.4rem;\n\ttext-align: center;\n\twhite-space: nowrap;\n}\n\n#" + CHAT_BOX_ID + ".showTags .chat-msg[data-type=\"" + Type.pmReceived + "\"] { color: purple; }\n#" + CHAT_BOX_ID + ".showTags .chat-msg[data-type=\"" + Type.pmSent + "\"] { color: purple; }\n#" + CHAT_BOX_ID + ".showTags .chat-msg[data-type=\"" + Type.serverMsg + "\"] { color: blue; }\n#" + CHAT_BOX_ID + ".showTags .chat-msg[data-tag=\"contributor\"] { color: green; }\n#" + CHAT_BOX_ID + ".showTags .chat-msg[data-tag=\"mod\"] { color: #669999; }\n#" + CHAT_BOX_ID + ".showTags .chat-msg[data-tag=\"dev\"] { color: #666600; }\n.chat-msg:not([data-type=\"" + Type.reload + "\"]) .user\n{\n\tflex: 0 0 132px;\n\tmargin-right: 5px;\n\twhite-space: nowrap;\n}\n#" + GENERAL_CHAT_DIV_ID + " .chat-msg:not([data-type=\"" + Type.reload + "\"]) .user\n{\n\tflex-basis: 182px;\n}\n#" + CHAT_BOX_ID + ".showIcons #" + GENERAL_CHAT_DIV_ID + " .chat-msg:not([data-type=\"" + Type.reload + "\"]) .user\n{\n\tpadding-left: 22px;\n}\n.chat-msg .user[data-same-user=\"true\"]:not([data-name=\"\"])\n{\n\tcursor: default;\n\topacity: 0;\n}\n\n.chat-msg .user .icon\n{\n\tdisplay: none;\n}\n#" + CHAT_BOX_ID + ".showIcons .chat-msg .user .icon\n{\n\tdisplay: inline-block;\n\tmargin-left: -22px;\n}\n.chat-msg .user .icon::before\n{\n\tbackground-size: 20px 20px;\n\tcontent: '';\n\tdisplay: inline-block;\n\tmargin-right: 2px;\n\twidth: 20px;\n\theight: 20px;\n\tvertical-align: middle;\n}\n.chat-msg .user .icon.halloween2015::before\t{ background-image: url('images/chat-icons/1.png'); }\n.chat-msg .user .icon.christmas2015::before\t{ background-image: url('images/chat-icons/2.png'); }\n.chat-msg .user .icon.easter2016::before\t{ background-image: url('images/chat-icons/3.png'); }\n.chat-msg .user .icon.halloween2016::before\t{ background-image: url('images/chat-icons/4.png'); }\n.chat-msg .user .icon.christmas2016::before\t{ background-image: url('images/chat-icons/5.png'); }\n.chat-msg .user .icon.dh1Max::before\t\t{ background-image: url('images/chat-icons/6.png'); }\n.chat-msg .user .icon.hardcore::before\t\t{ background-image: url('images/chat-icons/7.png'); }\n.chat-msg .user .icon.quest::before\t\t\t{ background-image: url('images/chat-icons/8.png'); }\n\n.chat-msg .user:not([data-same-user=\"true\"]) .name\n{\n\tcolor: rgba(0, 0, 0, 0.7);\n\tcursor: pointer;\n}\n.chat-msg .user .name.chat-tag-donor::before\n{\n\tbackground-image: url('images/chat-icons/donor.png');\n\tbackground-size: 20px 20px;\n\tcontent: '';\n\tdisplay: inline-block;\n\theight: 20px;\n\twidth: 20px;\n\tvertical-align: middle;\n}\n.chat-msg .user .name.chat-tag-yell\n{\n\tcursor: default;\n}\n#" + CHAT_BOX_ID + ".showTags .chat-msg .user .name.chat-tag-contributor,\n#" + CHAT_BOX_ID + ".showTags .chat-msg .user .name.chat-tag-mod,\n#" + CHAT_BOX_ID + ".showTags .chat-msg .user .name.chat-tag-dev,\n#" + CHAT_BOX_ID + ".showTags .chat-msg .user .name.chat-tag-yell\n{\n\tcolor: white;\n\tdisplay: inline-block;\n\tfont-size: 10pt;\n\tmargin-top: -1px;\n\tpadding-bottom: 0;\n\ttext-align: center;\n\t/* 2px border, 10 padding */\n\twidth: calc(100% - 2*1px - 2*5px);\n}\n#" + CHAT_BOX_ID + ":not(.showTags) .chat-msg .user .name.chat-tag-contributor,\n#" + CHAT_BOX_ID + ":not(.showTags) .chat-msg .user .name.chat-tag-mod,\n#" + CHAT_BOX_ID + ":not(.showTags) .chat-msg .user .name.chat-tag-dev,\n#" + CHAT_BOX_ID + ":not(.showTags) .chat-msg .user .name.chat-tag-yell\n{\n\tbackground: initial;\n\tborder: inherit;\n\tfont-family: inherit;\n\tfont-size: inherit;\n\tpadding: initial;\n}\n\n.chat-msg[data-type=\"" + Type.reload + "\"] .user > *,\n.chat-msg[data-type=\"" + Type.pmReceived + "\"] .user > .icon,\n.chat-msg[data-type=\"" + Type.pmSent + "\"] .user > .icon\n{\n\tdisplay: none;\n}\n\n.chat-msg .msg\n{\n\tmin-width: 0;\n\toverflow: hidden;\n\tword-wrap: break-word;\n}\n\n#" + CHAT_BOX_ID + " ." + CHAT_CLASS + "\n{\n\twidth: 100%;\n\theight: 130px;\n\tdisplay: none;\n}\n#" + CHAT_BOX_ID + " ." + CHAT_CLASS + ".selected\n{\n\tdisplay: block;\n}\n#" + CHAT_TABS_ID + "\n{\n\tdisplay: flex;\n\tmargin: 10px -6px -6px;\n\tflex-wrap: wrap;\n}\n#" + CHAT_TABS_ID + " .chat-tab\n{\n\tbackground-color: gray;\n\tborder-top: 1px solid black;\n\tborder-right: 1px solid black;\n\tcursor: pointer;\n\tdisplay: inline-block;\n\tfont-weight: normal;\n\tpadding: 0.3rem .6rem;\n\tposition: relative;\n}\n#" + CHAT_TABS_ID + " .chat-tab.selected\n{\n\tbackground-color: transparent;\n\tborder-top-color: transparent;\n}\n#" + CHAT_TABS_ID + " .chat-tab.default\n{\n\tdisplay: none;\n}\n#" + CHAT_TABS_ID + " .chat-tab.filler\n{\n\tbackground-color: hsla(0, 0%, 90%, 1);\n\tborder-right: 0;\n\tbox-shadow: inset 5px 5px 5px -5px rgba(0, 0, 0, 0.5);\n\tcolor: transparent;\n\tcursor: default;\n\tflex-grow: 1;\n}\n#" + CHAT_TABS_ID + " .chat-tab::after\n{\n\tcolor: white;\n\tcontent: '(' attr(data-new) ')';\n\tfont-size: .9rem;\n\tfont-weight: bold;\n\tmargin-left: .4rem;\n}\n#" + CHAT_TABS_ID + " .chat-tab[data-new=\"0\"]::after\n{\n\tcolor: inherit;\n\tfont-weight: normal;\n}\n#" + CHAT_TABS_ID + " .chat-tab:not(.general).selected::after,\n#" + CHAT_TABS_ID + " .chat-tab:not(.general):hover::after\n{\n\tvisibility: hidden;\n}\n#" + CHAT_TABS_ID + " .chat-tab:not(.general).selected .close::after,\n#" + CHAT_TABS_ID + " .chat-tab:not(.general):hover .close::after\n{\n\tcontent: '\u00D7';\n\tfont-size: 1.5rem;\n\tposition: absolute;\n\ttop: 0;\n\tright: .6rem;\n\tbottom: 0;\n}\n\n#" + CONTEXTMENU_ID + "\n{\n\tbox-shadow: rgba(0, 0, 0, 0.8) 4px 4px 4px -2px;\n\tposition: fixed;\n}\n#" + CONTEXTMENU_ID + " .ui-widget-header\n{\n\tcursor: default;\n\tpadding: .25rem;\n}\n\t\t");
}
function addIntelligentScrolling()
{
// add checkbox instead of button for toggling auto scrolling
var btn = document.querySelector('input[value="Toggle Autoscroll"]');
var btnParent = btn.parentElement;
var checkboxId = 'chat-toggle-autoscroll';
// create checkbox
var toggleCheckbox = document.createElement('input');
toggleCheckbox.type = 'checkbox';
toggleCheckbox.id = checkboxId;
toggleCheckbox.checked = true;
// create label
var toggleLabel = document.createElement('label');
toggleLabel.htmlFor = checkboxId;
toggleLabel.textContent = 'Autoscroll';
btnParent.insertBefore(toggleCheckbox, btn);
btnParent.insertBefore(toggleLabel, btn);
btn.style.display = 'none';
var chatArea = document.getElementById(GENERAL_CHAT_DIV_ID);
var showScrollTextTimeout = null;
function setAutoScrolling(value, full)
{
if (full === void 0)
{
full = false;
}
if (window.isAutoScrolling != value)
{
toggleCheckbox.checked = value;
window.isAutoScrolling = value;
var icon_1 = 'none';
var color_1 = value ? 'lime' : 'red';
var text_1 = (value ? 'En' : 'Dis') + 'abled' + (full ? ' Autoscroll' : '');
if (full)
{
if (showScrollTextTimeout)
{
window.clearTimeout(showScrollTextTimeout);
}
showScrollTextTimeout = window.setTimeout(function ()
{
return window.scrollText(icon_1, color_1, text_1);
}, 300);
}
else
{
window.scrollText(icon_1, color_1, text_1);
}
return true;
}
return false;
}
toggleCheckbox.addEventListener('change', function ()
{
setAutoScrolling(this.checked);
if (this.checked && settings.get(settings.KEY.intelligentScrolling))
{
chatArea.scrollTop = chatArea.scrollHeight - chatArea.clientHeight;
}
});
var placeholderTemplate = document.createElement('div');
placeholderTemplate.className = 'placeholder';
var childStore = new WeakMap();
function scrollHugeChat()
{
// # of children
var chunkNum = chatArea.children.length;
// start chunk hiding at a specific amount of chunks
if (chunkNum < CHUNK_HIDING_MIN_CHUNKS)
{
return;
}
var visibleTop = chatArea.scrollTop;
var visibleBottom = visibleTop + chatArea.clientHeight;
var referenceTop = visibleTop - window.innerHeight;
var referenceBottom = visibleBottom + window.innerHeight;
var top = 0;
// never hide the last element since its size may change at any time when a new message gets appended
for (var i = 0; i < chunkNum - 1; i++)
{
var child = chatArea.children[i];
var height = child.clientHeight;
var bottom = top + height;
var isVisible = top >= referenceTop && top <= referenceBottom
|| bottom >= referenceTop && bottom <= referenceBottom
|| top < referenceTop && bottom > referenceBottom;
var isPlaceholder = child.classList.contains('placeholder');
if (!isVisible && !isPlaceholder)
{
var newPlaceholder = placeholderTemplate.cloneNode(false);
newPlaceholder.style.height = height + 'px';
chatArea.replaceChild(newPlaceholder, child);
childStore.set(newPlaceholder, child);
}
else if (isVisible && isPlaceholder)
{
var oldChild = childStore.get(child);
chatArea.replaceChild(oldChild, child);
childStore.delete(child);
}
top = bottom;
}
}
var delayedScrollStart = null;
var delayedScrollTimeout = null;
// does not consider pm tabs; may be changed in a future version?
chatArea.addEventListener('scroll', function ()
{
if (settings.get(settings.KEY.intelligentScrolling))
{
var scrolled2Bottom = (chatArea.scrollTop + chatArea.clientHeight) >= chatArea.scrollHeight;
setAutoScrolling(scrolled2Bottom, true);
}
var n = now();
if (delayedScrollStart == null)
{
delayedScrollStart = n;
}
if (delayedScrollStart + 300 > n)
{
if (delayedScrollTimeout)
{
window.clearTimeout(delayedScrollTimeout);
}
delayedScrollTimeout = window.setTimeout(function ()
{
delayedScrollStart = null;
delayedScrollTimeout = null;
scrollHugeChat();
}, 50);
}
});
}
function getSelectedTab()
{
return document.querySelector('#' + CHAT_TABS_ID + ' .chat-tab.selected');
}
function clickChatTab(newTab)
{
var oldTab = getSelectedTab();
if (newTab == oldTab)
{
return;
}
changeChatTab(oldTab, newTab);
}
function clickCloseChatTab(tab)
{
var username = tab.dataset.username || '';
var chatDiv = getChatDiv(username);
if (chatDiv.children.length === 0
|| confirm("Do you want to close the pm tab of \"" + username + "\"?"))
{
closeChatTab(username);
}
}
function checkSetting(init)
{
if (init === void 0)
{
init = false;
}
var enabled = settings.get(settings.KEY.useNewChat);
// dis-/enable chat tabs
var chatTabs = document.getElementById(CHAT_TABS_ID);
chatTabs.style.display = enabled ? '' : 'none';
// dis-/enable checkbox for intelligent scrolling
var intelScrollId = 'chat-toggle-intelligent-scroll';
var input = document.getElementById(intelScrollId);
if (input)
{
input.style.display = enabled ? '' : 'none';
}
var label = document.querySelector('label[for="' + intelScrollId + '"]');
if (label)
{
label.style.display = enabled ? '' : 'none';
}
// virtually click on a tab
var defaultTab = getChatTab('', SpecialTab.default);
var generalTab = getChatTab('', SpecialTab.general);
clickChatTab(enabled ? generalTab : defaultTab);
if (init)
{
settings.observe(settings.KEY.useNewChat, function ()
{
return checkSetting(false);
});
}
}
function addChatTabs()
{
var chatBoxArea = document.getElementById(CHAT_BOX_ID);
var chatTabs = document.createElement('div');
chatTabs.id = CHAT_TABS_ID;
chatTabs.addEventListener('click', function (event)
{
var newTab = event.target;
if (newTab.classList.contains('close'))
{
return clickCloseChatTab(newTab.parentElement);
}
if (!newTab.classList.contains('chat-tab') || newTab.classList.contains('filler'))
{
return;
}
clickChatTab(newTab);
});
chatBoxArea.appendChild(chatTabs);
// default tab (for disabled new chat)
getChatTab('', SpecialTab.default);
// general server chat
var generalTab = getChatTab('', SpecialTab.general);
generalTab.textContent = 'Server';
getChatDiv('');
getChatTab('', SpecialTab.filler);
var _sendChat = window.sendChat;
window.sendChat = function (inputEl)
{
var msg = inputEl.value;
var selectedTab = document.querySelector('.chat-tab.selected');
if (selectedTab.dataset.username != '' && msg[0] != '/')
{
inputEl.value = '/pm ' + (selectedTab.dataset.username || '').replace(/ /g, '+') + ' ' + msg;
}
_sendChat(inputEl);
};
}
function switch2PmTab(username)
{
var newTab = getChatTab(username, null);
clickChatTab(newTab);
}
function notifyPm(data)
{
notifications.event('Message from "' + data.username + '"'
, {
body: data.msg
, onclick: function ()
{
return switch2PmTab(data.username);
}
, whenActive: getSelectedTab().dataset.username != data.username
});
}
function checkMentionAndKeywords(data)
{
var lowerMsg = data.msg.toLowerCase();
if (lowerMsg.indexOf(window.username) > -1)
{
notifications.event('You\'ve been mentioned'
, {
body: data.msg
});
}
var match = [];
for (var _i = 0, keywordList_1 = keywordList; _i < keywordList_1.length; _i++)
{
var keyword = keywordList_1[_i];
if (lowerMsg.indexOf(keyword) > -1)
{
match.push(keyword);
}
}
if (match.length > 0)
{
notifications.event('Keyword: "' + match.join('", "') + '"'
, {
body: data.msg
});
}
}
var addToChatBox_ = null;
function newAddToChatBox(username, icon, tag, msg, isPM)
{
var data = processChatData(username, icon, tag, msg, isPM);
if (isDataPM(data))
{
if (data.type == Type.pmSent)
{
switch2PmTab(data.username);
}
notifyPm(data);
}
else if (isSpam(data))
{
console.info('detected spam:', data);
return;
}
else
{
// check mentioning and keywords only for non-pms
checkMentionAndKeywords(data);
}
add2ChatHistory(data);
add2Chat(data);
var fn = addToChatBox_ == null ? window.addToChatBox : addToChatBox_;
fn(username, icon, tag, msg, isPM);
}
chat.newAddToChatBox = newAddToChatBox;
function openPmTab(username)
{
if (username == window.username || username == '')
{
return;
}
var userTab = getChatTab(username, null);
clickChatTab(userTab);
var input = document.getElementById(CHAT_INPUT_ID);
input.focus();
}
function newChat()
{
addChatTabs();
applyChatStyle();
addToChatBox_ = window.addToChatBox;
window.addToChatBox = newAddToChatBox;
chatInitialized = true;
var chatbox = document.getElementById(CHAT_BOX_ID);
chatbox.addEventListener('click', function (event)
{
var target = event.target;
var userEl = target && target.parentElement;
if (!target || !userEl || !target.classList.contains('name') || !userEl.classList.contains('user'))
{
return;
}
if (userEl.dataset.sameUser != 'true')
{
openPmTab(userEl.dataset.name || '');
}
});
chatbox.addEventListener('mouseover', function (event)
{
var target = event.target;
if (!target.classList.contains('timestamp') || !target.dataset.timestamp)
{
return;
}
var timestamp = parseInt(target.dataset.timestamp || '0', 10);
target.dataset.fulltime = (new Date(timestamp)).toLocaleDateString(LOCALE, LOCALE_OPTIONS);
target.dataset.timestamp = '';
});
// add context menu
var contextmenu = document.createElement('ul');
contextmenu.id = CONTEXTMENU_ID;
contextmenu.style.display = 'none';
contextmenu.innerHTML = "<li class=\"name ui-widget-header\"><div></div></li>\n\t\t<li class=\"open-pm\"><div>Open pm tab</div></li>\n\t\t<li class=\"mute\"><div>Mute</div></li>\n\t\t<li class=\"unmute\"><div>Unmute</div></li>";
document.body.appendChild(contextmenu);
window.$(contextmenu).menu(
{
items: '> :not(.ui-widget-header)'
});
var nameListEl = contextmenu.querySelector('.name');
var nameDivEl = nameListEl.firstElementChild;
var muteEl = contextmenu.querySelector('.mute');
var unmuteEl = contextmenu.querySelector('.unmute');
chatbox.addEventListener('contextmenu', function (event)
{
var target = event.target;
var userEl = target && target.parentElement;
if (!userEl || !userEl.classList.contains('user'))
{
return;
}
var username = userEl.dataset.name;
// ignore clicks on server messages or other special messages
if (!username || userEl.dataset.sameUser == 'true')
{
return;
}
contextmenu.style.left = event.clientX + 'px';
contextmenu.style.top = event.clientY + 'px';
contextmenu.style.display = '';
contextmenu.dataset.username = username;
nameDivEl.textContent = username;
var isMuted = window.mutedPeople.indexOf(username) !== -1;
muteEl.style.display = isMuted ? 'none' : '';
unmuteEl.style.display = isMuted ? '' : 'none';
event.preventDefault();
});
// add click listener for context menu and stop propagation
contextmenu.addEventListener('click', function (event)
{
var target = event.target;
event.stopPropagation();
while (target && target.id != CONTEXTMENU_ID && target.tagName != 'LI')
{
target = target.parentElement;
}
if (!target || target.id == CONTEXTMENU_ID)
{
return;
}
var username = contextmenu.dataset.username || '';
if (target.classList.contains('open-pm'))
{
openPmTab(username);
}
else if (target.classList.contains('mute'))
{
if (username == '')
{
return;
}
window.mutedPeople.push(username);
window.scrollText('none', 'lime', '<em>' + username + '</em> muted');
}
else if (target.classList.contains('unmute'))
{
if (username == '')
{
return;
}
var index = window.mutedPeople.indexOf(username);
if (index !== -1)
{
window.mutedPeople.splice(index, 1);
}
window.scrollText('none', 'red', '<em>' + username + '</em> unmuted');
}
else
{
return;
}
contextmenu.style.display = 'none';
});
// add click listener to hide context menu
document.addEventListener('click', function (event)
{
if (contextmenu.style.display != 'none')
{
contextmenu.style.display = 'none';
}
});
// handle settings
var showSettings = [settings.KEY.showTimestamps, settings.KEY.showIcons, settings.KEY.showTags];
function setShowSetting(key)
{
var enabled = settings.get(key);
chatbox.classList[enabled ? 'add' : 'remove'](settings.KEY[key]);
}
for (var _i = 0, showSettings_1 = showSettings; _i < showSettings_1.length; _i++)
{
var key = showSettings_1[_i];
setShowSetting(key);
settings.observe(key, function (k)
{
return setShowSetting(k);
});
}
}
var commands = ['pm', 'mute', 'ipmute'];
function addCommandSuggester()
{
var input = document.getElementById(CHAT_INPUT_ID);
input.addEventListener('keyup', function (event)
{
if (event.key == 'Backspace' || event.key == 'Delete' || event.key == 'Enter' || event.key == 'Tab'
|| input.selectionStart != input.selectionEnd
|| input.selectionStart != input.value.length
|| !input.value.startsWith('/'))
{
return;
}
var value = input.value.substr(1);
for (var _i = 0, commands_1 = commands; _i < commands_1.length; _i++)
{
var cmd = commands_1[_i];
if (cmd.startsWith(value))
{
input.value = '/' + cmd;
input.selectionStart = 1 + value.length;
input.selectionEnd = input.value.length;
break;
}
}
});
}
function addOwnCommands()
{
commands.push(TUTORIAL_CMD);
commands.push(KEYWORD_ADD_CMD);
commands.push(KEYWORD_REMOVE_CMD);
function processOwnCommands(value)
{
if (!value.startsWith('/'))
{
return value;
}
var msgPrefix = '/';
var msg = value.substr(1);
if (msg.startsWith('pm'))
{
var split = msg.split(' ');
msgPrefix = '/' + split.slice(0, 2).join(' ') + ' ';
msg = split.slice(2).join(' ');
}
if (msg.startsWith(TUTORIAL_CMD))
{
// thanks aguyd (https://greasyfork.org/forum/profile/aguyd) for the idea
var name_2 = msg.substr(TUTORIAL_CMD.length).trim();
msgPrefix = '';
msg = 'https://www.reddit.com/r/DiamondHunt/comments/5vrufh/diamond_hunt_2_starter_faq/';
if (name_2.length != 0)
{
// maybe add '@' before the name?
msg = name_2 + ', ' + msg;
}
}
else if (msg.startsWith(KEYWORD_ADD_CMD))
{
var keyword = msg.substr(KEYWORD_ADD_CMD.length).trim().toLowerCase();
if (keywordList.indexOf(keyword) == -1)
{
keywordList.push(keyword);
store.set(KEYWORD_LIST_KEY, keywordList);
}
window.scrollText('none', 'lime', 'Keyword added: <em>' + keyword + '</em>');
}
else if (msg.startsWith(KEYWORD_REMOVE_CMD))
{
var keyword = msg.substr(KEYWORD_REMOVE_CMD.length).trim().toLowerCase();
var index = keywordList.indexOf(keyword);
if (index != -1)
{
keywordList.splice(index, 1);
store.set(KEYWORD_LIST_KEY, keywordList);
}
window.scrollText('none', 'lime', 'Keyword removed: <em>' + keyword + '</em>');
}
return msgPrefix + msg;
}
var _sendChat = window.sendChat;
window.sendChat = function (inputEl)
{
inputEl.value = processOwnCommands(inputEl.value);
_sendChat(inputEl);
};
}
function checkColorize(init)
{
if (init === void 0)
{
init = false;
}
var chatDiv = document.getElementById(CHAT_BOX_ID);
chatDiv.classList[settings.get(settings.KEY.colorizeChat) ? 'add' : 'remove'](COLORIZE_CLASS);
if (init)
{
settings.observe(settings.KEY.colorizeChat, function ()
{
return checkColorize(false);
});
}
}
function init()
{
newChat();
addIntelligentScrolling();
addCommandSuggester();
addOwnCommands();
checkColorize(true);
checkSetting(true);
var _enlargeChat = window.enlargeChat;
var chatBoxArea = document.getElementById(CHAT_BOX_ID);
function setChatBoxHeight(height)
{
var defaultChat = document.getElementById(DEFAULT_CHAT_DIV_ID);
defaultChat.style.height = height;
var generalChat = document.getElementById(GENERAL_CHAT_DIV_ID);
generalChat.style.height = height;
var chatDivs = chatBoxArea.querySelectorAll('div[id^="' + PM_CHAT_DIV_PREFIX + '"]');
for (var i = 0; i < chatDivs.length; i++)
{
chatDivs[i].style.height = height;
}
}
window.enlargeChat = function (enlargeB)
{
_enlargeChat(enlargeB);
var defaultChatDiv = document.getElementById(DEFAULT_CHAT_DIV_ID);
var height = defaultChatDiv.style.height;
store.set('chat.height', height);
setChatBoxHeight(height);
handleScrolling(defaultChatDiv);
};
setChatBoxHeight(store.get('chat.height'));
// TEMP >>> (due to a naming issue, migrate the data)
var oldChatHistoryKey = 'chatHistory2';
var oldChatHistory = store.get(oldChatHistoryKey);
if (oldChatHistory != null)
{
store.set(CHAT_HISTORY_KEY, oldChatHistory);
store.remove(oldChatHistoryKey);
}
// TEMP <<<
// add history to chat
chatHistory.forEach(function (d)
{
return add2Chat(d);
});
if (chatboxFragments)
{
chatboxFragments.forEach(function (fragment, key)
{
var chatbox = getChatDiv(key);
chatbox.appendChild(fragment);
});
chatboxFragments = null;
}
// reset the new counter for all tabs
var tabs = document.querySelectorAll('.chat-tab');
for (var i = 0; i < tabs.length; i++)
{
tabs[i].dataset.new = '0';
}
}
chat.init = init;
var _a;
})(chat || (chat = {}));
/**
* hopefully only temporary fixes
*/
var temporaryFixes;
(function (temporaryFixes)
{
temporaryFixes.name = 'temporaryFixes';
// update spells being clickable in combat
function setSpellsClickable()
{
var spellbox = document.getElementById('fight-spellboox');
if (spellbox)
{
spellbox.style.pointerEvents = window.isInCombat() ? '' : 'none';
}
}
// warn before unloading/reloading the tab if combat is in progress
function combatWarnOnUnload()
{
if (!window.isInCombat())
{
window.onbeforeunload = null;
}
else
{
if (window.onbeforeunload == null)
{
window.onbeforeunload = function ()
{
return 'You are in a fight!';
};
}
}
}
function fixCombatCountdown()
{
if (window.isInCombat() && window.combatCommenceTimer != 0)
{
document.getElementById('combat-countdown').style.display = '';
}
}
// fix exhaustion timer and updating brewing and cooking recipes
function fixExhaustionTimer()
{
if (document.getElementById('tab-container-combat').style.display != 'none')
{
window.combatNotFightingTick();
}
}
function fixClientGameLoop()
{
var _clientGameLoop = window.clientGameLoop;
window.clientGameLoop = function ()
{
_clientGameLoop();
setSpellsClickable();
combatWarnOnUnload();
fixCombatCountdown();
fixExhaustionTimer();
};
}
// fix elements of scrollText (e.g. when joining the game and receiving xp at that moment)
function fixScroller()
{
var textEls = document.querySelectorAll('div.scroller');
for (var i = 0; i < textEls.length; i++)
{
var scroller = textEls[i];
if (scroller.style.position != 'absolute')
{
scroller.style.display = 'none';
}
}
}
// fix style of tooltips
function fixTooltipStyle()
{
addStyle("\nbody > div.tooltip > h2:first-child\n{\n\tmargin-top: 0;\n\tfont-size: 20pt;\n\tfont-weight: normal;\n}\n\t\t");
}
// fix buiulding magic table dynamically
function fixRefreshingMagicRecipes()
{
window.refreshLoadMagicTable = true;
var _processMagicTab = window.processMagicTab;
window.processMagicTab = function ()
{
var _refreshLoadCraftingTable = window.refreshLoadCraftingTable;
window.refreshLoadCraftingTable = window.refreshLoadMagicTable;
_processMagicTab();
window.refreshLoadCraftingTable = _refreshLoadCraftingTable;
};
}
// move the strange leaf to brewing tab (thanks lasse_brus for this idea)
function moveStrangeLeafs()
{
var strangeLeafBox = document.getElementById('item-box-strangeLeaf');
var brewingContainer = document.getElementById('tab-sub-container-brewing');
brewingContainer.appendChild(strangeLeafBox);
// remove event listeners before binding the tooltip to it
var $strangeLeafBox = window.$(strangeLeafBox);
$strangeLeafBox.off('mouseover').off('mouseleave');
strangeLeafBox.title = '';
// bind tooltip to item box
ensureTooltip('ingredient-secondary', strangeLeafBox);
// change color
var color1 = '#800080';
var color2 = '#990099';
strangeLeafBox.style.background = 'linear-gradient(' + color1 + ', ' + color2 + ')';
$strangeLeafBox
.mouseover(function ()
{
strangeLeafBox.style.background = 'none';
strangeLeafBox.style.backgroundColor = color2;
})
.mouseleave(function ()
{
strangeLeafBox.style.background = 'linear-gradient(' + color1 + ', ' + color2 + ')';
});
}
// fix height of map item
function fixTreasureMap()
{
var mapBox = document.getElementById('item-box-treasureMap');
var numSpan = mapBox.lastElementChild;
numSpan.style.display = '';
numSpan.style.visibility = 'hidden';
}
// fix wobbling tree places on hover (in wood cutting)
function fixWoodcutting()
{
addStyle("\nimg.woodcutting-tree-img\n{\n\tborder: 1px solid transparent;\n}\n\t\t");
}
// fix rake dialog
function fixRakeDialog()
{
var _clicksRake = window.clicksRake;
window.clicksRake = function ()
{
_clicksRake();
var upgradeBtn = document.querySelector('#dialogue-id-upgrade-rake input[value="Upgrade"]');
if (upgradeBtn)
{
var hide = window.diamondRake == 1;
upgradeBtn.style.display = hide ? 'none' : '';
}
};
}
// fix tooltip of promethium, whale and rainbowfish
function fixTooltips()
{
var fishTooltipTemplate = document.querySelector('#tooltip-list > div[id^="tooltip-raw"]');
var oreTooltipTemplate = document.getElementById('tooltip-marble');
if (!fishTooltipTemplate || !oreTooltipTemplate)
{
return;
}
function ensureTooltip(item, tooltipTemplate, onCreate)
{
var tooltipId = 'tooltip-' + item;
if (document.getElementById(tooltipId) != null)
{
return;
}
var newTooltip = tooltipTemplate.cloneNode(true);
newTooltip.id = tooltipId;
onCreate(newTooltip);
tooltipTemplate.parentElement.appendChild(newTooltip);
}
function ensureRawFishTooltip(fish)
{
ensureTooltip('raw' + fish, fishTooltipTemplate, function (newTooltip)
{
var foodName = 'Raw' + split2Words(fish);
newTooltip.firstChild.textContent = foodName;
var foodKey = fish[0].toLowerCase() + fish.substr(1);
var energy = window.getEnergyGained(foodKey);
newTooltip.lastChild.firstChild.textContent = '+' + format.number(energy) + ' ';
});
}
var boxes = document.querySelectorAll('#tab-sub-container-combat-large-btns > span.item-box[id^="item-box-raw"]');
for (var i = 0; i < boxes.length; i++)
{
var food = boxes[i].id.replace('item-box-raw', '');
ensureRawFishTooltip(food);
}
// promethium
ensureTooltip('promethium', oreTooltipTemplate, function (newTooltip)
{
var spans = newTooltip.getElementsByTagName('span');
var priceNode = newTooltip.lastChild;
spans[0].textContent = 'Promethium';
spans[1].textContent = 'Can be used for... nothing at the moment.';
priceNode.textContent = ' ' + format.number(getPrice('promethium'));
});
}
// fix wobbling quest rows on hover (in quest book)
function fixQuestBook()
{
addStyle("\n#table-quest-list tr\n{\n\tborder: 1px solid transparent;\n}\n\t\t");
}
// this fix was realized first here: https://www.reddit.com/r/DiamondHunt/60z9h9/
function fixedLoadSkillTabs()
{
for (var _i = 0, SKILL_LIST_1 = SKILL_LIST; _i < SKILL_LIST_1.length; _i++)
{
var skil = SKILL_LIST_1[_i];
var unlocked = getGameValue(skil + 'Unlocked') == 1;
if (!unlocked)
{
continue;
}
var xp = getGameValue(skil + 'Xp');
var currentLevelXp = window.getXpNeeded(window.getLevel(xp));
var nextLevelXp = window.getXpNeeded(window.getLevel(xp) + 1);
var perc = (xp - currentLevelXp) / (nextLevelXp - currentLevelXp) * 100;
var xpBarEl = document.getElementById('inner-skill-xp-bar-' + skil);
xpBarEl.style.minWidth = xpBarEl.style.maxWidth = perc + '%';
}
}
function fixSkillBars()
{
var _loadSkillTabs = window.loadSkillTabs;
window.loadSkillTabs = function ()
{
_loadSkillTabs();
fixedLoadSkillTabs();
};
}
function fixCraftingXpTooltip()
{
var el = document.getElementById('tooltip-skills-crafting-xp-left-value');
if (!el)
{
return;
}
var br = el.nextElementSibling;
if (!br)
{
return;
}
var annoyingTick = br.nextSibling;
if (!annoyingTick || annoyingTick.nodeType != Node.TEXT_NODE || !annoyingTick.textContent)
{
return;
}
annoyingTick.textContent = annoyingTick.textContent.replace('`', '');
}
function fixScrollImages()
{
function fixIcon(icon)
{
return icon + (icon != 'none' && !/\..{3,4}$/.test(icon) ? '.png' : '');
}
var _scrollTextHitSplat = window.scrollTextHitSplat;
window.scrollTextHitSplat = function (icon, color, text, elId, cbType)
{
_scrollTextHitSplat(fixIcon(icon), color, text, elId, cbType);
};
var _scrollText = window.scrollText;
window.scrollText = function (icon, color, text)
{
_scrollText(fixIcon(icon), color, text);
};
}
function fixQuest8BraveryRecipe()
{
observer.add([
'quest8'
, 'braveryPotion'
], function ()
{
var show = window.quest8 > 0 && window.braveryPotion == 0;
var recipe = document.getElementById('brewing-braveryPotion');
if (recipe)
{
recipe.style.display = show ? '' : 'none';
}
});
}
// fix cooking dialog of uncookable fish (e.g. whale/rainbow fish)
function fixCookingDialogForUncookableFish()
{
var _cookFoodDialogue = window.cookFoodDialogue;
window.cookFoodDialogue = function (rawFood)
{
_cookFoodDialogue(rawFood);
var dialog = document.getElementById('dialogue-id-cook-food');
if (!dialog)
{
return;
}
var isCookable = window.getHeatNeeded(rawFood) != 0;
function hideWhenNotCookable(el, mustBeCookable)
{
el.style.display = isCookable == mustBeCookable ? '' : 'none';
}
var boxes = dialog.getElementsByClassName('basic-smallbox');
var amountBox = boxes[1];
var notCookableBox = amountBox.nextElementSibling;
if (notCookableBox.tagName != 'DIV')
{
var newEl = amountBox.cloneNode(false);
newEl.innerHTML = "<b>Not cookable at the moment</b>";
notCookableBox.parentElement.insertBefore(newEl, notCookableBox);
notCookableBox = newEl;
}
hideWhenNotCookable(amountBox, true);
hideWhenNotCookable(notCookableBox, false);
var heatNeededBox = document.getElementById('heat-needed-dyn');
if (heatNeededBox)
{
hideWhenNotCookable(heatNeededBox, true);
hideWhenNotCookable(heatNeededBox.previousElementSibling, true);
}
var btn = dialog.querySelector('input[value="Cook"]');
if (btn)
{
btn.disabled = !isCookable;
}
// TODO: move to some other module like "requirementCheck"
var levelReq = document.getElementById('dialogue-cook-levelReq');
var levelReqLabel = levelReq && levelReq.previousElementSibling;
if (!levelReq || !levelReqLabel)
{
return;
}
var fulfilled = window.getCookingLevelReq(rawFood) > window.getLevel(window.cookingXp);
levelReq.style.color = fulfilled ? 'rgb(204, 0, 0)' : '';
levelReq.style.fontWeight = fulfilled ? 'bold' : '';
levelReqLabel.style.color = fulfilled ? 'rgb(204, 0, 0)' : '';
};
}
function fixHitText()
{
window.scrollTextHitSplat = function (icon, color, text, elId, cbType)
{
var imgTag = icon != 'none' ? "<img src=\"images/" + icon + "\" class=\"image-icon-50\" />" : '';
var elementChosen = document.getElementById(elId);
if (!elementChosen)
{
return;
}
var rect = elementChosen.getBoundingClientRect();
var xCoord = (rect.left + rect.right) / 2;
var yCoord = (rect.bottom + rect.top) / 2;
var extraStyle = '';
if (cbType == 'melee')
{
extraStyle = 'border: 1px solid red; background-color: #4d0000;';
}
else if (cbType == 'heal')
{
extraStyle = 'border: 1px solid green; background-color: lime;';
}
var $elementToAppend = window.$("<div class=\"scroller\" style=\"" + extraStyle + " color: " + color + "; position: fixed;\">" + imgTag + text + "</div>").appendTo('body');
if (xCoord == 0 && yCoord == 0)
{
var tab = document.getElementById('tab-container-bar-combat');
var tabRect = tab.getBoundingClientRect();
var boxRect = $elementToAppend.get(0).getBoundingClientRect();
xCoord = elId == 'img-hero' ? (tabRect.left - boxRect.width) : tabRect.right;
yCoord = tabRect.top;
}
$elementToAppend
.css(
{
left: xCoord
, top: yCoord
})
.animate(
{
top: '-=50px'
}, function ()
{
return $elementToAppend.fadeOut(1000, function ()
{
return $elementToAppend.remove();
});
});
};
}
function fixBoatTooltips()
{
var boatBox = document.getElementById('item-box-boundRowBoat');
var boatTooltip = boatBox && document.getElementById(boatBox.dataset.tooltipId || '');
var canoeBox = document.getElementById('item-box-boundCanoe');
if (!boatBox || !canoeBox || !boatTooltip)
{
return;
}
var canoeTooltip = boatTooltip.cloneNode(true);
canoeTooltip.id = 'tooltip-boundCanoe';
var header = canoeTooltip.firstElementChild;
header.textContent = 'Canoe';
boatTooltip.parentElement.appendChild(canoeTooltip);
canoeBox.dataset.tooltipId = 'tooltip-boundCanoe';
var boatDuration = document.createElement('div');
boatDuration.innerHTML = '<strong>Trip duration:</strong> 3 hours';
boatTooltip.appendChild(boatDuration);
var canoeDuration = document.createElement('div');
canoeDuration.innerHTML = '<strong>Trip duration:</strong> 6 hours';
canoeTooltip.appendChild(canoeDuration);
}
function fixAlignments()
{
addStyle("\n#tab-container-crafting settings-container\n{\n\tmargin: 5px 30px;\n}\n#table-crafting-recipe,\n#table-brewing-recipe,\n#table-magic-recipe\n{\n\twidth: calc(100% - 2*20px - 2*10px);\n}\n#tab-sub-container-magic-items\n{\n\tmargin: 5px 0px;\n}\n#table-magic-recipe\n{\n\twidth: calc(100% - 2*10px);\n}\n\n#tab-container-farming\n{\n\tpadding: 0 20px;\n}\n#tab-sub-container-farming\n{\n\tmargin: 5px 0;\n\tmargin-bottom: -10px;\n}\ndiv.farming-patch,\ndiv.farming-patch-locked\n{\n\tmargin: 10px;\n}\n\n#combat-table-area\n{\n\tborder-spacing: 0;\n}\ndiv#hero-area.hero,\ndiv#monster-area.monster\n{\n\tmargin-left: 20px;\n\tmargin-right: 20px;\n\tmargin-top: 10px;\n}\ntable.table-hero-stats,\ndiv.hp-bar,\n#hero-area div.fight-spellbook\n{\n\tmargin-left: 0;\n}\ndiv.hp-bar\n{\n\tmin-width: calc(100% - 2px);\n}\n#hero-area span.fight-spell\n{\n\tmargin-bottom: 0;\n\tmargin-top: 0;\n}\n#hero-area span.fight-spell:first-child\n{\n\tmargin-left: 0;\n}\n#hero-area span.fight-spell:last-child\n{\n\tmargin-right: 0;\n}\n#hero-area > div:last-child,\n.imageMonster\n{\n\theight: 556px !important;\n\tmargin-top: -50px;\n}\n#monster-area div.hp-bar\n{\n\tmargin-top: 66px;\n\tmargin-bottom: 74px;\n}\n#monster-area > br:first-child,\n#monster-area table.table-hero-stats + br\n{\n\tdisplay: none;\n}\n.imageMonster\n{\n\talign-items: flex-end;\n\tdisplay: flex;\n\tposition: relative;\n}\n#combat-table-area[style$=\"auto;\"]\n{\n\tborder-color: transparent;\n}\n#img-monster\n{\n\tposition: absolute;\n}\n#img-monster[src$=\"/1.png\"]\n{\n\theight: 250px;\n}\n#img-monster[src$=\"/2.png\"]\n{\n\ttransform: translateY(30px);\n}\n#img-monster[src$=\"/3.png\"]\n{\n\theight: 180px;\n\ttransform: translateY(-350px);\n}\n#img-monster[src$=\"/4.png\"]\n{\n\theight: 180px;\n}\n#img-monster[src$=\"/5.png\"]\n{\n\theight: 700px;\n\ttransform: translateY(130px);\n}\n#img-monster[src$=\"/7.png\"]\n{\n\theight: 450px;\n\ttransform: translateY(30px);\n}\n#img-monster[src$=\"/8.png\"]\n{\n\theight: 280px;\n\ttransform: translateY(-260px);\n}\n#img-monster[src$=\"/9.png\"]\n{\n\theight: 450px;\n\ttransform: translateY(-10px);\n}\n#img-monster[src$=\"/11.png\"],\n#img-monster[src$=\"/15.png\"]\n{\n\ttransform: translateY(-180px);\n}\n#img-monster[src$=\"/14.png\"]\n{\n\theight: 500px;\n\tmargin-left: -50px;\n\tmargin-right: -50px;\n}\n#combat-table-area span.large-button,\n#combat-table-area span.medium-button\n{\n\tmargin: 10px;\n}\n#combat-table-area span.medium-button + br + br\n{\n\tdisplay: none;\n}\n\ndiv#market-slot-1.market-slot\n{\n\tfloat: initial;\n\tmargin-left: 10px !important;\n}\n\t\t");
}
function addHeroStatTooltips()
{
var table = document.querySelector('#hero-area table.table-hero-stats');
if (!table)
{
return;
}
var statRow = table.rows.item(0);
var attackCell = statRow.cells.item(0);
attackCell.title = 'Attack Damage';
window.$(attackCell).tooltip();
var accuracyCell = statRow.cells.item(1);
accuracyCell.title = 'Attack Accuracy';
window.$(accuracyCell).tooltip();
var speedCell = statRow.cells.item(2);
speedCell.title = 'Attack Speed';
window.$(speedCell).tooltip();
var defenseCell = statRow.cells.item(3);
defenseCell.title = 'Defense';
window.$(defenseCell).tooltip();
}
function init()
{
fixClientGameLoop();
fixScroller();
fixTooltipStyle();
fixRefreshingMagicRecipes();
moveStrangeLeafs();
fixTreasureMap();
fixWoodcutting();
fixRakeDialog();
fixTooltips();
fixQuestBook();
fixSkillBars();
fixCraftingXpTooltip();
// apply fix for scroll images later to fix images in this code too
fixHitText();
fixScrollImages();
fixQuest8BraveryRecipe();
fixCookingDialogForUncookableFish();
fixBoatTooltips();
fixAlignments();
addHeroStatTooltips();
}
temporaryFixes.init = init;
})(temporaryFixes || (temporaryFixes = {}));
/**
* improve timer
*/
var improveTimer;
(function (improveTimer_1)
{
improveTimer_1.name = 'improveTimer';
function bindNewFormatter()
{
window.formatTime = function (seconds)
{
return format.timer(seconds);
};
window.formatTimeShort2 = function (seconds)
{
return format.timer(seconds);
};
}
function improveSmeltingTimer()
{
addStyle("\n#notif-smelting > span:not(.timer)\n{\n\tdisplay: none;\n}\n\t\t");
var smeltingNotifBox = document.getElementById('notif-smelting');
var smeltingTimerEl = document.createElement('span');
smeltingTimerEl.className = 'timer';
smeltingNotifBox.appendChild(smeltingTimerEl);
var smeltingInterval;
function updatePercValues()
{
if (smeltingInterval)
{
window.clearInterval(smeltingInterval);
}
var delta = 0;
smeltingInterval = window.setInterval(function ()
{
return updateSmeltingTimer(++delta);
}, 1000);
updateSmeltingTimer();
}
function updateSmeltingTimer(delta)
{
if (delta === void 0)
{
delta = 0;
}
var totalTime = window.smeltingPercD;
// thanks at /u/marcus898 for your bug report
var elapsedTime = Math.round(window.smeltingPerc * totalTime / 100) + delta;
smeltingTimerEl.textContent = format.timer(Math.max(totalTime - elapsedTime, 0));
}
observer.add('smeltingPercD', function ()
{
return updatePercValues();
});
observer.add('smeltingPerc', function ()
{
return updatePercValues();
});
updatePercValues();
}
function improveTimer(cssRulePrefix, textColor, timerColor, infoIdPrefx, containerPrefix, updateFn)
{
addStyle("\n/* hide built in timer elements */\n" + cssRulePrefix + " > *:not(img):not(.info)\n{\n\tdisplay: none;\n}\n" + cssRulePrefix + " > div.info\n{\n\tcolor: " + textColor + ";\n\tmargin-top: 5px;\n\tpointer-events: none;\n\ttext-align: center;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n}\n" + cssRulePrefix + " > div.info > div.name\n{\n\tfont-size: 1.2rem;\n}\n" + cssRulePrefix + " > div.info > div.timer\n{\n\tcolor: " + timerColor + ";\n}\n\t\t");
for (var i = 0; i < 6; i++)
{
var num = i + 1;
var infoId = infoIdPrefx + num;
var container = document.getElementById(containerPrefix + num);
container.style.position = 'relative';
var infoEl = document.createElement('div');
infoEl.className = 'info';
infoEl.id = infoId;
infoEl.innerHTML = "<div class=\"name\"></div><div class=\"timer\"></div>";
container.appendChild(infoEl);
updateFn(num, infoId, true);
}
}
function updateTreeInfo(placeId, infoElId, init)
{
if (init === void 0)
{
init = false;
}
var infoEl = document.getElementById(infoElId);
var nameEl = infoEl.firstElementChild;
var timerEl = infoEl.lastElementChild;
var idKey = 'treeId' + placeId;
var growTimerKey = 'treeGrowTimer' + placeId;
var lockedKey = 'treeUnlocked' + placeId;
var treeId = getGameValue(idKey);
if (treeId == 0)
{
var isLocked = placeId > 4 && getGameValue(lockedKey) == 0;
nameEl.textContent = isLocked ? 'Locked' : 'Empty';
timerEl.textContent = '';
}
else
{
nameEl.textContent = key2Name(window.getTreeName(treeId)) || 'Unknown Tree';
var remainingTime = window.TREE_GROW_TIME[treeId - 1] - getGameValue(growTimerKey);
timerEl.textContent = remainingTime > 0 ? '(' + format.timer(remainingTime, true) + ')' : 'Fully grown';
}
if (init)
{
observer.add([idKey, growTimerKey, lockedKey], function ()
{
return updateTreeInfo(placeId, infoElId, false);
});
}
}
// add tree grow timer
function improveTreeGrowTimer()
{
improveTimer('.woodcutting-tree', 'white', 'yellow', 'wc-tree-info-', 'wc-div-tree-', updateTreeInfo);
}
function updatePatchInfo(patchId, infoElId, init)
{
if (init === void 0)
{
init = false;
}
var infoEl = document.getElementById(infoElId);
var nameEl = infoEl.querySelector('.name');
var timerEl = infoEl.querySelector('.timer');
var idKey = 'farmingPatchSeed' + patchId;
var growTimeKey = 'farmingPatchGrowTime' + patchId;
var timerKey = 'farmingPatchTimer' + patchId;
var stageKey = 'farmingPatchStage' + patchId;
var stage = getGameValue(stageKey);
var seedName = SEED_NAME[getGameValue(idKey)] || 'Unkown Plant';
if (stage == 0)
{
var isLocked = patchId > 4 && window.donorFarmingPatch == 0;
nameEl.textContent = isLocked ? 'Locked' : 'Click to grow';
timerEl.textContent = '';
}
else if (stage >= 4)
{
nameEl.textContent = stage > 4 ? 'Dead Plant' : seedName;
timerEl.textContent = stage > 4 ? 'Click to remove' : 'Click to harvest';
}
else
{
nameEl.textContent = seedName;
var remainingTime = getGameValue(growTimeKey) - getGameValue(timerKey);
timerEl.textContent = '(' + format.timer(remainingTime, true) + ')';
}
if (init)
{
observer.add([idKey, timerKey, stageKey, 'donorFarmingPatch'], function ()
{
return updatePatchInfo(patchId, infoElId, false);
});
}
}
// add seed name and change color of timer
function improveSeedGrowTimer()
{
improveTimer('div[id^="farming-patch-area-"]', 'black', 'blue', 'farming-patch-info-', 'farming-patch-area-', updatePatchInfo);
}
function init()
{
bindNewFormatter();
improveSmeltingTimer();
improveTreeGrowTimer();
improveSeedGrowTimer();
}
improveTimer_1.init = init;
})(improveTimer || (improveTimer = {}));
/**
* improve smelting dialog
*/
var improveSmelting;
(function (improveSmelting)
{
improveSmelting.name = 'improveSmelting';
var TIME_NEEDED_ID = 'smelting-time-needed';
var LAST_SMELTING_AMOUNT_KEY = 'lastSmeltingAmount';
var LAST_SMELTING_BAR_KEY = 'lastSmeltingBar';
var smeltingValue = null;
var amountInput;
function prepareAmountInput()
{
amountInput = document.getElementById('input-smelt-bars-amount');
amountInput.type = 'number';
amountInput.min = '0';
amountInput.step = '5';
function onValueChange()
{
smeltingValue = null;
window.selectBar('', null, amountInput, document.getElementById('smelting-furnace-capacity').value);
}
amountInput.addEventListener('mouseup', onValueChange);
amountInput.addEventListener('keyup', onValueChange);
amountInput.setAttribute('onkeyup', '');
}
function setBarCap(bar, capacity)
{
if (bar == '')
{
bar = window.selectedBar;
}
var requirements = SMELTING_REQUIREMENTS[bar];
var maxAmount = parseInt(capacity, 10);
for (var key in requirements)
{
var req = requirements[key];
maxAmount = Math.min(Math.floor(getGameValue(key) / req), maxAmount);
}
var value = parseInt(amountInput.value, 10);
if (value > maxAmount)
{
smeltingValue = value;
amountInput.value = maxAmount.toString();
}
else if (smeltingValue != null)
{
amountInput.value = Math.min(smeltingValue, maxAmount).toString();
if (smeltingValue <= maxAmount)
{
smeltingValue = null;
}
}
}
function prepareTimeNeeded()
{
var neededMatsEl = document.getElementById('dialogue-furnace-mats-needed');
var parent = neededMatsEl && neededMatsEl.parentElement;
if (!neededMatsEl || !parent)
{
return;
}
var br = document.createElement('br');
var timeBox = document.createElement('div');
timeBox.className = 'basic-smallbox';
timeBox.innerHTML = "<img src=\"images/icons/hourglass.png\" class=\"image-icon-30\">\n\t\tDuration: <span id=\"" + TIME_NEEDED_ID + "\"></span>";
var next = neededMatsEl.nextElementSibling;
parent.insertBefore(br, next);
parent.insertBefore(timeBox, next);
}
function updateTimeNeeded(value)
{
var timeEl = document.getElementById(TIME_NEEDED_ID);
if (!timeEl)
{
return;
}
var num = parseInt(value, 10);
var timePerBar = SMELTING_TIME[window.selectedBar];
timeEl.textContent = format.timer(timePerBar * num);
}
function init()
{
prepareAmountInput();
prepareTimeNeeded();
var _selectBar = window.selectBar;
var updateSmeltingRequirements = function (bar, inputElement, inputBarsAmountEl, capacity)
{
_selectBar(bar, inputElement, inputBarsAmountEl, capacity);
updateTimeNeeded(inputBarsAmountEl.value);
};
window.selectBar = function (bar, inputElement, inputBarsAmountEl, capacity)
{
setBarCap(bar, capacity);
// save selected bar
if (bar != '')
{
store.set(LAST_SMELTING_BAR_KEY, bar);
}
// save amount
store.set(LAST_SMELTING_AMOUNT_KEY, inputBarsAmountEl.value);
updateSmeltingRequirements(bar, inputElement, inputBarsAmountEl, capacity);
};
var lastBar = store.get(LAST_SMELTING_BAR_KEY);
var lastAmount = store.get(LAST_SMELTING_AMOUNT_KEY);
var _openFurnaceDialogue = window.openFurnaceDialogue;
window.openFurnaceDialogue = function (furnace)
{
var capacity = window.getFurnaceCapacity(furnace);
if (window.smeltingBarType == 0)
{
amountInput.max = capacity.toString();
}
// restore amount
var inputBarsAmountEl = document.getElementById('input-smelt-bars-amount');
if (inputBarsAmountEl && inputBarsAmountEl.value == '-1' && lastAmount != null)
{
inputBarsAmountEl.value = lastAmount;
}
_openFurnaceDialogue(furnace);
// restore selected bar
if ((!window.selectedBar || window.selectedBar == 'none') && lastBar != null)
{
window.selectedBar = lastBar;
}
// update whether requirements are fulfilled
var barInputId = 'input-furnace-' + split2Words(window.selectedBar, '-').toLowerCase();
var inputElement = document.getElementById(barInputId);
if (inputElement && inputBarsAmountEl)
{
updateSmeltingRequirements(window.selectedBar, inputElement, inputBarsAmountEl, capacity.toString());
}
};
}
improveSmelting.init = init;
})(improveSmelting || (improveSmelting = {}));
/**
* add chance to time calculator
*/
var fishingInfo;
(function (fishingInfo)
{
fishingInfo.name = 'fishingInfo';
/**
* calculates the number of seconds until the event with the given chance happened at least once with the given
* probability p (in percent)
*/
function calcSecondsTillP(chancePerSecond, p)
{
return Math.round(Math.log(1 - p / 100) / Math.log(1 - chancePerSecond));
}
function addChanceTooltip(headline, chancePerSecond, elId, targetEl)
{
// ensure tooltip exists and is correctly binded
var tooltipEl = ensureTooltip('chance-' + elId, targetEl);
// set elements content
var percValues = [1, 10, 20, 50, 80, 90, 99];
var percRows = '';
for (var _i = 0, percValues_1 = percValues; _i < percValues_1.length; _i++)
{
var p = percValues_1[_i];
percRows += "\n\t\t\t\t<tr>\n\t\t\t\t\t<td>" + p + "%</td>\n\t\t\t\t\t<td>" + format.time2NearestUnit(calcSecondsTillP(chancePerSecond, p), true) + "</td>\n\t\t\t\t</tr>";
}
tooltipEl.innerHTML = "<h2>" + headline + "</h2>\n\t\t\t<table class=\"chance\">\n\t\t\t\t<tr>\n\t\t\t\t\t<th>Probability</th>\n\t\t\t\t\t<th>Time</th>\n\t\t\t\t</tr>\n\t\t\t\t" + percRows + "\n\t\t\t</table>\n\t\t";
}
function addChanceStyle()
{
addStyle("\ntable.chance\n{\n\tborder-spacing: 0;\n}\ntable.chance th\n{\n\tborder-bottom: 1px solid gray;\n}\ntable.chance td:first-child\n{\n\tborder-right: 1px solid gray;\n\ttext-align: center;\n}\ntable.chance th,\ntable.chance td\n{\n\tpadding: 4px 8px;\n}\ntable.chance tr:nth-child(2n) td\n{\n\tbackground-color: white;\n}\n\t\t");
}
function addXp()
{
var table = document.querySelector('#dialogue-id-fishingRod table');
if (!table)
{
return;
}
var rows = table.rows;
for (var i = 0; i < rows.length; i++)
{
var row = rows.item(i);
if (row.classList.contains('xp-added'))
{
continue;
}
if (i == 0)
{
var xpCell = document.createElement('th');
xpCell.textContent = 'XP';
row.appendChild(xpCell);
}
else
{
var cell = row.insertCell(-1);
var rawFish = row.id.replace('dialogue-fishing-rod-tr-', '');
var xp = FISH_XP[rawFish];
cell.textContent = xp == null ? '?' : format.number(xp);
}
row.classList.add('xp-added');
}
}
function chance2TimeCalculator()
{
var fishList = ['shrimp', 'sardine', 'tuna', 'swordfish', 'shark'];
for (var _i = 0, fishList_1 = fishList; _i < fishList_1.length; _i++)
{
var fish = fishList_1[_i];
var rawFish = 'raw' + capitalize(fish);
var row = document.getElementById('dialogue-fishing-rod-tr-' + rawFish);
if (!row)
{
continue;
}
var chanceCell = row.cells.item(4);
var chance = (chanceCell.textContent || '')
.replace(/[^\d\/]/g, '')
.split('/')
.reduce(function (p, c)
{
return p / parseInt(c, 10);
}, 1);
addChanceTooltip("One raw " + fish + " at least every:", chance, rawFish, row);
}
}
function init()
{
addChanceStyle();
var _clicksShovel = window.clicksShovel;
window.clicksShovel = function ()
{
_clicksShovel();
var shovelChance = document.getElementById('dialogue-shovel-chance');
var titleEl = shovelChance.parentElement;
var chance = 1 / window.getChanceOfDiggingSand();
addChanceTooltip('One sand at least every:', chance, 'shovel', titleEl);
};
// depends on fishingXp
var _clicksFishingRod = window.clicksFishingRod;
window.clicksFishingRod = function ()
{
_clicksFishingRod();
addXp();
chance2TimeCalculator();
};
}
fishingInfo.init = init;
})(fishingInfo || (fishingInfo = {}));
/**
* add tooltips for recipes
*/
var recipeTooltips;
(function (recipeTooltips)
{
recipeTooltips.name = 'recipeTooltips';
function updateRecipeTooltips(recipeKey, recipes)
{
var table = document.getElementById('table-' + recipeKey + '-recipe');
var rows = table.rows;
function recipe2Title(recipe)
{
return recipe.recipe
.map(function (name, i)
{
return format.number(recipe.recipeCost[i]) + ' '
+ split2Words(name).toLowerCase();
})
.join(' + ');
};
for (var i = 1; i < rows.length; i++)
{
var row = rows.item(i);
var key = row.id.replace(recipeKey + '-', '');
var recipe = recipes[key];
var requirementCell = row.cells.item(3);
requirementCell.title = recipe2Title(recipe);
window.$(requirementCell).tooltip();
}
}
function updateTooltipsOnReinitRecipes(key)
{
var capitalKey = capitalize(key);
var processKey = 'process' + capitalKey + 'Tab';
var _processTab = window[processKey];
window[processKey] = function ()
{
var reinit = !!getGameValue('refreshLoad' + capitalKey + 'Table');
_processTab();
if (reinit)
{
updateRecipeTooltips(key, getGameValue(key + 'Recipes'));
}
};
}
function init()
{
updateTooltipsOnReinitRecipes('crafting');
updateTooltipsOnReinitRecipes('brewing');
updateTooltipsOnReinitRecipes('magic');
updateTooltipsOnReinitRecipes('cooksBook');
}
recipeTooltips.init = init;
})(recipeTooltips || (recipeTooltips = {}));
/**
* fix formatting of numbers
*/
var fixNumbers;
(function (fixNumbers)
{
fixNumbers.name = 'fixNumbers';
function prepareRecipeForTable(recipe)
{
// create a copy of the recipe to prevent requirement check from failing
var newRecipe = JSON.parse(JSON.stringify(recipe));
newRecipe.recipeCost = recipe.recipeCost.map(function (cost)
{
return format.number(cost);
});
newRecipe.xp = format.number(recipe.xp);
return newRecipe;
}
function fixNumberFormat()
{
var _addRecipeToBrewingTable = window.addRecipeToBrewingTable;
window.addRecipeToBrewingTable = function (brewingRecipe)
{
_addRecipeToBrewingTable(prepareRecipeForTable(brewingRecipe));
};
var _addRecipeToMagicTable = window.addRecipeToMagicTable;
window.addRecipeToMagicTable = function (magicRecipe)
{
_addRecipeToMagicTable(prepareRecipeForTable(magicRecipe));
};
var tooltipList = document.querySelectorAll('#tooltip-list div[id^="tooltip-"][id$="Seeds"]');
for (var i = 0; i < tooltipList.length; i++)
{
var tooltip = tooltipList[i];
tooltip.innerHTML = format.numbersInText(tooltip.innerHTML);
}
var fightEnergyCells = document.querySelectorAll('#dialogue-fight tr > td:nth-child(4)');
for (var i = 0; i < fightEnergyCells.length; i++)
{
var cell = fightEnergyCells[i];
cell.innerHTML = format.numbersInText(cell.innerHTML);
}
}
function init()
{
fixNumberFormat();
}
fixNumbers.init = init;
})(fixNumbers || (fixNumbers = {}));
/**
* add slider for machines
*/
var betterMachines;
(function (betterMachines)
{
betterMachines.name = 'betterMachines';
var $slider;
function createSlider()
{
var br = document.querySelector('#dialogue-machinery-current-total ~ br');
var parent = br && br.parentElement;
if (!br || !parent)
{
return;
}
var slider = document.createElement('div');
slider.style.margin = '10px 5px';
parent.insertBefore(slider, br);
$slider = window.$(slider)
.slider(
{
range: false
, min: 0
, max: 10
, value: 0
, slide: function (event, ui)
{
return updateValue(ui.value);
}
});
// hide br and up/down arrows
br.style.display = 'none';
var arrows = document.querySelectorAll('input[onclick^="turnOn("]');
for (var i = 0; i < arrows.length; i++)
{
arrows[i].style.display = 'none';
}
var els = document.querySelectorAll('[onclick*="openMachineryDialogue("]');
var boundMachineKeyList = [];
for (var i = 0; i < els.length; i++)
{
var match = els[i].id.match(/openMachineryDialogue\('(.+?)'\)/);
if (match)
{
boundMachineKeyList.push(getBoundKey(match[1]));
}
}
observer.add(boundMachineKeyList, function ()
{
return updateMax();
});
}
function updateMax()
{
var machineEl = document.getElementById('dialogue-machinery-chosen');
if (machineEl && machineEl.value != '')
{
var boundMachineKey = getBoundKey(machineEl.value);
$slider.slider('option', 'max', getGameValue(boundMachineKey));
}
}
function updateValue(value)
{
var typeEl = document.getElementById('dialogue-machinery-chosen');
var numEl = document.getElementById('dialogue-machinery-current-on');
if (numEl && typeEl)
{
var valueBefore = parseInt(numEl.textContent || '0', 10);
var machine = typeEl.value;
var increment = valueBefore < value;
var diff = Math.abs(valueBefore - value);
for (var i = 0; i < diff; i++)
{
window.turnOn(machine, increment);
}
}
}
function init()
{
createSlider();
var _openMachineryDialogue = window.openMachineryDialogue;
window.openMachineryDialogue = function (machineType)
{
_openMachineryDialogue(machineType);
updateMax();
$slider.slider('value', getGameValue(machineType + 'On'));
};
}
betterMachines.init = init;
})(betterMachines || (betterMachines = {}));
/**
* improve behaviour of amount inputs
*/
var amountInputs;
(function (amountInputs)
{
amountInputs.name = 'amountInputs';
function getMax(recipe)
{
var max = Number.MAX_SAFE_INTEGER;
for (var i = 0; i < recipe.recipe.length; i++)
{
max = Math.min(max, Math.floor(getGameValue(recipe.recipe[i]) / recipe.recipeCost[i]));
}
return max;
}
function setAmount(id, recipeCollection, key)
{
var numInput = document.getElementById(id);
if (!numInput)
{
return;
}
var max = getMax(recipeCollection[key]);
numInput.value = max.toString();
numInput.select();
}
function init()
{
var _multiCraft = window.multiCraft;
window.multiCraft = function (item)
{
_multiCraft(item);
setAmount('dialogue-multicraft-input', window.craftingRecipes, item);
};
var _brew = window.brew;
window.brew = function (potion)
{
_brew(potion);
setAmount('dialogue-brewing-input', window.brewingRecipes, potion);
};
var _cooksBookInputDialogue = window.cooksBookInputDialogue;
window.cooksBookInputDialogue = function (food)
{
_cooksBookInputDialogue(food);
setAmount('dialogue-cooksBook-input', window.cooksBookRecipes, food);
};
}
amountInputs.init = init;
})(amountInputs || (amountInputs = {}));
/**
* improves the top bar
*/
var newTopbar;
(function (newTopbar)
{
newTopbar.name = 'newTopbar';
function init()
{
addStyle("\ntable.top-links,\ntable.top-links *\n{\n\tpadding: 0;\n}\ntable.top-links td > *\n{\n\tdisplay: inline-block;\n\tpadding: 2px 6px;\n}\n\t\t");
var table = document.querySelector('table.top-links');
if (!table)
{
return;
}
var row = table.rows.item(0);
var cells = row.cells;
var tabIdx = [2, 4];
var infoIdx = [5, 6];
var newRow = table.insertRow(-1);
var linkCell = newRow.insertCell(-1);
var tabCell = newRow.insertCell(-1);
tabCell.style.textAlign = 'center';
var infoCell = newRow.insertCell(-1);
infoCell.style.textAlign = 'right';
for (var i = 0; i < cells.length; i++)
{
var container = linkCell;
if (tabIdx.indexOf(i) != -1)
{
container = tabCell;
}
else if (infoIdx.indexOf(i) != -1)
{
container = infoCell;
}
var cell = cells.item(i);
var el = cell.firstElementChild;
if (cell.childNodes.length > 1)
{
el = document.createElement('span');
el.style.color = 'yellow';
while (cell.childNodes.length > 0)
{
el.appendChild(cell.childNodes[0]);
}
}
if (container.children.length > 0)
{
container.appendChild(document.createTextNode('|'));
}
if (el)
{
container.appendChild(el);
}
}
var parent = row.parentElement;
if (parent)
{
parent.removeChild(row);
}
var _openTab = window.openTab;
window.openTab = function (newTab)
{
var oldTab = window.currentOpenTab;
_openTab(newTab);
var children = tabCell.children;
for (var i = 0; i < children.length; i++)
{
var el = children[i];
var match = (el.getAttribute('onclick') || '').match(/openTab\('([^']+)'\)/);
if (!match)
{
continue;
}
var tab = match[1];
if (oldTab == tab)
{
el.style.color = '';
}
if (newTab == tab)
{
el.style.color = 'white';
}
}
};
}
newTopbar.init = init;
})(newTopbar || (newTopbar = {}));
/**
* style tweaks
*/
var styleTweaks;
(function (styleTweaks)
{
styleTweaks.name = 'styleTweaks';
function addTweakStyle(setting, style)
{
if (setting != '')
{
var prefix = setting == '' ? '' : 'body.' + setting;
style = style.replace(/(^\s*|,\s*|\}\s*)([^\{\},]+)(,|\s*\{)/g, '$1' + prefix + ' $2$3');
document.body.classList.add(setting);
}
addStyle(style, setting != '' ? setting : null);
}
// tweak oil production/consumption
function tweakOil()
{
addTweakStyle('tweak-oil', "\nspan#oil-flow-values\n{\n\tmargin-left: .5em;\n\tpadding-left: 2rem;\n\tposition: relative;\n}\n#oil-flow-values > span:nth-child(-n+2)\n{\n\tfont-size: 0px;\n\tposition: absolute;\n\tleft: 0;\n\ttop: -0.75rem;\n\tvisibility: hidden;\n}\n#oil-flow-values > span:nth-child(-n+2) > span\n{\n\tfont-size: 1rem;\n\tvisibility: visible;\n}\n#oil-flow-values > span:nth-child(2)\n{\n\ttop: 0.75rem;\n}\n#oil-flow-values span[data-item-display=\"oilIn\"]::before\n{\n\tcontent: '+';\n}\n#oil-flow-values span[data-item-display=\"oilOut\"]::before\n{\n\tcontent: '-';\n}\n\t\t");
// make room for oil cell on small devices
var oilFlowValues = document.getElementById('oil-flow-values');
var oilFlowCell = oilFlowValues.parentElement;
oilFlowCell.style.width = '30%';
}
function tweakSelection()
{
addTweakStyle('no-select', "\ntable.tab-bar,\nspan.item-box,\ndiv.farming-patch,\ndiv.farming-patch-locked,\ndiv#tab-sub-container-combat > span,\ntable.top-links a,\n#hero-area > div:last-child\n{\n\t-webkit-user-select: none;\n\t-moz-user-select: none;\n\t-ms-user-select: none;\n\tuser-select: none;\n}\n\t\t");
}
// tweak stardust monitor of DH2QoL to keep it in place
function tweakStardust()
{
addTweakStyle('dh2qol', "\n#dh2qol-stardustMonitor\n{\n\tdisplay: inline-block;\n\tmargin-left: .25rem;\n\ttext-align: left;\n\twidth: 2.5rem;\n}\n\t\t");
}
function tweakSkillLevelText()
{
addTweakStyle('', "\ndiv.skill-xp-label\n{\n\ttext-shadow: white 0px 0px 0.5rem;\n}\n\t\t");
}
function tweakFightDialog()
{
addTweakStyle('smaller-fight-dialog', "\n#dialogue-fight img[width=\"300px\"]\n{\n\twidth: 120px;\n\theight: 50px;\n}\n#dialogue-fight img[src=\"images/icons/combat.png\"] ~ br\n{\n\tdisplay: none;\n}\n\t\t");
}
function init()
{
tweakOil();
tweakSelection();
tweakStardust();
tweakSkillLevelText();
tweakFightDialog();
}
styleTweaks.init = init;
})(styleTweaks || (styleTweaks = {}));
/**
* init
*/
var scriptInitialized = false;
function init()
{
console.info('[%s] "DH2 Fixed %s" up and running.', (new Date).toLocaleTimeString(), version);
scriptInitialized = true;
var initModules = [
settings
, notifications
, gameEvents
, temporaryFixes
, hideCraftedRecipes
, hideUselessItems
, improveItemBoxes
, chat
, improveTimer
, improveSmelting
, fishingInfo
, recipeTooltips
, fixNumbers
, betterMachines
, amountInputs
, newTopbar
, styleTweaks
];
window.initModules = initModules;
for (var _i = 0, initModules_1 = initModules; _i < initModules_1.length; _i++)
{
var module = initModules_1[_i];
try
{
module.init();
}
catch (error)
{
console.error('Error during initialization in module "' + module.name + '":', error);
}
}
}
document.addEventListener('DOMContentLoaded', function ()
{
var oldValues = new Map();
var _doCommand = window.doCommand;
window.doCommand = function (data)
{
if (data.startsWith('REFRESH_ITEMS='))
{
oldValues = new Map();
for (var _i = 0, _a = window.jsItemArray; _i < _a.length; _i++)
{
var key = _a[_i];
oldValues.set(key, getGameValue(key));
}
_doCommand(data);
if (!scriptInitialized)
{
init();
}
return;
}
else if (!scriptInitialized)
{
if (data.startsWith('CHAT='))
{
var parts = data.substr(5).split('~');
return chat.newAddToChatBox(parts[0], parts[1], parts[2], parts[3], 0);
}
else if (data.startsWith('PM='))
{
return chat.newAddToChatBox(window.username, '0', '0', data.substr(3), 1);
}
}
var formattedData = data;
if (data.startsWith('STHS=') || data.startsWith('STE=') || data.startsWith('SM=') || data.startsWith('ST='))
{
if (data.indexOf('Your account has been running for:') != -1)
{
data = data.replace(/Your account has been running for: (\d+) minutes./, function (wholeMatch, minutes)
{
return 'Your account has been running for ' + format.min2Str(minutes) + '.';
});
}
formattedData = format.numbersInText(data);
}
var ret = _doCommand(formattedData);
// notifications for this kind of message: "SM=An update has been scheduled for today."
if (data.startsWith('SM='))
{
if (settings.get(settings.KEY.showNotifications))
{
var msg = data.substr(3)
.replace(/<br\s*\/?>/g, '\n')
.replace(/<img src='images\/(.+?)\.png'.+?\/?> (\d+)/g, function (wholeMatch, key, amount)
{
return format.number(amount) + ' ' + split2Words(key) + ', ';
})
.replace(/(\s)\1+/g, '$1')
.replace(/, $/, '')
.replace(/<.+?>/g, '');
notifications.event('Message from server'
, {
body: msg
});
}
}
return ret;
};
var _refreshItemValues = window.refreshItemValues;
window.refreshItemValues = function (itemKeyList, firstLoad)
{
_refreshItemValues(itemKeyList, firstLoad);
for (var _i = 0, itemKeyList_1 = itemKeyList; _i < itemKeyList_1.length; _i++)
{
var key = itemKeyList_1[_i];
observer.notify(key, oldValues.get(key));
}
};
});
/**
* fix web socket errors
*/
var main;
(function (main)
{
function webSocketLoaded(event)
{
var ws = window.webSocket;
if (ws == null)
{
console.error('no webSocket instance found!');
return;
}
var messageQueue = [];
var _onMessage = ws.onmessage;
ws.onmessage = function (event)
{
return messageQueue.push(event);
};
document.addEventListener('DOMContentLoaded', function ()
{
messageQueue.forEach(function (event)
{
return window.onMessage(event);
});
ws.onmessage = _onMessage;
});
var commandQueue = [];
var _cBytes = window.cBytes;
window.cBytes = function (command)
{
return commandQueue.push(command);
};
var _onOpen = ws.onopen;
ws.onopen = function (event)
{
window.cBytes = _cBytes;
commandQueue.forEach(function (command)
{
return window.cBytes(command);
});
return _onOpen.call(ws, event);
};
}
function isScriptElement(el)
{
return el.nodeName === 'SCRIPT';
}
function isWebSocketScript(script)
{
return script.src.includes('socket.js');
}
var found = false;
var scripts = document.head ? document.head.querySelectorAll('script') : [];
for (var i = 0; i < scripts.length; i++)
{
if (isWebSocketScript(scripts[i]))
{
// does this work?
scripts[i].onload = webSocketLoaded;
found = true;
}
}
if (!found)
{
// create an observer instance
var mutationObserver_1 = new MutationObserver(function (mutationList)
{
mutationList.forEach(function (mutation)
{
if (mutation.addedNodes.length === 0)
{
return;
}
for (var i = 0; i < mutation.addedNodes.length; i++)
{
var node = mutation.addedNodes[i];
if (isScriptElement(node) && isWebSocketScript(node))
{
mutationObserver_1.disconnect();
node.onload = webSocketLoaded;
return;
}
}
});
});
mutationObserver_1.observe(document.head
, {
childList: true
});
}
// fix scrollText (e.g. when joining the game and receiving xp at that moment)
window.mouseX = window.innerWidth / 2;
window.mouseY = window.innerHeight / 2;
})(main || (main = {}));
})();