// ==UserScript== // @sandbox raw // @name PSNP+ // @namespace psnp.plus // @version 8.5 // @description Browser script that makes PSNProfiles.com just a little bit better // @author HusKyCode // @downloadURL https://psnp-plus.huskycode.dev/psnp-plus.user.js // @updateURL https://psnp-plus.huskycode.dev/psnp-plus.meta.js // @run-at document-start // @inject-into page // @noframes // @match https://psnprofiles.com/* // @grant GM_xmlhttpRequest // @grant GM.getValue // @grant GM.setValue // @grant GM.deleteValue // @icon https://psnp-plus.huskycode.dev/icon.png // ==/UserScript== /******/ (() => { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ([ /* 0 */, /* 1 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "launchAfterDomContentLoaded": () => (/* binding */ launchAfterDomContentLoaded), /* harmony export */ "launchImmediately": () => (/* binding */ launchImmediately) /* harmony export */ }); /* harmony import */ var _modules_Base__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2); /* harmony import */ var _modules_Frontpage__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(44); /* harmony import */ var _modules_immediate_FrontpageImmediate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(48); /* harmony import */ var _modules_Guide__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(50); /* harmony import */ var _modules_Profile__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(56); /* harmony import */ var _modules_immediate_ProfileImmediate__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(73); /* harmony import */ var _modules_Trophies__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(74); /* harmony import */ var _modules_immediate_TrophiesImmediate__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(77); /* harmony import */ var _modules_GameLeaderboard__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(78); /* harmony import */ var _modules_Games__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(79); /* harmony import */ var _modules_Search__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(80); /* harmony import */ var _modules_Sessions__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(81); /* harmony import */ var _modules_Series__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(82); /* harmony import */ var _modules_100club__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(83); /* harmony import */ var _modules_Trophy__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(84); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(12); /* harmony import */ var _util_user__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(19); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(5); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(34); /* harmony import */ var _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(21); /* harmony import */ var _modules_immediate_BaseImmediate__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(86); /* harmony import */ var _modules_immediate_GuideImmediate__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(87); const featurePath = (0,_util_url__WEBPACK_IMPORTED_MODULE_15__.getPathSegments)()[0]; const pathSegment1 = (0,_util_url__WEBPACK_IMPORTED_MODULE_15__.getPathSegments)()[1]; const pathSegment2 = (0,_util_url__WEBPACK_IMPORTED_MODULE_15__.getPathSegments)()[2]; function launchImmediately() { console.debug('document-start launcher running. Feature path:', featurePath); new _modules_immediate_BaseImmediate__WEBPACK_IMPORTED_MODULE_20__.BaseImmediate().run(); switch (featurePath) { case 'guides': case 'leaderboard': case 'games': case 'trophy': case 'series': case 'lib': case 'login': case 'about': case 'account': case '100-club': case 'game-leaderboard': case 'search': case 'sessions': case 'session': // NOTE: We don't do anything here. break; case 'guide': new _modules_immediate_GuideImmediate__WEBPACK_IMPORTED_MODULE_21__.GuideImmediate(pathSegment2).run(); break; case 'trophies': new _modules_immediate_TrophiesImmediate__WEBPACK_IMPORTED_MODULE_7__.TrophiesImmediate().run(); break; default: if (featurePath != null) { new _modules_immediate_ProfileImmediate__WEBPACK_IMPORTED_MODULE_5__.ProfileImmediate().run(); } else { new _modules_immediate_FrontpageImmediate__WEBPACK_IMPORTED_MODULE_2__.FrontpageImmediate(new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_17__.SettingsStorage()).run(); } break; } } async function launchAfterDomContentLoaded() { const psnId = (0,_util_user__WEBPACK_IMPORTED_MODULE_16__.getPsnId)(); const isMe = psnId === featurePath; console.debug('DOMContentLoaded launcher running. Feature path:', featurePath); await (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_18__.loadJqueryUi)(); // Run Base module new _modules_Base__WEBPACK_IMPORTED_MODULE_0__.Base(psnId, new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_17__.SettingsStorage(), new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_19__.ScriptStateStorage()).run(); switch (featurePath) { case 'guides': case 'leaderboard': case 'lib': case 'login': case 'about': case 'account': case 'session': // NOTE: We don't do anything here. break; case '100-club': new _modules_100club__WEBPACK_IMPORTED_MODULE_13__.HundredClub().run(); break; case 'game-leaderboard': new _modules_GameLeaderboard__WEBPACK_IMPORTED_MODULE_8__.GameLeaderboard(new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_17__.SettingsStorage()).run(); break; case 'trophy': new _modules_Trophy__WEBPACK_IMPORTED_MODULE_14__.Trophy().run(); break; case 'trophies': await new _modules_Trophies__WEBPACK_IMPORTED_MODULE_6__.Trophies(pathSegment2).run(); break; case 'guide': await (new _modules_Guide__WEBPACK_IMPORTED_MODULE_3__.Guide(pathSegment2)).run(); break; case 'games': new _modules_Games__WEBPACK_IMPORTED_MODULE_9__.Games().run(); break; case 'search': new _modules_Search__WEBPACK_IMPORTED_MODULE_10__.Search(pathSegment1).run(); break; case 'series': new _modules_Series__WEBPACK_IMPORTED_MODULE_12__.Series(pathSegment2).run(); break; case 'sessions': new _modules_Sessions__WEBPACK_IMPORTED_MODULE_11__.Sessions().run(); break; default: // NOTE: featurePath is some username if (featurePath != null) { new _modules_Profile__WEBPACK_IMPORTED_MODULE_4__.Profile(isMe, featurePath, pathSegment1).run(); } else { new _modules_Frontpage__WEBPACK_IMPORTED_MODULE_1__.Frontpage(new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_17__.SettingsStorage()).run(); } break; } } /***/ }), /* 2 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Base": () => (/* binding */ Base) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _features_settings_SettingsPanel__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4); /* harmony import */ var _util_user__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(19); /* harmony import */ var _features_sessions_SessionStorage__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(17); /* harmony import */ var _ui_ui_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(39); /* harmony import */ var _features_plat_prices_PlatPricesStorage__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(30); /* harmony import */ var _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(24); /* harmony import */ var _features_update_UpdatePanel__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(41); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(25); /* harmony import */ var _features_donators_DonatorsStorage__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(43); class Base { constructor(psnId, settingsStorage, scriptStateStorage) { this._psnId = psnId; this._settingsStorage = settingsStorage; this._scriptStateStorage = scriptStateStorage; } _getDropdownMenu() { return _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div.user-menu > div.dropdown > ul.dropdown-menu'); } _appendButtonsInUserDropdown() { this._getDropdownMenu() .find('li', { containsText: 'Your Profile' }) .after(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', `/${this._psnId}#gamelists`) .setText('Game Lists'))); } _appendPsnppSettingsButton() { this._getDropdownMenu() .find('li', { containsText: 'Settings' }) .after(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('PSNP+ Settings') .click((e) => { e.preventDefault(); (0,_ui_ui_utils__WEBPACK_IMPORTED_MODULE_4__.appendPanel)(new _features_settings_SettingsPanel__WEBPACK_IMPORTED_MODULE_1__.SettingsPanel()); }))); } _modifyUpdateProfileButton() { this._getDropdownMenu() .find('a', { containsText: 'Update Profile' }) .setAttribute('href', (0,_util_user__WEBPACK_IMPORTED_MODULE_2__.getUpdateProfileRedirectUrl)(this._psnId, '/' + this._psnId)); } _modifySessionsLink() { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div#header div.navigation a[href="/sessions"]') .setAttribute('href', '/sessions?all'); } _checkUpdate() { const version = this._scriptStateStorage.get('version'); this._scriptStateStorage.set('version', GM_info.script.version); if (version !== GM_info.script.version) { (0,_ui_ui_utils__WEBPACK_IMPORTED_MODULE_4__.appendPanel)(new _features_update_UpdatePanel__WEBPACK_IMPORTED_MODULE_7__.UpdatePanel()); } } _appendScriptInfo() { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div.logo', { eq: 1 }).append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('style', `font-size: 10px; background: ${_util_constants__WEBPACK_IMPORTED_MODULE_8__.COLOR_PURPLE};`) .setAttribute('href', _util_constants__WEBPACK_IMPORTED_MODULE_8__.LINK_MAIN_THREAD) .setAttribute('target', '_blank') .setText(`PSNP+ v${GM_info.script.version}`)); } _detectServiceDown() { const isDown = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('h1', { equalsText: '503 Service Temporarily Unavailable' }).exists(); if (isDown) { setTimeout(() => location.reload(), 5000); } return isDown; } run() { console.debug('Base module is running'); if (this._detectServiceDown()) { return; } this._appendScriptInfo(); this._checkUpdate(); if (this._settingsStorage.get('automaticallyRedirectAfterUpdatingProfile')) { this._modifyUpdateProfileButton(); } if (this._settingsStorage.get('gamingSessionsShowAllByDefault')) { this._modifySessionsLink(); } this._appendButtonsInUserDropdown(); this._appendPsnppSettingsButton(); if (this._settingsStorage.get('gamingSessionsScraping')) { const sessionStorage = new _features_sessions_SessionStorage__WEBPACK_IMPORTED_MODULE_3__.SessionStorage(); sessionStorage.refresh() .then((didRefresh) => { if (didRefresh) { console.debug('Sessions have been refreshed.'); } }) .catch((e) => console.debug('Failed to refresh sessions.', e)); } if (this._settingsStorage.get('markUnobtainableTrophies')) { const utStorage = new _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_6__.UnobtainableTrophiesStorage(); utStorage.refresh() .then((didRefresh) => { if (didRefresh) { console.debug('Unobtainable trophies have been refreshed.'); } }) .catch((e) => console.debug('Failed to refresh unobtainable trophies.', e)); } const donatorsStorage = new _features_donators_DonatorsStorage__WEBPACK_IMPORTED_MODULE_9__.DonatorsStorage(); donatorsStorage.refresh() .then((didRefresh) => { if (didRefresh) { console.debug('Donators have been refreshed.'); } }) .catch((e) => console.debug('Failed to refresh donators.', e)); if (this._settingsStorage.get('platPricesIntegration')) { new _features_plat_prices_PlatPricesStorage__WEBPACK_IMPORTED_MODULE_5__.PlatPricesStorage().clearExpired(); } } } /***/ }), /* 3 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "J": () => (/* binding */ J), /* harmony export */ "JC": () => (/* binding */ JC), /* harmony export */ "all": () => (/* binding */ all) /* harmony export */ }); function find(query, options, base = document) { let allElements = Array.from(base.querySelectorAll(query)); if (options.containsText != null) { allElements = allElements.filter((el) => { const content = el.textContent == null ? '' : el.textContent; return RegExp(options.containsText).test(content); }); } if (options.equalsText != null) { allElements = allElements.filter((el) => { const content = el.textContent == null ? '' : el.textContent; return options.equalsText === content; }); } return allElements; } class J { constructor(base) { this._base = base; } static q(query, options = {}, base = document) { const allElements = find(query, options, base); if (allElements.length === 0) { return new J(null); } const chosenElement = options.eq === undefined ? allElements[0] : allElements[options.eq]; return new J(chosenElement); } static c(tagname) { return new J(document.createElement(tagname)); } find(query, options = {}) { if (this._base == null) { return this; } const allElements = find(query, options, this._base); if (allElements.length === 0) { this._base = null; return this; } this._base = options.eq === undefined ? allElements[0] : allElements[options.eq]; return this; } append(...children) { children.forEach((x) => { if (x == null || this._base == null) { return; } const toAppend = typeof x === 'string' ? document.createTextNode(x) : x.get(); this._base.appendChild(toAppend); }); return this; } prepend(...children) { children.reverse().forEach((x) => { if (x == null || this._base == null || this._base.parentElement == null) { return; } const toAppend = typeof x === 'string' ? document.createTextNode(x) : x.get(); this._base.insertBefore(toAppend, this._base.firstChild); }); return this; } after(...children) { children.reverse().forEach((x) => { if (this._base == null) { return; } if (this._base.parentNode == null) { return; } const toAppend = typeof x === 'string' ? document.createTextNode(x) : x.get(); this._base.parentNode.insertBefore(toAppend, this._base.nextSibling); }); return this; } before(...children) { children.forEach((x) => { if (this._base == null) { return; } if (this._base.parentNode == null) { return; } const toAppend = typeof x === 'string' ? document.createTextNode(x) : x.get(); this._base.parentNode.insertBefore(toAppend, this._base); }); return this; } prev() { if (this._base == null) { return this; } this._base = this._base.previousElementSibling; return this; } next() { if (this._base == null) { return this; } this._base = this._base.nextElementSibling; return this; } isEmpty() { if (this._base == null) { return true; } return this._base.innerHTML.trim() === ''; } empty() { if (this._base == null) { return this; } this._base.innerHTML = ''; return this; } remove() { if (this._base == null) { return this; } if (this._base.parentNode == null) { return this; } this._base.parentNode.removeChild(this._base); return this; } getText() { if (this._base == null) { return ''; } return this._base.textContent == null ? '' : this._base.textContent; } setText(text) { if (this._base == null) { return this; } this._base.textContent = text; return this; } getValue() { return this._base.value; } setValue(value) { this._base.value = value; return this; } getOuterHTML() { if (this._base == null) { return ''; } return this._base.outerHTML; } setOuterHTML(value) { if (this._base == null) { return this; } this._base.outerHTML = value; return this; } getInnerHtml() { if (this._base == null) { return ''; } return this._base.innerHTML; } setInnerHtml(value) { if (this._base == null) { return this; } this._base.innerHTML = value; return this; } getAttribute(attribute) { if (this._base == null) { return ''; } const attributeValue = this._base.getAttribute(attribute); return attributeValue == null ? '' : attributeValue; } setAttribute(attribute, value) { if (this._base == null) { return this; } this._base.setAttribute(attribute, value); return this; } removeAttribute(attribute) { if (this._base == null) { return this; } this._base.removeAttribute(attribute); return this; } getClassName() { if (this._base == null) { return ''; } return this._base.className; } toggleClass(className) { if (this._base == null) { return this; } this._base.classList.toggle(className); return this; } addClass(...classNames) { classNames.forEach((className) => { if (this._base == null) { return; } this._base.classList.add(className); }); return this; } removeClass(className) { if (this._base == null) { return this; } this._base.classList.remove(className); return this; } hasClass(className) { if (this._base == null) { return false; } return this._base.classList.contains(className); } triggerClick() { if (this._base == null) { return this; } this._base.click(); return this; } triggerKeypress(key) { if (this._base == null) { return this; } this._base.dispatchEvent(new KeyboardEvent('keypress', { key })); return this; } click(callback) { if (this._base == null) { return this; } this._base.addEventListener('click', (e) => callback(e, this)); return this; } load(callback) { if (this._base == null) { return this; } this._base.addEventListener('load', (e) => callback(e, this)); return this; } error(callback) { if (this._base == null) { return this; } this._base.addEventListener('error', (e) => callback(e, this)); return this; } mouseenter(callback) { if (this._base == null) { return this; } this._base.addEventListener('mouseenter', (e) => callback(e, this)); return this; } mouseleave(callback) { if (this._base == null) { return this; } this._base.addEventListener('mouseleave', (e) => callback(e, this)); return this; } keyup(callback) { if (this._base == null) { return this; } this._base.addEventListener('keyup', (e) => callback(e, this)); return this; } change(callback) { if (this._base == null) { return this; } this._base.addEventListener('change', (e) => callback(e, this)); return this; } setCss(property, value) { if (this._base == null) { return this; } this._base.style[property] = value; return this; } exists() { return this._base != null; } parent() { if (this._base == null) { return this; } this._base = this._base.parentElement; return this; } show() { if (this._base == null) { return this; } this._base.style.display = ''; return this; } hide() { if (this._base == null) { return this; } this._base.style.display = 'none'; return this; } clone() { return new J(this._base); } get() { if (this._base == null) { throw new Error('Base element is null'); } return this._base; } apply(runner) { if (this._base == null) { return this; } runner(this._base); return this; } condition(cond, runner) { if (!cond) { return this; } if (this._base == null) { return this; } runner(this); return this; } } class JC extends J { constructor(tagname) { super(J.c(tagname).get()); } } function all(query, options = {}, base = document) { return find(query, options, base).map(x => new J(x)); } /***/ }), /* 4 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "SettingsPanel": () => (/* binding */ SettingsPanel) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _SettingsStorage__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5); /* harmony import */ var _util_data__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7); /* harmony import */ var _ui_panel_Panel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(31); /* harmony import */ var _sessions_SessionStorage__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(17); /* harmony import */ var _ui_panel_PanelSection__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(32); /* harmony import */ var _ui_panel_PanelInput__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(33); /* harmony import */ var _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(36); /* harmony import */ var _ui_panel_PanelBottom__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(37); /* harmony import */ var _ui_panel_PanelSelect__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(38); /* harmony import */ var _plat_prices_PlatPricesAPI__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(23); /* harmony import */ var _plat_prices_PlatPricesStorage__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(30); /* harmony import */ var _unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(24); /* harmony import */ var _guide_GuideStorage__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(29); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(25); /* harmony import */ var _ui_ui_utils__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(39); /* harmony import */ var _lists_ListRefreshPanel__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(40); /* harmony import */ var _game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(20); /* harmony import */ var _update_UpdatePanel__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(41); /* harmony import */ var _util_async__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(42); class SettingsDataButtons extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(closePanelFunction) { super('div'); this._closePanelFunction = closePanelFunction; this._build(); } _build() { const fileInput = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('input') .setAttribute('type', 'file') .setAttribute('style', 'display: none;') .change(async (e) => { if (e == null || e.target == null) { return; } const target = e.target; if (target.files == null || target.files.length === 0) { return; } await (0,_util_data__WEBPACK_IMPORTED_MODULE_2__.importData)(target.files[0]); location.reload(); }); this .addClass('row', 'center-xs') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-2') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('button', 'green') .setAttribute('href', '#') .setText('Refresh Lists') .click((e) => { e.preventDefault(); this._closePanelFunction(); (0,_ui_ui_utils__WEBPACK_IMPORTED_MODULE_15__.appendPanel)(new _lists_ListRefreshPanel__WEBPACK_IMPORTED_MODULE_16__.ListRefreshPanel()); })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-2') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('button', 'yellow') .setAttribute('href', '#') .setText('Clear') .click((e) => { e.preventDefault(); const confirmed = confirm('Are you sure you want to clear all your PSNP+ data? This operation is irreversible.'); if (!confirmed) { return; } (0,_util_data__WEBPACK_IMPORTED_MODULE_2__.clearData)(); location.reload(); })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-2') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('button', 'blue') .setAttribute('href', '#') .setText('Export') .click(async (e) => { e.preventDefault(); await (0,_util_async__WEBPACK_IMPORTED_MODULE_19__.safeRun)(() => (0,_util_data__WEBPACK_IMPORTED_MODULE_2__.exportData)()); })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-2') .append(fileInput, _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('button', 'blue') .setAttribute('href', '#') .setText('Import') .click((e) => { e.preventDefault(); fileInput.triggerClick(); }))); } } class SettingsPanel extends _ui_panel_Panel__WEBPACK_IMPORTED_MODULE_3__.Panel { constructor() { super('PSNP+ Settings'); this._addContent(new _SettingsStorage__WEBPACK_IMPORTED_MODULE_1__.SettingsStorage()); } _addContent(settingsStorage) { const markUnobtainableTrophies = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Mark unobtainable trophies', settingsStorage.get('markUnobtainableTrophies'), 'Known unobtainable trophies will be marked across PSNProfiles.'); const hideStacksOnTheFrontpage = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Merge stacks in "New Trophy Lists" on the frontpage', settingsStorage.get('hideStacksOnTheFrontpage'), 'PSNP+ will show you latest 10 unique trophy lists. All extra stacks will be merged.'); const mergePopularGamesOnTheFrontpage = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Merge stacks in "Popular Games This Week" on the frontpage', settingsStorage.get('mergePopularGamesOnTheFrontpage'), 'PSNP+ will combine players statistics for all of the stacks in top 50. This also overrides "Show long stats" setting.'); const loadDLCImagesOnTheFrontpage = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Load correct images for "New DLC" on the frontpage', settingsStorage.get('loadDLCImagesOnTheFrontpage')); const resizePS5Icons = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Resize PS5 icons', settingsStorage.get('resizePS5Icons'), 'This feature will resize PS5 icons to standard size. Available on the frontpage and in profiles.'); const useNewTrophyIcons = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Use new trophy icons', settingsStorage.get('useNewTrophyIcons'), 'PSNP+ will replace old trophy icons with new trophy icons that arrived with PS5 generation.'); const hideFloatingMenus = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Hide floating menus', settingsStorage.get('hideFloatingMenus'), 'Floating menus (top-left corner) will be hidden. Any functionality inside these menus will not be available.'); const use24HourTimeFormat = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Use 24-hour time format', settingsStorage.get('use24HourTimeFormat')); const guideLazyLoadMedia = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Lazy load images and videos inside guides', settingsStorage.get('guideLazyLoadMedia'), 'Reduces loading times in guides by downloading images and videos only once they are visible on the screen. Also fixes embedded YouTube videos.'); const enableScriptLogger = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Enable script logger', settingsStorage.get('enableScriptLogger'), 'PSNP+ will log extra debugging information to browser console.'); const hideRank = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Hide rank', settingsStorage.get('hideRank'), 'This feature will automatically hide rank in all profiles.'); const profileShowAddToListButton = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Show "Add to list" button', settingsStorage.get('profileShowAddToListButton'), '"Add to list" button will be available for every game in the profile'); const automaticallyRedirectAfterUpdatingProfile = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Automatically redirect after updating profile', settingsStorage.get('automaticallyRedirectAfterUpdatingProfile')); const profileShowOnlyUniqueGamesInRarestTrophies = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Show unique games in "Rarest Trophies" widget', settingsStorage.get('profileShowOnlyUniqueGamesInRarestTrophies')); const profileDisableScraping = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Disable scraping of game progress in your profile', settingsStorage.get('profileDisableScraping'), 'This is mostly useful for people with super large profiles where the script may crash due to storage issues. WARNING: Certain features will not work. You will not see your progress in lists or sessions.'); const profileUseCoffeeBadge = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Donator badge - replace 🍺 with ☕', settingsStorage.get('profileUseCoffeeBadge')); const pricingPlatPricesIntegration = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Enable PlatPrices.com integration', settingsStorage.get('platPricesIntegration'), 'PSNP+ will automatically fetch pricing information from PlatPrices.com and will display this information inside trophy lists.'); const pricingPlatPricesApiKey = new _ui_panel_PanelInput__WEBPACK_IMPORTED_MODULE_6__.PanelInput('API key', settingsStorage.get('platPricesApiKey'), 'Your API key can be found in Settings over at PlatPrices.com.', (key) => { if (!pricingPlatPricesIntegration.serialize()) { return true; } return key !== '' && /\d+x[a-f0-9]{32}/.test(key); }); const pricingPlatPricesRegion = new _ui_panel_PanelSelect__WEBPACK_IMPORTED_MODULE_9__.PanelSelect('Region', settingsStorage.get('platPricesRegion'), _plat_prices_PlatPricesAPI__WEBPACK_IMPORTED_MODULE_10__.PLAT_PRICES_REGIONS); const trophyListHideTrophyGuideBanner = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Hide trophy guide banner', settingsStorage.get('trophyListHideTrophyGuideBanner')); const guideAutomaticallyHideEarnedTrophies = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Automatically hide earned trophies in guides', settingsStorage.get('guideAutomaticallyHideEarnedTrophies')); const guideScrapeComplexity = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Show info about game complexity in profiles and game lists', settingsStorage.get('guideScrapeComplexity')); const gamingSessionsShowAllByDefault = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Show all gaming sessions by default', settingsStorage.get('gamingSessionsShowAllByDefault')); const gamingSessionsScraping = new _ui_panel_PanelCheckbox__WEBPACK_IMPORTED_MODULE_7__.PanelCheckbox('Show info about active sessions in profiles and game lists', settingsStorage.get('gamingSessionsScraping'), 'PSNP+ will automatically scrape gaming sessions (at most once an hour) and will show this information on other PSNProfiles pages.'); const gameLeaderboardHighlightedCountries = new _ui_panel_PanelInput__WEBPACK_IMPORTED_MODULE_6__.PanelInput('Highlighted countries', settingsStorage.get('gameLeaderboardHighlightedCountries').join(', '), 'List of countries separated by ",". Country needs to match exact country name used by PSNProfiles.'); this.addContent(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .setAttribute('id', 'inner') .addClass('inner') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('center') .setAttribute('style', 'margin-bottom: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('img').setAttribute('src', GM_info.script.icon) .setAttribute('width', '16px') .setAttribute('height', '16px') .setAttribute('style', 'vertical-align: text-top;'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText('PSNP+'), ` v${GM_info.script.version} by `, _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', _util_constants__WEBPACK_IMPORTED_MODULE_14__.LINK_AUTHOR_PSNP_PROFILE) .setText(_util_constants__WEBPACK_IMPORTED_MODULE_14__.AUTHOR_PSN_ID), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .setAttribute('style', 'margin: 10px 0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('small') .setAttribute('style', 'padding: 3px; background-color: #E2AA51; border: 1px solid #a77b34; border-radius: 2px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', 'https://www.buymeacoffee.com/HusKyCode') .setAttribute('target', '_blank') .setAttribute('style', 'color: white;') .append('If you find PSNP+ useful, please consider supporting this project and buying me a beer 🍺. Thanks!'))), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', _util_constants__WEBPACK_IMPORTED_MODULE_14__.LINK_WEBSITE) .setAttribute('target', '_blank') .setText('Website'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText(' • '), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Changelog') .click(e => { e.preventDefault(); this.remove(); (0,_ui_ui_utils__WEBPACK_IMPORTED_MODULE_15__.appendPanel)(new _update_UpdatePanel__WEBPACK_IMPORTED_MODULE_18__.UpdatePanel()); }), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText(' • '), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', _util_constants__WEBPACK_IMPORTED_MODULE_14__.LINK_MAIN_THREAD) .setAttribute('target', '_blank') .setText('Forum'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText(' • '), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', _util_constants__WEBPACK_IMPORTED_MODULE_14__.LINK_UNOBTAINABLE_TROPHIES_THREAD) .setAttribute('target', '_blank') .setText('Report Unobtainable Trophies')), new _ui_panel_PanelSection__WEBPACK_IMPORTED_MODULE_5__.PanelSection('General Settings', markUnobtainableTrophies, hideStacksOnTheFrontpage, mergePopularGamesOnTheFrontpage, loadDLCImagesOnTheFrontpage, resizePS5Icons, useNewTrophyIcons, hideFloatingMenus, use24HourTimeFormat, enableScriptLogger), new _ui_panel_PanelSection__WEBPACK_IMPORTED_MODULE_5__.PanelSection('Profile', hideRank, profileShowAddToListButton, automaticallyRedirectAfterUpdatingProfile, profileShowOnlyUniqueGamesInRarestTrophies, profileDisableScraping, profileUseCoffeeBadge), new _ui_panel_PanelSection__WEBPACK_IMPORTED_MODULE_5__.PanelSection('Pricing', pricingPlatPricesIntegration, pricingPlatPricesApiKey, pricingPlatPricesRegion), new _ui_panel_PanelSection__WEBPACK_IMPORTED_MODULE_5__.PanelSection('Trophy List', trophyListHideTrophyGuideBanner), new _ui_panel_PanelSection__WEBPACK_IMPORTED_MODULE_5__.PanelSection('Guide', guideLazyLoadMedia, guideAutomaticallyHideEarnedTrophies, guideScrapeComplexity), new _ui_panel_PanelSection__WEBPACK_IMPORTED_MODULE_5__.PanelSection('Gaming Sessions', gamingSessionsShowAllByDefault, gamingSessionsScraping), new _ui_panel_PanelSection__WEBPACK_IMPORTED_MODULE_5__.PanelSection('Game Leaderboard', gameLeaderboardHighlightedCountries), new _ui_panel_PanelSection__WEBPACK_IMPORTED_MODULE_5__.PanelSection('Data', new SettingsDataButtons(() => this.remove()))), new _ui_panel_PanelBottom__WEBPACK_IMPORTED_MODULE_8__.PanelBottom('Save & Reload', () => { const formInvalid = [ pricingPlatPricesApiKey.validate() ].some(result => result === false); if (formInvalid) { return; } const newSettings = { enableScriptLogger: enableScriptLogger.serialize(), markUnobtainableTrophies: markUnobtainableTrophies.serialize(), hideStacksOnTheFrontpage: hideStacksOnTheFrontpage.serialize(), mergePopularGamesOnTheFrontpage: mergePopularGamesOnTheFrontpage.serialize(), loadDLCImagesOnTheFrontpage: loadDLCImagesOnTheFrontpage.serialize(), resizePS5Icons: resizePS5Icons.serialize(), useNewTrophyIcons: useNewTrophyIcons.serialize(), hideFloatingMenus: hideFloatingMenus.serialize(), use24HourTimeFormat: use24HourTimeFormat.serialize(), hideRank: hideRank.serialize(), profileShowAddToListButton: profileShowAddToListButton.serialize(), automaticallyRedirectAfterUpdatingProfile: automaticallyRedirectAfterUpdatingProfile.serialize(), profileShowOnlyUniqueGamesInRarestTrophies: profileShowOnlyUniqueGamesInRarestTrophies.serialize(), profileDisableScraping: profileDisableScraping.serialize(), profileUseCoffeeBadge: profileUseCoffeeBadge.serialize(), platPricesIntegration: pricingPlatPricesIntegration.serialize(), platPricesApiKey: pricingPlatPricesApiKey.serialize(), platPricesRegion: pricingPlatPricesRegion.serialize(), trophyListHideTrophyGuideBanner: trophyListHideTrophyGuideBanner.serialize(), guideLazyLoadMedia: guideLazyLoadMedia.serialize(), guideAutomaticallyHideEarnedTrophies: guideAutomaticallyHideEarnedTrophies.serialize(), guideScrapeComplexity: guideScrapeComplexity.serialize(), gameLeaderboardHighlightedCountries: gameLeaderboardHighlightedCountries.commaSeparatedList(), gamingSessionsShowAllByDefault: gamingSessionsShowAllByDefault.serialize(), gamingSessionsScraping: gamingSessionsScraping.serialize() }; settingsStorage.save(newSettings); if (!newSettings.platPricesIntegration) { new _plat_prices_PlatPricesStorage__WEBPACK_IMPORTED_MODULE_11__.PlatPricesStorage().clear(); } if (!newSettings.guideScrapeComplexity) { new _guide_GuideStorage__WEBPACK_IMPORTED_MODULE_13__.GuideStorage().clear(); } if (!newSettings.gamingSessionsScraping) { new _sessions_SessionStorage__WEBPACK_IMPORTED_MODULE_4__.SessionStorage().clear(); } if (!newSettings.markUnobtainableTrophies) { new _unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_12__.UnobtainableTrophiesStorage().clear(); } if (newSettings.profileDisableScraping) { new _game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_17__.GameProgressStorage().clear(); } this.remove(); location.reload(); }, 'Close', () => this.remove())); } } /***/ }), /* 5 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "SettingsStorage": () => (/* binding */ SettingsStorage) /* harmony export */ }); /* harmony import */ var _ISettings__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6); class SettingsStorage /* implements IExportableStorage */ { constructor() { this._storageKey = 'psnpp-settings'; } _load() { try { const settingsString = localStorage.getItem(this._storageKey); if (settingsString == null) { return _ISettings__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SETTINGS; } return Object.assign({}, _ISettings__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SETTINGS, JSON.parse(settingsString)); } catch (e) { console.error('Failed to load settings', e); return _ISettings__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SETTINGS; } } save(settings) { localStorage.setItem(this._storageKey, JSON.stringify(settings)); } get(key) { const settings = this._load(); return settings[key]; } set(key, value) { const settings = this._load(); settings[key] = value; this.save(settings); } disablePlatPricesIntegration() { const settings = this._load(); settings.platPricesIntegration = false; this.save(settings); } export() { return this._load(); } import(settings) { this.save(settings); } clear() { localStorage.removeItem(this._storageKey); } } /***/ }), /* 6 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "DEFAULT_SETTINGS": () => (/* binding */ DEFAULT_SETTINGS) /* harmony export */ }); const DEFAULT_SETTINGS = { enableScriptLogger: false, markUnobtainableTrophies: true, hideStacksOnTheFrontpage: true, mergePopularGamesOnTheFrontpage: true, loadDLCImagesOnTheFrontpage: true, resizePS5Icons: false, useNewTrophyIcons: false, hideFloatingMenus: false, use24HourTimeFormat: false, hideRank: false, profileShowAddToListButton: false, automaticallyRedirectAfterUpdatingProfile: false, profileShowOnlyUniqueGamesInRarestTrophies: false, profileDisableScraping: false, profileUseCoffeeBadge: false, platPricesIntegration: false, platPricesApiKey: '', platPricesRegion: 'US', guideLazyLoadMedia: true, guideAutomaticallyHideEarnedTrophies: false, guideScrapeComplexity: true, gameLeaderboardHighlightedCountries: [], gamingSessionsShowAllByDefault: false, gamingSessionsScraping: true, trophyListHideTrophyGuideBanner: false }; /***/ }), /* 7 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "clearData": () => (/* binding */ clearData), /* harmony export */ "downloadBlob": () => (/* binding */ downloadBlob), /* harmony export */ "downloadFile": () => (/* binding */ downloadFile), /* harmony export */ "exportData": () => (/* binding */ exportData), /* harmony export */ "importData": () => (/* binding */ importData), /* harmony export */ "importList": () => (/* binding */ importList) /* harmony export */ }); /* harmony import */ var _J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5); /* harmony import */ var _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8); /* harmony import */ var _features_sessions_SessionStorage__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(17); /* harmony import */ var _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20); /* harmony import */ var _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(21); /* harmony import */ var _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(24); /* harmony import */ var _features_compare_plus_ComparePlusStorage__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(27); /* harmony import */ var _features_guide_GuideStorage__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(29); /* harmony import */ var _features_plat_prices_PlatPricesStorage__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(30); async function getData() { return { version: 10, settings: new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_1__.SettingsStorage().export(), lists: new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_2__.ListStorage().export(), comparePlus: await (new _features_compare_plus_ComparePlusStorage__WEBPACK_IMPORTED_MODULE_7__.ComparePlusStorage()).export(), guides: new _features_guide_GuideStorage__WEBPACK_IMPORTED_MODULE_8__.GuideStorage().export() }; } function saveData(data) { switch (data.version) { case 1: case 2: case 3: case 4: case 5: new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_1__.SettingsStorage().import(data.settings); break; case 6: case 7: case 8: new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_1__.SettingsStorage().import(data.settings); new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_2__.ListStorage().import(data.lists); break; case 9: new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_1__.SettingsStorage().import(data.settings); new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_2__.ListStorage().import(data.lists); new _features_compare_plus_ComparePlusStorage__WEBPACK_IMPORTED_MODULE_7__.ComparePlusStorage().import(data.comparePlus); break; case 10: new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_1__.SettingsStorage().import(data.settings); new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_2__.ListStorage().import(data.lists); new _features_compare_plus_ComparePlusStorage__WEBPACK_IMPORTED_MODULE_7__.ComparePlusStorage().import(data.comparePlus); new _features_guide_GuideStorage__WEBPACK_IMPORTED_MODULE_8__.GuideStorage().import(data.guides); break; default: console.error('Skipping import for unknown version of backup:', data.version); break; } } function downloadBlob(dataBlob, fileName) { const a = _J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('style', 'display: none;') .setAttribute('href', dataBlob) .setAttribute('download', fileName); _J__WEBPACK_IMPORTED_MODULE_0__.J.q('body').append(a); a.triggerClick(); a.remove(); } function downloadFile(data, fileName, type) { const dataBlob = window.URL.createObjectURL(new Blob([data], { type })); downloadBlob(dataBlob, fileName); URL.revokeObjectURL(dataBlob); } async function readTextFile(file) { return new Promise((resolve, reject) => { const fileReader = new FileReader(); fileReader.onerror = (e) => { console.error('Failed reading file', e); fileReader.abort(); reject(new Error('File read failed')); }; fileReader.onload = () => { if (fileReader.result == null) { return resolve(''); } return resolve(fileReader.result); }; fileReader.readAsText(file); }); } async function exportData() { const data = await getData(); downloadFile(JSON.stringify(data, null, 2), 'psnpp-export.json', 'application/json'); } async function importData(file) { try { const textData = await readTextFile(file); const parsedData = JSON.parse(textData); saveData(parsedData); } catch (e) { console.error('Failed to import data', e); } } async function importList(file) { const textData = await readTextFile(file); const parsedData = JSON.parse(textData); return (new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_2__.ListStorage().createList(parsedData)); } function clearData() { new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_2__.ListStorage().clear(); new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_1__.SettingsStorage().clear(); new _features_sessions_SessionStorage__WEBPACK_IMPORTED_MODULE_3__.SessionStorage().clear(); new _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_4__.GameProgressStorage().clear(); new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_5__.ScriptStateStorage().clear(); new _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_6__.UnobtainableTrophiesStorage().clear(); new _features_compare_plus_ComparePlusStorage__WEBPACK_IMPORTED_MODULE_7__.ComparePlusStorage().clear(); new _features_guide_GuideStorage__WEBPACK_IMPORTED_MODULE_8__.GuideStorage().clear(); new _features_plat_prices_PlatPricesStorage__WEBPACK_IMPORTED_MODULE_9__.PlatPricesStorage().clear(); } /***/ }), /* 8 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ListStorage": () => (/* binding */ ListStorage) /* harmony export */ }); /* harmony import */ var _util_uuidv4__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9); /* harmony import */ var _list_tags__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10); /* harmony import */ var _ListScraper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11); /* harmony import */ var _util_promise__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(15); /* harmony import */ var _util_transform__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(16); const ONE_DAY = 24 * 60 * 60 * 1000; class ListStorage /* implements IExportableStorage */ { constructor() { this._storageKey = 'psnpp-lists'; } get() { try { const listsData = localStorage.getItem(this._storageKey); if (listsData == null) { return []; } return JSON.parse(listsData); } catch (e) { console.error('Failed to load lists', e); return []; } } _save(lists) { localStorage.setItem(this._storageKey, JSON.stringify(lists)); } createList(list) { const listToSave = { ...list, id: (0,_util_uuidv4__WEBPACK_IMPORTED_MODULE_0__.uuidv4)() }; const currentLists = this.get(); currentLists.push(listToSave); this._save(currentLists); return listToSave.id; } updateList(listId, newList) { const allLists = this.get(); const listIndex = allLists.findIndex(list => list.id === listId); if (listIndex === -1) { throw new Error('Invalid list ID'); } allLists[listIndex].name = newList.name; allLists[listIndex].tags = newList.tags; allLists[listIndex].removeStartedGames = newList.removeStartedGames; allLists[listIndex].removeGames = newList.removeGames; allLists[listIndex].orderBy = newList.orderBy; allLists[listIndex].direction = newList.direction; allLists[listIndex].note = newList.note; allLists[listIndex].url = newList.url; this._save(allLists); } getById(listId) { const allLists = this.get(); const list = allLists.find(list => list.id === listId); if (list == null) { throw new Error('Invalid list ID'); } return list; } getUniqueGamesForRefresh() { const allNonRemoteLists = this .get() .filter(list => list.url == null || list.url === ''); const allGames = []; allNonRemoteLists.forEach(list => { list.games.forEach(game => allGames.push(game)); }); return (0,_util_transform__WEBPACK_IMPORTED_MODULE_4__.unique)(allGames, (item, currentItem) => item.id === currentItem.id); } addGameToList(listId, item, setTimestamp = false) { if (setTimestamp) { item.timestamp = Date.now(); } const allLists = this.get(); const listIndex = allLists.findIndex(list => list.id === listId); if (listIndex === -1) { return false; } const gameIndex = allLists[listIndex].games.findIndex(game => game.id === item.id); if (gameIndex > -1) { allLists[listIndex].games[gameIndex] = item; } else { const tags = (0,_list_tags__WEBPACK_IMPORTED_MODULE_1__.getDefaultTags)(allLists[listIndex].tags); item.tags = item.tags != null ? (0,_util_transform__WEBPACK_IMPORTED_MODULE_4__.unique)([...item.tags, ...tags]) : tags; allLists[listIndex].games.push(item); } this._save(allLists); return true; } addTagsToList(listId, tags) { const list = this.getById(listId); const newTags = (0,_util_transform__WEBPACK_IMPORTED_MODULE_4__.unique)([...list.tags, ...tags]); this.updateList(listId, { timestamp: list.timestamp, name: list.name, tags: newTags, removeStartedGames: list.removeStartedGames, removeGames: list.removeGames, orderBy: list.orderBy, direction: list.direction, note: list.note, games: list.games }); } remove(listId) { const allLists = this.get(); const index = allLists.findIndex((x) => x.id === listId); if (index === -1) { return false; } allLists.splice(index, 1); this._save(allLists); return true; } moveCopyGame(fromListId, toListId, item, deleteOriginal) { const targetList = this.getById(toListId); const gameIndex = targetList.games.findIndex(game => game.id === item.id); if (gameIndex > -1) { return false; } if (item.tags != null) { this.addTagsToList(toListId, item.tags); } this.addGameToList(toListId, item); if (deleteOriginal) { this.removeGame(fromListId, item.id); } return true; } removeGame(listId, gameId) { const allLists = this.get(); const listIndex = allLists.findIndex((x) => x.id === listId); if (listIndex === -1) { return false; } const gameIndex = allLists[listIndex].games.findIndex(game => game.id === gameId); if (gameIndex === -1) { return false; } allLists[listIndex].games.splice(gameIndex, 1); this._save(allLists); return true; } sortGame(listId, oldIndex, newIndex) { const allLists = this.get(); const listIndex = allLists.findIndex((x) => x.id === listId); if (listIndex === -1) { return false; } allLists[listIndex].games.reverse(); (0,_util_transform__WEBPACK_IMPORTED_MODULE_4__.move)(allLists[listIndex].games, oldIndex, newIndex); allLists[listIndex].games.reverse(); this._save(allLists); return true; } moveToIndex(listId, gameId, targetIndex) { const allLists = this.get(); const listIndex = allLists.findIndex((x) => x.id === listId); if (listIndex === -1) { return false; } const gameIndex = allLists[listIndex].games.findIndex(game => game.id === gameId); if (gameIndex === -1) { return false; } (0,_util_transform__WEBPACK_IMPORTED_MODULE_4__.move)(allLists[listIndex].games, gameIndex, targetIndex); this._save(allLists); return true; } removeGameFromAllListsWithAutoRemoval(game) { const allLists = this.get(); const listsWithAutoRemoval = allLists.filter(list => (list.removeGames != null && list.removeGames != 'never') || list.removeStartedGames); const removeResults = listsWithAutoRemoval.map(list => { if (list.removeGames === 'started' || list.removeStartedGames) { return this.removeGame(list.id, game.id); } if (list.removeGames === 'completed' && game.progress === 100) { return this.removeGame(list.id, game.id); } if (list.removeGames === 'platinum' && (game.progress === 100 || (game.trophies != null && game.trophies.platinum > 0))) { return this.removeGame(list.id, game.id); } return false; }); return removeResults.some(result => result === true); } clearTags(listId, tags) { const allLists = this.get(); const listIndex = allLists.findIndex((x) => x.id === listId); if (listIndex === -1) { throw new Error('Invalid list ID'); } allLists[listIndex].games.forEach(item => { tags.forEach(t => { if (typeof item.tags === 'undefined') { return; } const tagIndex = item.tags.findIndex(itemTag => itemTag === t); if (tagIndex === -1) { return; } item.tags.splice(tagIndex, 1); }); }); this._save(allLists); } hasInList(listId, id) { const allLists = this.get(); const listIndex = allLists.findIndex((x) => x.id === listId); if (listIndex === -1) { throw new Error('Invalid list ID'); } const index = allLists[listIndex].games.findIndex((x) => x.id === id); return index > -1; } has(id) { const allLists = this.get(); return allLists.some(list => list.id === id); } clear() { localStorage.removeItem(this._storageKey); } export() { return this.get(); } import(lists) { this._save(lists); } refreshGame(newScrape) { let refreshed = false; const allLists = this.get(); allLists.forEach(list => { const gameIndex = list.games.findIndex(game => game.id === newScrape.id); if (gameIndex > -1) { newScrape.timestamp = list.games[gameIndex].timestamp; newScrape.psplus = list.games[gameIndex].psplus; newScrape.tags = list.games[gameIndex].tags; newScrape.note = list.games[gameIndex].note; this.addGameToList(list.id, newScrape); refreshed = true; } }); return refreshed; } async refresh(onUpdate) { const uniqueGames = this.getUniqueGamesForRefresh(); for (let i = 0; i < uniqueGames.length; i++) { const item = uniqueGames[i]; if (typeof item.scrapetime !== 'undefined') { if (Date.now() - item.scrapetime < ONE_DAY) { onUpdate('success', i); continue; } } try { const newScrape = await _ListScraper__WEBPACK_IMPORTED_MODULE_2__.ListScraper.getFromUrl(item.url); this.refreshGame(newScrape); if (i < uniqueGames.length - 1) { await (0,_util_promise__WEBPACK_IMPORTED_MODULE_3__.sleep)(5000); } onUpdate('success', i); } catch (e) { console.warn(`Failed to fetch item: ${item.title}. Keeping old data. Error:`, e); // NOTE: For now we don't process/display fetch errors. onUpdate('success', i); } } onUpdate('done', null); } } /***/ }), /* 9 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "uuidv4": () => (/* binding */ uuidv4) /* harmony export */ }); // NOTE: This isn't cryptographically secure but it works // for our purposes. // https://stackoverflow.com/a/2117523/7494817 function uuidv4() { const uuidv4Base = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'; return uuidv4Base.replace(/[xy]/g, (char) => { const random = Math.random() * 16 | 0; const value = char == 'x' ? random : (random & 0x3 | 0x8); return value.toString(16); }); } /***/ }), /* 10 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "getDefaultTags": () => (/* binding */ getDefaultTags) /* harmony export */ }); function getTagPrefix(tag) { const match = tag.match(/^([@]{1})/); if (match == null) { return ''; } return match[0]; } function isDefaultTag(tag) { const prefix = getTagPrefix(tag); return prefix.indexOf('@') > -1; } function getDefaultTags(tags) { return tags.filter(tag => isDefaultTag(tag)); } /***/ }), /* 11 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ListScraper": () => (/* binding */ ListScraper) /* harmony export */ }); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13); /* harmony import */ var _regions__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(14); class ListScraper { constructor(doc) { this._doc = doc; } _q(query, options = {}) { return _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q(query, options, this._doc); } _getSidebarInfobox() { return this._q('div#content > div.row > div.col-xs-4 > div.box.no-top-border'); } _getTrophyCountBox() { return this._getSidebarInfobox().find('div.trophy-count'); } _getPlatformsBox() { return this._getSidebarInfobox().find('div.platforms'); } _getTotalPointCount() { const numberText = this._getTrophyCountBox().find('span.small-info.floatr').find('b', { eq: 1 }).getText().replace(/[^\d]*/g, ''); return parseInt(numberText, 10); } getFromTrophiesPage() { const title = this._q('meta[name="Description"]').getAttribute('content').split(' • ')[0].replace(' Trophy List', ''); const image = this._q('meta[property="og:image"]').getAttribute('content'); const url = this._q('meta[property="og:url"]').getAttribute('content'); const points = this._getTotalPointCount(); const id = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getFirstLevelIdFromUrl)(url); const isPS5 = this._getPlatformsBox().find('span.tag.platform.ps5').exists(); const isPS4 = this._getPlatformsBox().find('span.tag.platform.ps4').exists(); const isPS3 = this._getPlatformsBox().find('span.tag.platform.ps3').exists(); const isPSVITA = this._getPlatformsBox().find('span.tag.platform.psvita').exists(); const isPSVR = this._getPlatformsBox().find('span.tag.platform.psvr').exists(); const platinum = parseInt(this._getTrophyCountBox().find('li.icon-sprite.platinum').getText(), 10); const gold = parseInt(this._getTrophyCountBox().find('li.icon-sprite.gold').getText(), 10); const silver = parseInt(this._getTrophyCountBox().find('li.icon-sprite.silver').getText(), 10); const bronze = parseInt(this._getTrophyCountBox().find('li.icon-sprite.bronze').getText(), 10); const regionTh = this._getSidebarInfobox().find('th.center'); const regionLongDescription = regionTh.exists() ? regionTh.getText() : undefined; const region = typeof regionLongDescription !== 'undefined' ? (0,_regions__WEBPACK_IMPORTED_MODULE_3__.getCodeFromDescription)(regionLongDescription) : undefined; const guideLink = this._q('div.banner-overlay a', { containsText: 'Guide' }); const guideurl = guideLink.exists() ? (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getWebsiteUrl)() + guideLink.getAttribute('href') : undefined; const dlccount = (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('[id^="DLC-"]', {}, this._doc).length; const platinumpctMatch = this._q('span', { containsText: 'Platinum Achiever' }).getText().match(/\(([\d.]{1,6})%\)/); const platinumpct = platinumpctMatch != null ? parseFloat(platinumpctMatch[1]) : undefined; const completepctMatch = this._q('span', { containsText: '100% Completed' }).getText().match(/\(([\d.]{1,6})%\)/); const completepct = completepctMatch != null ? parseFloat(completepctMatch[1]) : undefined; const timestamp = Date.now(); return { id, scrapetime: timestamp, title, image, url, points, platforms: { ps5: isPS5, ps4: isPS4, ps3: isPS3, psvita: isPSVITA, psvr: isPSVR }, trophies: { platinum, gold, silver, bronze }, region, guideurl, dlccount, platinumpct, completepct, timestamp, psplus: false, tags: [], note: '' }; } static async getFromUrl(url) { const doc = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_2__.fetchDocument)(url); return new ListScraper(doc).getFromTrophiesPage(); } } /***/ }), /* 12 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "getCdnCodeFromImageUrl": () => (/* binding */ getCdnCodeFromImageUrl), /* harmony export */ "getFirstLevelIdFromPathname": () => (/* binding */ getFirstLevelIdFromPathname), /* harmony export */ "getFirstLevelIdFromUrl": () => (/* binding */ getFirstLevelIdFromUrl), /* harmony export */ "getPathSegments": () => (/* binding */ getPathSegments), /* harmony export */ "getPathSegmentsFromPathname": () => (/* binding */ getPathSegmentsFromPathname), /* harmony export */ "getSearchParams": () => (/* binding */ getSearchParams), /* harmony export */ "getSearchParamsFromHash": () => (/* binding */ getSearchParamsFromHash), /* harmony export */ "getSecondLevelIdFromPathname": () => (/* binding */ getSecondLevelIdFromPathname), /* harmony export */ "getUrl": () => (/* binding */ getUrl), /* harmony export */ "getUrlObject": () => (/* binding */ getUrlObject), /* harmony export */ "getWebsiteUrl": () => (/* binding */ getWebsiteUrl), /* harmony export */ "redirect": () => (/* binding */ redirect), /* harmony export */ "validateUrl": () => (/* binding */ validateUrl) /* harmony export */ }); function getUrlObject() { return new URL(window.location.href); } function getWebsiteUrl() { const url = getUrlObject(); return url.protocol + '//' + url.host; } function getUrl() { return window.location.href; } function getPathSegmentsFromPathname(pathname) { return pathname .split('/') .filter((segment) => segment !== ''); } function getPathSegments() { return getPathSegmentsFromPathname(window.location.pathname); } function getSearchParams() { const url = getUrlObject(); return url.searchParams; } function getSearchParamsFromHash() { const url = getUrlObject(); const fakeUrl = new URL('/' + url.hash.replace(/^#/, ''), 'https://psnprofiles.com'); return fakeUrl.searchParams; } function getCdnCodeFromImageUrl(imageUrl) { return (new URL(imageUrl)).pathname.split('/')[2]; } function getFirstLevelIdFromPathname(pathname) { return pathname.split('/')[2].split('-')[0]; } function getFirstLevelIdFromUrl(url) { return getFirstLevelIdFromPathname((new URL(url)).pathname); } function getSecondLevelIdFromPathname(pathname) { return pathname.split('/')[3].split('-')[0]; } function redirect(path) { location.href = path; } function validateUrl(url) { try { new URL(url); return true; } catch (_a) { return false; } } /***/ }), /* 13 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "fetchDocument": () => (/* binding */ fetchDocument), /* harmony export */ "fetchJson": () => (/* binding */ fetchJson), /* harmony export */ "fetchText": () => (/* binding */ fetchText), /* harmony export */ "gmFetchJson": () => (/* binding */ gmFetchJson), /* harmony export */ "gmFetchSafe": () => (/* binding */ gmFetchSafe), /* harmony export */ "loadCssSheet": () => (/* binding */ loadCssSheet), /* harmony export */ "loadScriptTag": () => (/* binding */ loadScriptTag) /* harmony export */ }); /* harmony import */ var _J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); async function fetchSafe(url) { const res = await fetch(url); if (res.status !== 200) { throw new Error(`Invalid response status code ${res.status}`); } return res; } async function fetchText(url) { const res = await fetchSafe(url); return res.text(); } async function fetchJson(url) { const res = await fetchSafe(url); return res.json(); } async function fetchDocument(url) { const htmlString = await fetchText(url); return new DOMParser().parseFromString(htmlString, 'text/html'); } async function gmFetchSafe(url) { if (typeof GM_xmlhttpRequest === 'undefined') { throw new Error('This feature is not available in your web browser.'); } return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: 'GET', url, onload: (res) => { if (res.status !== 200) { reject(new Error(`Invalid response status code ${res.status}`)); } else { resolve(res); } }, onerror: (e) => reject(e) }); }); } async function gmFetchJson(url) { const res = await gmFetchSafe(url); return JSON.parse(res.responseText); } const loadedResourcesMap = new Set(); function loadScriptTag(src) { if (loadedResourcesMap.has(src)) { return Promise.resolve(); } return new Promise((resolve, reject) => { _J__WEBPACK_IMPORTED_MODULE_0__.J.q('head') .append(_J__WEBPACK_IMPORTED_MODULE_0__.J.c('script') .setAttribute('type', 'text/javascript') .setAttribute('src', src) .load(() => { loadedResourcesMap.add(src); resolve(); }) .error((e) => reject(e))); }); } function loadCssSheet(src) { if (loadedResourcesMap.has(src)) { return Promise.resolve(); } return new Promise((resolve, reject) => { _J__WEBPACK_IMPORTED_MODULE_0__.J.q('head') .append(_J__WEBPACK_IMPORTED_MODULE_0__.J.c('link') .setAttribute('type', 'text/css') .setAttribute('rel', 'stylesheet') .setAttribute('href', src) .load(() => { loadedResourcesMap.add(src); resolve(); }) .error((e) => reject(e))); }); } /***/ }), /* 14 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "getCodeFromDescription": () => (/* binding */ getCodeFromDescription), /* harmony export */ "getDescritionFromCode": () => (/* binding */ getDescritionFromCode) /* harmony export */ }); const REGION_MAP = { 'European List': 'EU', 'Japanese List': 'JP', 'North American List': 'NA', 'United Kingdom List': 'UK', 'Asian List': 'AS', 'Australian List': 'AU', 'Brazilian List': 'BR', 'Chinese List': 'CN', 'French List': 'FR', 'German List': 'GER', 'Hong Kong List': 'HK', 'Korean List': 'KR', 'Russian List': 'RU', 'Saudi Arabian List': 'SA', 'Spanish List': 'ES', 'Taiwanese List': 'TW', 'Western List': 'WE', 'Digital Edition List': 'DG', 'Physical/Disc List': 'PH', 'Original List': 'OR', 'Rereleased List': 'RR', 'Pre-Order Bonus List': 'PO', 'Bonus/Bundle List': 'BO' }; function getCodeFromDescription(description) { return REGION_MAP[description]; } function getDescritionFromCode(code) { const keys = Object.keys(REGION_MAP); for (let i = 0; i < keys.length; i++) { if (REGION_MAP[keys[i]] === code) { return keys[i]; } } } /***/ }), /* 15 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "sleep": () => (/* binding */ sleep) /* harmony export */ }); async function sleep(ms) { return new Promise((resolve) => setTimeout(() => resolve(), ms)); } /***/ }), /* 16 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "cloneDeep": () => (/* binding */ cloneDeep), /* harmony export */ "flatten": () => (/* binding */ flatten), /* harmony export */ "move": () => (/* binding */ move), /* harmony export */ "unique": () => (/* binding */ unique) /* harmony export */ }); function unique(arr, equality = (item, currentItem) => (item === currentItem)) { return arr.reduce((uniqueElements, currentItem) => { if (!uniqueElements.some(item => equality(item, currentItem))) { uniqueElements.push(currentItem); } return uniqueElements; }, []); } function move(arr, fromIndex, toIndex) { const element = arr[fromIndex]; arr.splice(fromIndex, 1); arr.splice(toIndex, 0, element); } function cloneDeep(obj) { return JSON.parse(JSON.stringify(obj)); } // NOTE: Hacky type info but will work for now. function flatten(target) { const output = {}; function step(object, prev = '', currentDepth = 1) { Object.keys(object).forEach(function (key) { const value = object[key]; const isarray = Array.isArray(value); const type = Object.prototype.toString.call(value); const isobject = (type === '[object Object]' || type === '[object Array]'); const newKey = prev.length > 0 ? prev + '.' + key : key; if (!isarray && isobject && Object.keys(value).length > 0) { return step(value, newKey, currentDepth + 1); } output[newKey] = value; }); } step(target); return output; } /***/ }), /* 17 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "SessionStorage": () => (/* binding */ SessionStorage) /* harmony export */ }); /* harmony import */ var _SessionScraper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(18); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(12); const ONE_HOUR = 1 * 60 * 60 * 1000; class SessionStorage { constructor() { this._storageKey = 'psnpp-sessions'; } get() { try { const sessionData = localStorage.getItem(this._storageKey); if (sessionData == null) { return []; } return JSON.parse(sessionData); } catch (e) { console.error('Failed to load sessions', e); return []; } } indexedByCdnCode() { const currentSessions = this.get(); const result = new Map(); currentSessions.forEach(session => { const cdnCode = (0,_util_url__WEBPACK_IMPORTED_MODULE_1__.getCdnCodeFromImageUrl)(session.image); const sessionArray = result.get(cdnCode); if (typeof sessionArray === 'undefined') { result.set(cdnCode, [session]); } else { sessionArray.push(session); } }); return result; } _save(newSessions) { localStorage.setItem(this._storageKey, JSON.stringify(newSessions)); } clear() { localStorage.removeItem(this._storageKey); } async refresh() { const currentSessions = this.get(); if (currentSessions.length > 0 && (currentSessions[0].scrapetime + ONE_HOUR) > Date.now()) { return false; } const newSessions = await _SessionScraper__WEBPACK_IMPORTED_MODULE_0__.SessionScraper.getFromSessionsPageRemotely(); this._save(newSessions); return true; } } /***/ }), /* 18 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "SessionScraper": () => (/* binding */ SessionScraper) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(12); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13); /* harmony import */ var _util_user__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(19); class SessionScraper { constructor(doc) { this._doc = doc; } getFromSessionsPageWithElements() { return (0,_util_J__WEBPACK_IMPORTED_MODULE_0__.all)('table.box.zebra tr', {}, this._doc).map(row => { const title = row.clone().find('a.title').getText(); const image = row.clone().find('img.game').getAttribute('src'); const urlPath = row.clone().find('a.title').getAttribute('href'); const hostElement = row.clone().find('a.small-title'); const host = hostElement.exists() ? hostElement.getText() // NOTE: This is my own session located in "Your Upcoming Sessions" section. : (0,_util_user__WEBPACK_IMPORTED_MODULE_3__.getPsnId)(); const url = (0,_util_url__WEBPACK_IMPORTED_MODULE_1__.getWebsiteUrl)() + urlPath; const id = (0,_util_url__WEBPACK_IMPORTED_MODULE_1__.getFirstLevelIdFromUrl)(url); const isPS5 = row.clone().find('span.tag.platform.ps5').exists(); const isPS4 = row.clone().find('span.tag.platform.ps4').exists(); const isPS3 = row.clone().find('span.tag.platform.ps3').exists(); const isPSVITA = row.clone().find('span.tag.platform.psvita').exists(); const isPSVR = row.clone().find('span.tag.platform.psvr').exists(); return { el: row, session: { id, scrapetime: Date.now(), title, image, url, host, platforms: { ps5: isPS5, ps4: isPS4, ps3: isPS3, psvita: isPSVITA, psvr: isPSVR } } }; }); } getFromSessionsPage() { return this.getFromSessionsPageWithElements().map(x => x.session); } static async getFromSessionsPageRemotely() { const doc = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_2__.fetchDocument)((0,_util_url__WEBPACK_IMPORTED_MODULE_1__.getWebsiteUrl)() + '/sessions?all'); return new SessionScraper(doc).getFromSessionsPage(); } } /***/ }), /* 19 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "getProfileUrl": () => (/* binding */ getProfileUrl), /* harmony export */ "getPsnId": () => (/* binding */ getPsnId), /* harmony export */ "getUpdateProfileRedirectUrl": () => (/* binding */ getUpdateProfileRedirectUrl), /* harmony export */ "isLoggedIn": () => (/* binding */ isLoggedIn) /* harmony export */ }); /* harmony import */ var _J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); function getPsnId() { return _J__WEBPACK_IMPORTED_MODULE_0__.J.q('div.dropdown.user-nav').find('span').getText(); } function getProfileUrl() { return '/' + getPsnId(); } function getUpdateProfileRedirectUrl(psnId, pathname) { return `/?psnId=${psnId}&redirect=${pathname}`; } function isLoggedIn() { return !_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#subnav a.signin.button').exists(); } /***/ }), /* 20 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "GameProgressStorage": () => (/* binding */ GameProgressStorage) /* harmony export */ }); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); class GameProgressStorage { constructor() { this._storageKey = 'psnpp-gameslist'; } get() { try { const data = localStorage.getItem(this._storageKey); if (data == null) { return []; } return JSON.parse(data); } catch (e) { console.error('Failed to load game progress', e); return []; } } has(id) { const currentGames = this.get(); return currentGames.some(game => game.id === id); } indexedById() { const currentGames = this.get(); const result = new Map(); currentGames.forEach(game => { result.set(game.id, game); }); return result; } indexedByCdnCode() { const currentGames = this.get(); const result = new Map(); currentGames.forEach(game => { if (game.image == null) { return; } const cdnCode = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getCdnCodeFromImageUrl)(game.image); result.set(cdnCode, game); }); return result; } addMany(games) { const currentGames = this.get(); games.forEach(game => { const progressExists = currentGames.findIndex((x) => x.id === game.id); if (progressExists > -1) { currentGames[progressExists] = game; } else { currentGames.push(game); } }); this._save(currentGames); } _save(games) { localStorage.setItem(this._storageKey, JSON.stringify(games)); } clear() { localStorage.removeItem(this._storageKey); } } /***/ }), /* 21 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ScriptStateStorage": () => (/* binding */ ScriptStateStorage) /* harmony export */ }); /* harmony import */ var _IScriptState__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(22); /* harmony import */ var _plat_prices_PlatPricesAPI__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(23); class ScriptStateStorage { constructor() { this._storageKey = 'psnpp-scriptstate'; } _load() { try { const state = localStorage.getItem(this._storageKey); if (state == null) { return _IScriptState__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SCRIPT_STATE; } return Object.assign({}, _IScriptState__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SCRIPT_STATE, JSON.parse(state)); } catch (e) { console.error('Failed to load script state', e); return _IScriptState__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_SCRIPT_STATE; } } _save(scriptState) { localStorage.setItem(this._storageKey, JSON.stringify(scriptState)); } get(key) { const state = this._load(); return state[key]; } set(key, value) { const state = this._load(); state[key] = value; this._save(state); } isPlatPricesCooldownActive() { const cooldown = this.get('platPricesCooldownTriggerTime'); if (cooldown == null) { return false; } return cooldown + _plat_prices_PlatPricesAPI__WEBPACK_IMPORTED_MODULE_1__.PLAT_PRICES_COOLDOWN_PERIOD > Date.now(); } clear() { localStorage.removeItem(this._storageKey); } } /***/ }), /* 22 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "DEFAULT_SCRIPT_STATE": () => (/* binding */ DEFAULT_SCRIPT_STATE) /* harmony export */ }); const DEFAULT_SCRIPT_STATE = { version: GM_info.script.version, lastActiveGameList: null, platPricesCooldownTriggerTime: 0, guideSimpleMatching: false, seriesAutoCollapse: false, seriesDoNotCollapseNoStage: false, newListsSignature: '', latestGames: [], popularListsSignature: '', popularGames: [], newDLCSignature: '', dlcImages: [] }; /***/ }), /* 23 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "IPlatPricesError": () => (/* binding */ IPlatPricesError), /* harmony export */ "PLAT_PRICES_COOLDOWN_PERIOD": () => (/* binding */ PLAT_PRICES_COOLDOWN_PERIOD), /* harmony export */ "PLAT_PRICES_REGIONS": () => (/* binding */ PLAT_PRICES_REGIONS), /* harmony export */ "PlatPricesAPIError": () => (/* binding */ PlatPricesAPIError), /* harmony export */ "fetchPrice": () => (/* binding */ fetchPrice) /* harmony export */ }); /* harmony import */ var _settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5); const BASE_API_URL = 'https://platprices.com/psnpplus.php'; const PLAT_PRICES_COOLDOWN_PERIOD = 60 * 60 * 1000; // ONE HOUR var IPlatPricesError; (function (IPlatPricesError) { IPlatPricesError[IPlatPricesError["NETWORK_ERROR"] = -1] = "NETWORK_ERROR"; IPlatPricesError[IPlatPricesError["OK"] = 0] = "OK"; IPlatPricesError[IPlatPricesError["UNAUTHORIZED"] = 1] = "UNAUTHORIZED"; IPlatPricesError[IPlatPricesError["FORBIDDEN"] = 2] = "FORBIDDEN"; IPlatPricesError[IPlatPricesError["NOTFOUND"] = 3] = "NOTFOUND"; // 404, not found })(IPlatPricesError || (IPlatPricesError = {})); const PLAT_PRICES_REGIONS = { AR: 'Argentina', AU: 'Australia', AT: 'Austria', BE: 'Belgium', BR: 'Brazil', BG: 'Bulgaria', CA: 'Canada', CL: 'Chile', HR: 'Croatia', CZ: 'Czechia', DK: 'Denmark', FI: 'Finland', FR: 'France', DE: 'Germany', GR: 'Greece', HK: 'Hong Kong', HU: 'Hungary', IS: 'Iceland', IN: 'India', ID: 'Indonesia', IE: 'Ireland', IL: 'Israel', IT: 'Italy', JP: 'Japan', KR: 'Korea', MY: 'Malaysia', MX: 'Mexico', NL: 'Netherlands', NZ: 'New Zealand', NO: 'Norway', PL: 'Poland', PT: 'Portugal', RO: 'Romania', RU: 'Russia', SA: 'Saudi Arabia', SG: 'Singapore', SK: 'Slovakia', ZA: 'South Africa', ES: 'Spain', SE: 'Sweden', CH: 'Switzerland', TW: 'Taiwan', TH: 'Thailand', TR: 'Turkey', UA: 'Ukraine', AE: 'U. A. Emirates', GB: 'United Kingdom', US: 'United States' }; class PlatPricesAPIError extends Error { constructor(response) { super('PlatPricesAPI Error'); Object.setPrototypeOf(this, PlatPricesAPIError.prototype); this._response = response; } getErrorCode() { return this._response.error; } getNiceErrorMessage() { if (this._response.error == IPlatPricesError.NETWORK_ERROR) { return 'Network error. Please try again later.'; } if (this._response.error === IPlatPricesError.OK) { return 'Invalid error state'; } if (this._response.error === IPlatPricesError.UNAUTHORIZED) { return 'API key is invalid - check your settings'; } if (this._response.error === IPlatPricesError.FORBIDDEN) { return 'Request limit reached - integration disabled for 1 hour'; } if (this._response.error === IPlatPricesError.NOTFOUND) { return 'Not available'; } return 'Invalid error state: ' + this._response.error; } } async function fetchPrice(trophyListIdentifiers) { const urlParamsObject = trophyListIdentifiers.reduce((acc, value, index) => { acc[`url${index + 1}`] = value; return acc; }, {}); const settingsStorage = new _settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_0__.SettingsStorage(); const apiKey = settingsStorage.get('platPricesApiKey'); const region = settingsStorage.get('platPricesRegion'); urlParamsObject['api'] = apiKey; urlParamsObject['reg'] = region; let req; try { req = await fetch(BASE_API_URL + '?' + new URLSearchParams(urlParamsObject)); } catch (e) { console.warn('PlatPricesAPI Fetch failed', e); throw new PlatPricesAPIError({ error: -1 }); } if (req.status >= 400 && req.status < 500) { const res = await req.json(); throw new PlatPricesAPIError(res); } if (req.status !== 200) { throw new PlatPricesAPIError({ error: -1 }); } return req.json(); } /***/ }), /* 24 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "UnobtainableTrophiesStorage": () => (/* binding */ UnobtainableTrophiesStorage) /* harmony export */ }); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(25); /* harmony import */ var _storage_ExpirableStorage__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(26); class UnobtainableTrophiesStorage extends _storage_ExpirableStorage__WEBPACK_IMPORTED_MODULE_1__.ExpirableStorage { constructor() { super({ supportedVersion: 1, remoteUrl: _util_constants__WEBPACK_IMPORTED_MODULE_0__.LINK_UNOBTAINABLE_TROPHIES_MASTER_LIST, storageKey: 'psnpp-unobtainabletrophies', // 4 hours expirationTimeMs: 4 * 60 * 60 * 1000, emptyValue: {} }); } getByTrophyListId(id) { return this.get().data.list[id]; } } /***/ }), /* 25 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "AUTHOR_PSN_ID": () => (/* binding */ AUTHOR_PSN_ID), /* harmony export */ "COLOR_DARK_ORANGE": () => (/* binding */ COLOR_DARK_ORANGE), /* harmony export */ "COLOR_LIGHT_ORANGE": () => (/* binding */ COLOR_LIGHT_ORANGE), /* harmony export */ "COLOR_LIGHT_YELLOW": () => (/* binding */ COLOR_LIGHT_YELLOW), /* harmony export */ "COLOR_PURPLE": () => (/* binding */ COLOR_PURPLE), /* harmony export */ "EXTERNAL_SCRIPT_URLS": () => (/* binding */ EXTERNAL_SCRIPT_URLS), /* harmony export */ "HASH_COMPARE_PLUS": () => (/* binding */ HASH_COMPARE_PLUS), /* harmony export */ "HASH_GAME_LISTS": () => (/* binding */ HASH_GAME_LISTS), /* harmony export */ "HASH_PROFILE": () => (/* binding */ HASH_PROFILE), /* harmony export */ "HASH_UNOBTAINABLES": () => (/* binding */ HASH_UNOBTAINABLES), /* harmony export */ "ICON_SPRITE": () => (/* binding */ ICON_SPRITE), /* harmony export */ "LINK_AUTHOR_PSNP_PROFILE": () => (/* binding */ LINK_AUTHOR_PSNP_PROFILE), /* harmony export */ "LINK_CHANGELOG": () => (/* binding */ LINK_CHANGELOG), /* harmony export */ "LINK_DONATORS": () => (/* binding */ LINK_DONATORS), /* harmony export */ "LINK_MAIN_THREAD": () => (/* binding */ LINK_MAIN_THREAD), /* harmony export */ "LINK_UNOBTAINABLE_TROPHIES_MASTER_LIST": () => (/* binding */ LINK_UNOBTAINABLE_TROPHIES_MASTER_LIST), /* harmony export */ "LINK_UNOBTAINABLE_TROPHIES_MASTER_LIST_FULL": () => (/* binding */ LINK_UNOBTAINABLE_TROPHIES_MASTER_LIST_FULL), /* harmony export */ "LINK_UNOBTAINABLE_TROPHIES_THREAD": () => (/* binding */ LINK_UNOBTAINABLE_TROPHIES_THREAD), /* harmony export */ "LINK_WEBSITE": () => (/* binding */ LINK_WEBSITE), /* harmony export */ "MAGIC_SPACE": () => (/* binding */ MAGIC_SPACE), /* harmony export */ "NEW_TROPHY_ICONS": () => (/* binding */ NEW_TROPHY_ICONS), /* harmony export */ "UNOBTAINABLE_TROPHIES_REPORT_NOTE_MAXLEN": () => (/* binding */ UNOBTAINABLE_TROPHIES_REPORT_NOTE_MAXLEN) /* harmony export */ }); const MAGIC_SPACE = ' '; const UNOBTAINABLE_TROPHIES_REPORT_NOTE_MAXLEN = 280; const COLOR_DARK_ORANGE = '#db8320'; const COLOR_LIGHT_ORANGE = '#fbe2bf'; const COLOR_LIGHT_YELLOW = '#ffffed'; const COLOR_PURPLE = '#5865f2'; const HASH_PROFILE = '#profile'; const HASH_GAME_LISTS = '#gamelists'; const HASH_COMPARE_PLUS = '#compare-plus'; const HASH_UNOBTAINABLES = '#unobtainables'; const EXTERNAL_SCRIPT_URLS = { JQUERY_UI: '/lib/js/jquery-ui.min.js', VANILLA_LAZYLOAD: 'https://cdnjs.cloudflare.com/ajax/libs/vanilla-lazyload/17.8.3/lazyload.min.js', PAPAPARSE: 'https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.2/papaparse.min.js', HTML2CANVAS: 'https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js', DATA_TABLES_JS: 'https://cdn.datatables.net/2.0.3/js/dataTables.min.js', DATA_TABLES_CSS: 'https://cdn.datatables.net/2.0.3/css/dataTables.dataTables.min.css' }; const AUTHOR_PSN_ID = 'HusKyCode'; const LINK_AUTHOR_PSNP_PROFILE = 'https://psnprofiles.com/HusKyCode'; const LINK_WEBSITE = 'https://psnp-plus.huskycode.dev/'; const LINK_CHANGELOG = 'https://psnp-plus.huskycode.dev/changelog.txt'; const LINK_MAIN_THREAD = 'https://forum.psnprofiles.com/topic/78709-psnp-plus'; const LINK_UNOBTAINABLE_TROPHIES_THREAD = 'https://forum.psnprofiles.com/topic/118915-psnp-unobtainable-trophies-master-list/'; const LINK_UNOBTAINABLE_TROPHIES_MASTER_LIST = 'https://psnp-plus.huskycode.dev/list.min.json'; const LINK_UNOBTAINABLE_TROPHIES_MASTER_LIST_FULL = 'https://psnp-plus.huskycode.dev/list.json'; const LINK_DONATORS = 'https://psnp-plus.huskycode.dev/donators.min.json'; const NEW_TROPHY_ICONS = { x40: { platinum: 'https://psnp-plus.huskycode.dev/img/trophy-icons/40/platinum.png', gold: 'https://psnp-plus.huskycode.dev/img/trophy-icons/40/gold.png', silver: 'https://psnp-plus.huskycode.dev/img/trophy-icons/40/silver.png', bronze: 'https://psnp-plus.huskycode.dev/img/trophy-icons/40/bronze.png', hidden: 'https://psnp-plus.huskycode.dev/img/trophy-icons/40/hidden.png', }, x24: { platinum: 'https://psnp-plus.huskycode.dev/img/trophy-icons/24/platinum.png', gold: 'https://psnp-plus.huskycode.dev/img/trophy-icons/24/gold.png', silver: 'https://psnp-plus.huskycode.dev/img/trophy-icons/24/silver.png', bronze: 'https://psnp-plus.huskycode.dev/img/trophy-icons/24/bronze.png', hidden: 'https://psnp-plus.huskycode.dev/img/trophy-icons/24/hidden.png', } }; const ICON_SPRITE = 'https://psnp-plus.huskycode.dev/img/sprites/icon-sprite.png'; /***/ }), /* 26 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ExpirableStorage": () => (/* binding */ ExpirableStorage) /* harmony export */ }); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13); class ExpirableStorage { constructor(config) { this._config = config; } _getEmptyValue() { return { timestamp: 0, data: { version: 1, list: this._config.emptyValue } }; } get() { try { const data = localStorage.getItem(this._config.storageKey); if (data == null) { return this._getEmptyValue(); } return JSON.parse(data); } catch (e) { console.error('Failed to load data', this._config.storageKey, e); return this._getEmptyValue(); } } _save(newList) { const toSave = { timestamp: Date.now(), data: newList }; localStorage.setItem(this._config.storageKey, JSON.stringify(toSave)); } clear() { localStorage.removeItem(this._config.storageKey); } async refresh() { const currentData = this.get(); if (currentData.timestamp + this._config.expirationTimeMs > Date.now()) { return false; } const newList = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_0__.fetchJson)(this._config.remoteUrl); if (newList.version !== this._config.supportedVersion) { return false; } this._save(newList); return true; } } /***/ }), /* 27 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ComparePlusStorage": () => (/* binding */ ComparePlusStorage) /* harmony export */ }); /* harmony import */ var _storage_HybridStorage__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28); class ComparePlusStorage { constructor() { this._storageKey = 'psnpp-compareplus'; this._storage = new _storage_HybridStorage__WEBPACK_IMPORTED_MODULE_0__.HybridStorage(); } async _get() { try { const data = await this._storage.getItem(this._storageKey); if (data == null) { return {}; } return JSON.parse(data); } catch (e) { console.error('Failed to load compare plus data', e); return {}; } } async getByTrophyListId(trophyListId) { const compareObject = await this._get(); const value = compareObject[trophyListId]; return value == null ? '' : value; } async set(trophyListId, comparePlusData) { const compareObject = await this._get(); compareObject[trophyListId] = comparePlusData; this._save(compareObject); } async _save(compareObject) { await this._storage.setItem(this._storageKey, JSON.stringify(compareObject)); } async clear() { await this._storage.removeItem(this._storageKey); } async export() { return this._get(); } async import(compareObject) { await this._save(compareObject); } } /***/ }), /* 28 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "HybridStorage": () => (/* binding */ HybridStorage) /* harmony export */ }); /** * NOTE: GM.* APIs used in this storage are not available * when running in UserScripts. We just fallback to localStorage. */ class HybridStorage { async setItem(key, value) { if (GM.setValue == null) { return localStorage.setItem(key, value); } localStorage.removeItem(key); return GM.setValue(key, value); } async getItem(key) { if (GM.getValue == null) { return localStorage.getItem(key); } const gmValue = await GM.getValue(key); return gmValue == null ? localStorage.getItem(key) : gmValue; } async removeItem(key) { if (GM.deleteValue != null) { await GM.deleteValue(key); } localStorage.removeItem(key); } } /***/ }), /* 29 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "GuideStorage": () => (/* binding */ GuideStorage) /* harmony export */ }); const TWENTY_FOUR_HOURS = 24 * 60 * 60 * 1000; class GuideStorage /* implements IExportableStorage */ { constructor() { this._storageKey = 'psnpp-guidelist'; this._limit = 1000; } get() { try { const data = localStorage.getItem(this._storageKey); if (data == null) { return []; } return JSON.parse(data); } catch (e) { console.error('Failed to load guide info', e); return []; } } indexedByTrophyListId() { const guides = this.get(); const result = new Map(); guides.forEach(guide => { result.set(guide.trophyListId, guide); }); return result; } getByTrophyListId(trophyListId) { const guides = this.indexedByTrophyListId(); return guides.get(trophyListId); } add(item) { this._removeOldestIfNeeded(); const guides = this.get(); const existsIndex = guides.findIndex((x) => x.trophyListId === item.trophyListId); if (existsIndex > -1) { guides[existsIndex] = item; } else { guides.push(item); } this._save(guides); } shouldUpdate(trophyListId) { const guides = this.indexedByTrophyListId(); const guide = guides.get(trophyListId); if (guide == null) { return true; } return guide.timestamp + TWENTY_FOUR_HOURS < Date.now(); } _removeOldestIfNeeded() { const guides = this.get(); if (guides.length >= this._limit) { guides .sort((a, b) => a.timestamp - b.timestamp) .shift(); this._save(guides); } } _save(guides) { localStorage.setItem(this._storageKey, JSON.stringify(guides)); } export() { return this.get(); } import(guides) { this._save(guides); } clear() { localStorage.removeItem(this._storageKey); } } /***/ }), /* 30 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "PlatPricesStorage": () => (/* binding */ PlatPricesStorage) /* harmony export */ }); /* harmony import */ var _PlatPricesAPI__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(23); const ONE_HOUR = 60 * 60 * 1000; const TWELVE_HOURS = 12 * ONE_HOUR; const TWENTYFOUR_HOURS = 2 * TWELVE_HOURS; class PlatPricesStorage { constructor() { this._storageKey = 'psnpp-platprices'; } get() { try { const prices = localStorage.getItem(this._storageKey); if (prices == null) { return []; } return JSON.parse(prices); } catch (e) { console.error('Failed to load prices from storage', e); return []; } } async getById(trophyListId, trophyListIdentifiers) { const prices = this.get(); const price = prices.find(list => list.id === trophyListId); if (price == null || price.timestamp + TWELVE_HOURS < Date.now()) { let priceResponse; try { priceResponse = await (0,_PlatPricesAPI__WEBPACK_IMPORTED_MODULE_0__.fetchPrice)(trophyListIdentifiers); } catch (e) { const typedError = e; const errorCode = typedError.getErrorCode(); // NOTE: Create dummy record for: 404, 5xx, random network errors if (errorCode === _PlatPricesAPI__WEBPACK_IMPORTED_MODULE_0__.IPlatPricesError.NETWORK_ERROR || errorCode === _PlatPricesAPI__WEBPACK_IMPORTED_MODULE_0__.IPlatPricesError.NOTFOUND) { this.add({ id: trophyListId, timestamp: Date.now() - TWELVE_HOURS + ONE_HOUR, error: errorCode, BasePrice: '', SalePrice: '', PlusPrice: '', formattedBasePrice: '', formattedSalePrice: '', formattedPlusPrice: '', PSStoreURL: '', PlatPricesURL: '', PSPExtra: '0', PSPPremium: '0' }); } throw typedError; } const priceRecord = Object.assign({}, { id: trophyListId, timestamp: Date.now() }, priceResponse); this.add(priceRecord); return priceRecord; // NOTE: Price record exists and is not expired } else { // This is a cached error result // Throw error and UI will handle showing it to user if (price.error !== 0) { throw new _PlatPricesAPI__WEBPACK_IMPORTED_MODULE_0__.PlatPricesAPIError({ error: price.error }); } return price; } } add(item) { const prices = this.get(); const existsIndex = prices.findIndex((x) => x.id === item.id); if (existsIndex > -1) { prices[existsIndex] = item; } else { prices.push(item); } this._save(prices); } _save(newPrices) { localStorage.setItem(this._storageKey, JSON.stringify(newPrices)); } clear() { localStorage.removeItem(this._storageKey); } clearExpired() { const prices = this.get(); const validPrices = prices.filter(price => price.timestamp + TWENTYFOUR_HOURS > Date.now()); this._save(validPrices); } } /***/ }), /* 31 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Panel": () => (/* binding */ Panel) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); class PanelCornerButton extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(onClick) { super('a'); this._onClick = onClick; this._build(); } _build() { this .setAttribute('href', '#') .addClass('close') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('img') .setAttribute('src', '/lib/img/layout/close.png') .setAttribute('title', 'close') .addClass('close_image') .click((e) => { e.preventDefault(); this._onClick(); })); } } class PanelTitle extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(title) { super('div'); this._title = title; this._build(); } _build() { this.addClass('title-bar', 'flex', 'v-align') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('grow') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('h3').setText(this._title))); } } class PanelMain extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(title, onClose) { super('div'); this._title = title; this._onClose = onClose; this._holder = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('holder'); this._build(); } _build() { this .setAttribute('id', 'facebox') .setAttribute('style', 'top: 50px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('popup') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('content') .append(new PanelTitle(this._title), this._holder), new PanelCornerButton(() => this._onClose()))); } addContent(...content) { this._holder.append(...content); } } class PanelBackdrop extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(onClick) { super('div'); this._onClick = onClick; this._build(); } _build() { this.setAttribute('id', 'facebox_overlay') .setAttribute('style', 'opacity: 0.5; display: block;') .addClass('facebox_overlayBG') .click(() => this._onClick()); } } class Panel extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(title) { super('div'); this._backdropCloseEnabled = true; this._resolver = null; this._title = title; this._main = new PanelMain(this._title, () => this.remove()); this._build(); } _build() { this.append(this._main, new PanelBackdrop(() => { if (this._backdropCloseEnabled) { this.remove(); } })); } addContent(...content) { this._main.addContent(...content); } disableBackdropClose() { this._backdropCloseEnabled = false; } wait() { return new Promise((resolve) => { this._resolver = resolve; }); } resolve(result) { if (this._resolver != null) { this._resolver(result); } } } /***/ }), /* 32 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "PanelSection": () => (/* binding */ PanelSection) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); class PanelSectionTitle extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(title) { super('div'); this._build(title); } _build(title) { this.addClass('title', 'center', 'flex', 'v-align') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('grow') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('h3').setText(title))); } } class PanelSection extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(sectionTitle, ...children) { super('div'); this._sectionTitle = sectionTitle; this._children = children; this._build(); } _build() { const childrenContainer = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('box', 'no-top-border', 'form') .setAttribute('style', 'padding: 10px;'); this._children.forEach(c => { childrenContainer.append(c); }); this .addClass('row') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-12') .append(new PanelSectionTitle(this._sectionTitle), childrenContainer)); } } /***/ }), /* 33 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "PanelInput": () => (/* binding */ PanelInput) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(34); class PanelInput extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(label, value, tooltipText, validator = () => true, action = null) { super('div'); this._input = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('input'); this._label = label; this._value = value; this._tooltipText = tooltipText; this._validator = validator; this._action = action; this._build(); } _build() { this._input = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('input') .setAttribute('type', 'text') .setAttribute('value', this._value); if (this._tooltipText !== '') { this._input.apply(e => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_1__.tooltip)(e, this._tooltipText)); } this .addClass('row', 'middle-xs') .setAttribute('style', 'margin-top: 10px; margin-bottom: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-2') .setAttribute('style', 'text-align: right;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('small-title') .setText(this._label)), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass(this._action == null ? 'col-xs-10' : 'col-xs-9') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('label') .addClass('input') .append(this._input, _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i'))), this._action == null ? null : _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div').addClass('col-xs-1').append(this._action)); } serialize() { return this._input.getValue().trim(); } commaSeparatedList() { return this.serialize() .split(',') .map((x) => x.trim()) .filter((x) => x !== ''); } validate() { const validationResult = this._validator(this.serialize()); if (!validationResult) { this._input.setCss('borderColor', '#ffb6c1'); } else { this._input.setCss('borderColor', '#e3e3e6'); } return validationResult; } } /***/ }), /* 34 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "activateSpoilers": () => (/* binding */ activateSpoilers), /* harmony export */ "gamesListCanBeExpanded": () => (/* binding */ gamesListCanBeExpanded), /* harmony export */ "loadAllGames": () => (/* binding */ loadAllGames), /* harmony export */ "loadJqueryUi": () => (/* binding */ loadJqueryUi), /* harmony export */ "sortable": () => (/* binding */ sortable), /* harmony export */ "tooltip": () => (/* binding */ tooltip) /* harmony export */ }); /* harmony import */ var _observe__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(35); /* harmony import */ var _J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _fetch__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13); /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25); function tooltip(element, text) { $(element).tipTip({ defaultPosition: 'bottom', maxWidth: '500px', edgeOffset: 0, delay: 0, fadeIn: 50, fadeOut: 50, content: text }); } function loadAllGames(callback) { if (nextPage === 0) { callback(); return; } const disconnect = (0,_observe__WEBPACK_IMPORTED_MODULE_0__.gamesObserve)(() => { disconnect(); setTimeout(() => loadAllGames(callback), 1000); }); loadMoreGames(); nextPage = 0; } function gamesListCanBeExpanded() { return nextPage > 0; } function loadJqueryUi() { return (0,_fetch__WEBPACK_IMPORTED_MODULE_2__.loadScriptTag)(_constants__WEBPACK_IMPORTED_MODULE_3__.EXTERNAL_SCRIPT_URLS.JQUERY_UI); } function sortable(element, onSort) { $(element).sortable({ axis: 'y', containment: $(_J__WEBPACK_IMPORTED_MODULE_1__.J.q('body').get()), cursor: 'ns-resize', handle: 'div.draggable-list-handle', placeholder: 'placeholder', revert: '150', items: 'tr', scrollSpeed: 50, scrollSensitivity: 100, start: (e, ui) => { ui.item.data('previndex', ui.item.index()); }, update: (e, ui) => onSort(e, ui), }); } function activateSpoilers() { prepareSpoilers(); } /***/ }), /* 35 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "gamesObserve": () => (/* binding */ gamesObserve), /* harmony export */ "htmlObserve": () => (/* binding */ htmlObserve), /* harmony export */ "observe": () => (/* binding */ observe) /* harmony export */ }); /* harmony import */ var _J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); function observe(target, callback) { const observer = new MutationObserver(callback); observer.observe(target.get(), { childList: true, subtree: true }); return () => observer.disconnect(); } let singletonHtmlObserveDisconnect = null; const htmlObserveCallbacks = []; function htmlObserve(callback) { htmlObserveCallbacks.push(callback); if (singletonHtmlObserveDisconnect == null) { singletonHtmlObserveDisconnect = observe(_J__WEBPACK_IMPORTED_MODULE_0__.J.q('html'), (mutations, observer) => { htmlObserveCallbacks.forEach(x => x(mutations, observer)); }); } } function gamesObserve(callback) { const disconnect = observe(_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#gamesTable').parent(), (mutations, observer) => { const scrollLoaderExists = _J__WEBPACK_IMPORTED_MODULE_0__.J.q('#gamesTable > tbody > tr#table-loading').exists(); const searchLoaderExists = _J__WEBPACK_IMPORTED_MODULE_0__.J.q(`#${CSS.escape('search-results')} .loadingoverlay`).exists(); if (scrollLoaderExists || searchLoaderExists) { return; } callback(mutations, observer); }); return disconnect; } /***/ }), /* 36 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "PanelCheckbox": () => (/* binding */ PanelCheckbox) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(34); class PanelCheckbox extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(label, value, labelTooltipText = undefined) { super('div'); this._input = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('input'); this._label = label; this._value = value; this._labelTooltipText = labelTooltipText; this._build(); } _build() { this._input = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('input') .setAttribute('type', 'checkbox'); if (this._value) { this._input.setAttribute('checked', 'checked'); } this .addClass('row', 'middle-xs') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-10', 'col-xs-offset-2') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('label') .addClass('checkbox') .append(this._input, _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').setText(this._label).apply(el => { if (this._labelTooltipText != null) { (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_1__.tooltip)(el, this._labelTooltipText); } })))); } serialize() { return this._input.get().checked; } } /***/ }), /* 37 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "PanelBottom": () => (/* binding */ PanelBottom) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); class PanelBottom extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(saveButtonLabel, onClickSave, closeButtonLabel, onClickClose) { super('div'); this._onClickSave = onClickSave; this._onClickClose = onClickClose; this._saveButtonLabel = saveButtonLabel; this._closeButtonLabel = closeButtonLabel; this._build(); } _build() { this.addClass('bottom', 'cf') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('floatr') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setAttribute('style', 'margin-right: 4px;') .addClass('button', 'green') .setText(this._saveButtonLabel) .click((e) => { this._onClickSave(); e.preventDefault(); }), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .addClass('button', 'red') .setText(this._closeButtonLabel) .click((e) => { this._onClickClose(); e.preventDefault(); }))); } } /***/ }), /* 38 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "PanelSelect": () => (/* binding */ PanelSelect) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); class PanelSelect extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(label, value, options) { super('div'); this._label = label; this._value = value; this._options = options; this._build(); } _build() { this .addClass('row', 'middle-xs') .setAttribute('style', 'margin-top: 10px; margin-bottom: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-2') .setAttribute('style', 'text-align: right;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('small-title') .setText(this._label)), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-10') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('label') .addClass('select') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('select') .change(e => { if (e == null || e.target == null) { return; } this._value = e.target.value; }) .append(...Object.keys(this._options).map(key => { return _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('option') .setAttribute('value', key) .setText(this._options[key]) .condition(this._value === key, (el) => el.setAttribute('selected', 'selected')); })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i')))); } serialize() { return this._value; } } /***/ }), /* 39 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "appendPanel": () => (/* binding */ appendPanel), /* harmony export */ "appendPanelWait": () => (/* binding */ appendPanelWait) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); function appendPanel(panel) { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('body').append(panel); scrollTo(0, 0); } function appendPanelWait(panel) { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('body').append(panel); scrollTo(0, 0); return panel.wait(); } /***/ }), /* 40 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ListRefreshPanel": () => (/* binding */ ListRefreshPanel) /* harmony export */ }); /* harmony import */ var _ui_panel_Panel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(31); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _ListStorage__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8); class SimpleProgress extends _util_J__WEBPACK_IMPORTED_MODULE_1__.JC { constructor() { super('span'); this.done = 0; this.total = 0; this.hide(); this.refresh(); } refresh() { this.setText(`[ Progress: ${this.done}/${this.total} ]`); } } class ListRefreshPanel extends _ui_panel_Panel__WEBPACK_IMPORTED_MODULE_0__.Panel { constructor() { super('Refresh games in your lists'); this._addContent(); this.disableBackdropClose(); } _addContent() { const progress = new SimpleProgress(); const buttonsContainer = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('center'); this.addContent(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .setAttribute('id', 'inner') .addClass('inner') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('center') .setAttribute('style', 'margin-bottom: 10px;') .append('PSNP+ allows you to refresh game data in your non-remote lists (name of the game, completion rates, guide availability etc.).', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), 'Each unique game in your lists can be refreshed once every 24 hours, but in general, you should not need to run this more than once every few weeks. It takes about 2-3 seconds to refresh a single game on average. Once you start the process, leave the window open and let PSNP+ finish the refresh.', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), 'Once the process is done, every game across all of your lists will be refreshed.', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), 'As a friendly reminder, make regular backups of your PSNP+ data every once in a while if you make large changes.'), buttonsContainer .setAttribute('style', 'margin-bottom: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .addClass('button', 'blue') .setText('Refresh') .click(async (e) => { e.preventDefault(); buttonsContainer.hide(); const listStorage = new _ListStorage__WEBPACK_IMPORTED_MODULE_2__.ListStorage(); progress.total = listStorage.getUniqueGamesForRefresh().length; progress.refresh(); progress.show(); await listStorage.refresh((state, index) => { if (state === 'success' && index !== null) { progress.done = index + 1; progress.refresh(); } if (state === 'done') { progress.setText('[ Refresh is done. You can reload the page now. ]'); buttonsContainer.empty() .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .addClass('button', 'green') .setText('Reload') .click((e) => { e.preventDefault(); location.reload(); })) .show(); } }); }), ' ', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .addClass('button', 'red') .setText('Close') .click((e) => { e.preventDefault(); this.remove(); })), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('center') .append(progress))); } } /***/ }), /* 41 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "UpdatePanel": () => (/* binding */ UpdatePanel) /* harmony export */ }); /* harmony import */ var _ui_panel_Panel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(31); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(25); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3); class UpdatePanel extends _ui_panel_Panel__WEBPACK_IMPORTED_MODULE_0__.Panel { constructor() { super('PSNP+ Update'); this._addContent(); this._loadChangelog(); this.disableBackdropClose(); } async _loadChangelog() { try { const changelog = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_2__.fetchText)(_util_constants__WEBPACK_IMPORTED_MODULE_1__.LINK_CHANGELOG); _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-changelog').setValue(changelog); } catch (e) { _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-changelog').setValue('Failed to load changelog: ' + e.message); } } _addContent() { this.addContent(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .setAttribute('id', 'inner') .addClass('inner') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('center') .setAttribute('style', 'margin-bottom: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('img').setAttribute('src', GM_info.script.icon), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .setAttribute('style', 'font-size: 20px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('b').setText('PSNP+'), ' has been updated to ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('b').setText(`v${GM_info.script.version}`)), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .setAttribute('style', 'margin: 10px 0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('small') .setAttribute('style', 'padding: 3px; background-color: #E2AA51; border: 1px solid #a77b34; border-radius: 2px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', 'https://www.buymeacoffee.com/HusKyCode') .setAttribute('target', '_blank') .setAttribute('style', 'color: white;') .append('If you find PSNP+ useful, please consider supporting this project and buying me a beer 🍺. Thanks!'))), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .addClass('form') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('label') .addClass('textarea') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('textarea') .setAttribute('id', 'psnpp-changelog') .setAttribute('readonly', 'readonly') .setAttribute('style', 'width: 60%; height: 200px; font-family: monospace;'))), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), 'Visit ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', _util_constants__WEBPACK_IMPORTED_MODULE_1__.LINK_MAIN_THREAD) .setAttribute('target', '_blank') .setText('discussion thread'), ' for more info.'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('center') .setAttribute('style', 'margin-bottom: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', '#') .addClass('button', 'red') .setText('Close') .click((e) => { e.preventDefault(); this.remove(); })))); } } /***/ }), /* 42 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "safeRun": () => (/* binding */ safeRun) /* harmony export */ }); async function safeRun(func) { try { await func(); } catch (e) { console.error('[PSNP+ SafeRun]', e); } } /***/ }), /* 43 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "DonatorsStorage": () => (/* binding */ DonatorsStorage) /* harmony export */ }); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(25); /* harmony import */ var _storage_ExpirableStorage__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(26); class DonatorsStorage extends _storage_ExpirableStorage__WEBPACK_IMPORTED_MODULE_1__.ExpirableStorage { constructor() { super({ supportedVersion: 1, remoteUrl: _util_constants__WEBPACK_IMPORTED_MODULE_0__.LINK_DONATORS, storageKey: 'psnpp-donators', // 4 hours expirationTimeMs: 4 * 60 * 60 * 1000, emptyValue: {} }); } getDonatorStatus(psnId) { const donators = this.get(); if (donators.data.list[psnId] == null) { return { isDonator: false, count: 0 }; } return { isDonator: true, count: donators.data.list[psnId] }; } } /***/ }), /* 44 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Frontpage": () => (/* binding */ Frontpage) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(12); /* harmony import */ var _util_user__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(19); /* harmony import */ var _util_observe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(35); /* harmony import */ var _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(25); /* harmony import */ var _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(21); /* harmony import */ var _features_blacklist_GamesScraper__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(45); /* harmony import */ var _features_lists_platforms__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(46); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(34); /* harmony import */ var _util_Logger__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(47); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(13); class Frontpage { constructor(settingsStorage) { this._settingsStorage = settingsStorage; this._logger = new _util_Logger__WEBPACK_IMPORTED_MODULE_10__.Logger(this._settingsStorage.get('enableScriptLogger'), 'Frontpage'); } _getRedirect() { return (0,_util_url__WEBPACK_IMPORTED_MODULE_1__.getSearchParams)().get('redirect'); } _isRedirectSet() { const redirectParam = this._getRedirect(); return (typeof redirectParam === 'string' && redirectParam.length > 0); } _getPsnId() { return (0,_util_url__WEBPACK_IMPORTED_MODULE_1__.getSearchParams)().get('psnId'); } _overrideRefreshBox() { // Override green Update User button _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.button.green', { containsText: 'Update User' }) .setAttribute('onclick', '') .click((e) => { e.preventDefault(); const psnId = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#psnId').getValue(); if (psnId === '') { return; } (0,_util_url__WEBPACK_IMPORTED_MODULE_1__.redirect)((0,_util_user__WEBPACK_IMPORTED_MODULE_2__.getUpdateProfileRedirectUrl)(psnId, '/' + psnId)); }); // Override 'Update' button in inline results const observableTarget = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#inline-results'); if (!observableTarget.exists()) { return; } (0,_util_observe__WEBPACK_IMPORTED_MODULE_3__.observe)(observableTarget, () => { (0,_util_J__WEBPACK_IMPORTED_MODULE_0__.all)('#inline-results tr').forEach((el) => { const username = el.clone().find('td', { eq: 0 }).find('a').getText(); el .find('td', { eq: 1 }) .find('a', { eq: 1 }) .setAttribute('onclick', '') .setAttribute('href', (0,_util_user__WEBPACK_IMPORTED_MODULE_2__.getUpdateProfileRedirectUrl)(username, '/' + username)); }); }); } _highlightRelevantDlcs() { const gameProgressStorage = new _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_4__.GameProgressStorage(); const gameProgressList = gameProgressStorage.indexedById(); const newDlcBanner = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div.grow > h3', { equalsText: 'New DLC' }); const newDlcTable = newDlcBanner .clone() .parent() .parent() .next() .find('table.zebra'); (0,_util_J__WEBPACK_IMPORTED_MODULE_0__.all)('tr', {}, newDlcTable.get()).forEach(el => { const pathname = el.clone().find('a.title').getAttribute('href'); const trophyListId = (0,_util_url__WEBPACK_IMPORTED_MODULE_1__.getFirstLevelIdFromPathname)(pathname); const gameProgress = gameProgressList.get(trophyListId); if (gameProgress == null) { return; } el.setCss('backgroundColor', _util_constants__WEBPACK_IMPORTED_MODULE_5__.COLOR_LIGHT_YELLOW); }); } async _mergePopularGames() { const header = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('h3', { equalsText: 'Popular Games This Week' }); const gamesContainer = header.parent().parent().next(); const signature = (0,_util_J__WEBPACK_IMPORTED_MODULE_0__.all)('tr', {}, gamesContainer.get()) .map(row => { const pathname = row.clone().find('span.small-title').parent().getAttribute('href'); const recentPlayers = row.clone().find('span.typo-top').getText(); return (0,_util_url__WEBPACK_IMPORTED_MODULE_1__.getFirstLevelIdFromPathname)(pathname) + recentPlayers; }) .join(''); const scriptStateStorage = new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_6__.ScriptStateStorage(); const storedSignature = scriptStateStorage.get('popularListsSignature'); let popularGames = scriptStateStorage.get('popularGames'); if (storedSignature !== signature) { try { popularGames = await _features_blacklist_GamesScraper__WEBPACK_IMPORTED_MODULE_7__.GamesScraper.getFromUrl('https://psnprofiles.com/games?order=popular'); scriptStateStorage.set('popularListsSignature', signature); scriptStateStorage.set('popularGames', popularGames); } catch (e) { this._logger.error('Failed to fetch popular games', e); } } const duplicateInfo = {}; const gamesToUse = []; for (let i = 0; i < popularGames.length; i++) { const matchingGame = gamesToUse.find(game => game.title === popularGames[i].title); if (matchingGame != null) { duplicateInfo[popularGames[i].title] = duplicateInfo[popularGames[i].title] || 0; duplicateInfo[popularGames[i].title]++; for (const [key, value] of Object.entries(popularGames[i].platforms)) { if (value) { matchingGame.platforms[key] = value; } } matchingGame.recent += popularGames[i].recent; continue; } if (gamesToUse.length < 10) { gamesToUse.push(popularGames[i]); } } gamesToUse.sort((a, b) => b.recent - a.recent); gamesContainer.empty(); gamesContainer.append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('table') .addClass('zebra') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('tbody') .append(...gamesToUse.map(game => { return _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('tr') .addClass('even') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', game.url) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('img') .addClass('game') .setAttribute('src', game.image))), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'width: 100%;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('line-clamp', 'two', 'title') .setAttribute('href', game.url) .setText(game.title), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('platforms') .append(...Object.entries((0,_features_lists_platforms__WEBPACK_IMPORTED_MODULE_8__.mapPlatforms)(game.platforms)) .map(([key, value]) => _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('tag', 'platform', key) .setText(value)), duplicateInfo[game.title] != null ? _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('small-info') .setAttribute('href', '/search/games?q=' + encodeURIComponent(game.title)) .setText(` (+${duplicateInfo[game.title]})`) .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_9__.tooltip)(el, `Number of hidden stacks: ${duplicateInfo[game.title]}. Click to search.`)) : null)), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('center') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').addClass('typo-top').setText(game.recent.toLocaleString('en-US')), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').addClass('typo-bottom').setText('Players')))); })))); } async _hideStacksInNewTrophylists() { const header = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('h3', { equalsText: 'New Trophy Lists' }); const gamesContainer = header.parent().parent().next(); const signature = (0,_util_J__WEBPACK_IMPORTED_MODULE_0__.all)('tr', {}, gamesContainer.get()) .map(row => { const pathname = row.clone().find('a.title').getAttribute('href'); return (0,_util_url__WEBPACK_IMPORTED_MODULE_1__.getFirstLevelIdFromPathname)(pathname); }) .join(''); const scriptStateStorage = new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_6__.ScriptStateStorage(); const storedSignature = scriptStateStorage.get('newListsSignature'); let latestGames = scriptStateStorage.get('latestGames'); if (storedSignature !== signature) { try { latestGames = await _features_blacklist_GamesScraper__WEBPACK_IMPORTED_MODULE_7__.GamesScraper.getFromUrl('https://psnprofiles.com/games'); scriptStateStorage.set('newListsSignature', signature); scriptStateStorage.set('latestGames', latestGames); } catch (e) { this._logger.error('Failed to fetch new games', e); } } const duplicateInfo = {}; const gamesToUse = []; for (let i = 0; i < latestGames.length; i++) { const matchingGame = gamesToUse.find(game => game.title === latestGames[i].title); if (matchingGame != null) { duplicateInfo[latestGames[i].title] = duplicateInfo[latestGames[i].title] || 0; duplicateInfo[latestGames[i].title]++; for (const [key, value] of Object.entries(latestGames[i].platforms)) { if (value) { matchingGame.platforms[key] = value; } } continue; } gamesToUse.push(latestGames[i]); if (gamesToUse.length === 10) { break; } } gamesContainer.empty(); gamesContainer.append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('table') .addClass('zebra') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('tbody') .append(...gamesToUse.map(game => { return _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('tr') .addClass('even') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', game.url) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('img') .addClass('game') .setAttribute('src', game.image))), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'width: 100%;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('line-clamp', 'two', 'title') .setAttribute('href', game.url) .setText(game.title), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('platforms') .append(...Object.entries((0,_features_lists_platforms__WEBPACK_IMPORTED_MODULE_8__.mapPlatforms)(game.platforms)) .map(([key, value]) => _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('tag', 'platform', key) .setText(value)), duplicateInfo[game.title] != null ? _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('small-info') .setAttribute('href', '/search/games?q=' + encodeURIComponent(game.title)) .setText(` (+${duplicateInfo[game.title]})`) .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_9__.tooltip)(el, `Number of hidden stacks: ${duplicateInfo[game.title]}. Click to search.`)) : null)), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('trophy-count', 'cf') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('ul') .addClass('floatr') .append(game.trophies.platinum === 1 ? _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li').addClass('icon-sprite', 'platinum').setText(game.trophies.platinum.toString()) : null, _util_constants__WEBPACK_IMPORTED_MODULE_5__.MAGIC_SPACE, _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li').addClass('icon-sprite', 'gold').setText(game.trophies.gold.toString()), _util_constants__WEBPACK_IMPORTED_MODULE_5__.MAGIC_SPACE, _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li').addClass('icon-sprite', 'silver').setText(game.trophies.silver.toString()), _util_constants__WEBPACK_IMPORTED_MODULE_5__.MAGIC_SPACE, _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li').addClass('icon-sprite', 'bronze').setText(game.trophies.bronze.toString())), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('small-info', 'floatr') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b') .setText((game.trophies.platinum + game.trophies.gold + game.trophies.silver + game.trophies.bronze).toString()), ' Trophies ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText(game.points.toLocaleString('en-US')), ' Points')))); })))); } async _loadDlcImages() { const header = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('h3', { equalsText: 'New DLC' }); const gamesContainer = header.parent().parent().next(); const pathnames = (0,_util_J__WEBPACK_IMPORTED_MODULE_0__.all)('tr', {}, gamesContainer.get()) .map(row => row.clone().find('a.title').getAttribute('href')); const signature = pathnames.join(','); const scriptStateStorage = new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_6__.ScriptStateStorage(); const storedSignature = scriptStateStorage.get('newDLCSignature'); let dlcImages = scriptStateStorage.get('dlcImages'); if (signature !== storedSignature) { const dlcDocument = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_11__.fetchDocument)('https://psnprofiles.com/games/dlc'); dlcImages = pathnames.map(pathname => { return _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q(`a.title[href="${pathname}"]`, {}, dlcDocument) .parent() .prev() .find('picture') .getOuterHTML(); }); scriptStateStorage.set('newDLCSignature', signature); scriptStateStorage.set('dlcImages', dlcImages); } (0,_util_J__WEBPACK_IMPORTED_MODULE_0__.all)('tr', {}, gamesContainer.get()).forEach((row, i) => { row.find('a') .empty() .setInnerHtml(dlcImages[i]); }); } run() { this._logger.debug('Running'); const shouldRedirect = this._isRedirectSet(); const psnId = this._getPsnId(); if (shouldRedirect && psnId != null) { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.button.green', { containsText: 'Update User' }).triggerClick(); const destroy = (0,_util_observe__WEBPACK_IMPORTED_MODULE_3__.observe)(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div#processing'), () => { const updateDone = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div.psn-info').find('span.success', { containsText: 'Updated' }).exists(); const errorOccured = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div.psn-info').find('span.error', { containsText: 'Error' }).exists(); if (updateDone || errorOccured) { destroy(); } if (updateDone) { const redirectPath = this._getRedirect(); if (redirectPath != null) { (0,_util_url__WEBPACK_IMPORTED_MODULE_1__.redirect)(redirectPath); } } }); return; } if (location.hash.startsWith(_util_constants__WEBPACK_IMPORTED_MODULE_5__.HASH_PROFILE)) { const websiteUrl = (0,_util_url__WEBPACK_IMPORTED_MODULE_1__.getWebsiteUrl)(); const psnId = (0,_util_user__WEBPACK_IMPORTED_MODULE_2__.getPsnId)(); const searchParams = (0,_util_url__WEBPACK_IMPORTED_MODULE_1__.getSearchParamsFromHash)(); const hash = searchParams.get('hash'); this._logger.debug('Redirecting to profile. Hash:', hash); const urlToRedirectTo = `${websiteUrl}/${psnId}${hash == null ? '' : '#' + hash}`; location.href = urlToRedirectTo; return; } if (this._settingsStorage.get('automaticallyRedirectAfterUpdatingProfile')) { this._overrideRefreshBox(); } if (this._settingsStorage.get('hideStacksOnTheFrontpage')) { this._hideStacksInNewTrophylists(); } if (this._settingsStorage.get('mergePopularGamesOnTheFrontpage')) { this._mergePopularGames(); } if (this._settingsStorage.get('loadDLCImagesOnTheFrontpage')) { this._loadDlcImages(); } this._highlightRelevantDlcs(); } } /***/ }), /* 45 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "GamesScraper": () => (/* binding */ GamesScraper) /* harmony export */ }); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(12); class GamesScraper { constructor(doc) { this._doc = doc; } _q(query, options = {}) { return _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q(query, options, this._doc); } getFromGamesPage() { const gameList = this._q('#game_list'); return (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('tr', {}, gameList.get()).map(row => { const titleElement = row.clone().find('a.title'); const pathname = titleElement.getAttribute('href'); const id = (0,_util_url__WEBPACK_IMPORTED_MODULE_2__.getFirstLevelIdFromPathname)(pathname); const title = titleElement.getText(); const image = row.clone().find('picture img').getAttribute('src'); const url = (0,_util_url__WEBPACK_IMPORTED_MODULE_2__.getWebsiteUrl)() + pathname; const pointsText = row.clone().find('span.small-info', { eq: 1 }).find('b', { eq: 1 }).getText().replace(/[^\d]*/g, ''); const points = parseInt(pointsText, 10); const owners = parseInt(row.clone().find('span.small-info').find('b').getText().replace(/[^\d]*/g, ''), 10); const recent = parseInt(row.clone().find('span.small-info').find('b', { eq: 1 }).getText().replace(/[^\d]*/g, ''), 10); const platinumElement = row.clone().find('span.icon-sprite.platinum'); const platinum = platinumElement.exists() ? parseInt(platinumElement.next().getText(), 10) : 0; const gold = parseInt(row.clone().find('span.icon-sprite.gold').next().getText(), 10); const silver = parseInt(row.clone().find('span.icon-sprite.silver').next().getText(), 10); const bronze = parseInt(row.clone().find('span.icon-sprite.bronze').next().getText(), 10); const isPS5 = row.clone().find('span.tag.platform.ps5').exists(); const isPS4 = row.clone().find('span.tag.platform.ps4').exists(); const isPS3 = row.clone().find('span.tag.platform.ps3').exists(); const isPSVITA = row.clone().find('span.tag.platform.psvita').exists(); const isPSVR = row.clone().find('span.tag.platform.psvr').exists(); return { id, title, image, url, points, owners, recent, platforms: { ps3: isPS3, ps4: isPS4, ps5: isPS5, psvita: isPSVITA, psvr: isPSVR }, trophies: { platinum, gold, silver, bronze } }; }); } static async getFromUrl(url) { const doc = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_0__.fetchDocument)(url); return new GamesScraper(doc).getFromGamesPage(); } } /***/ }), /* 46 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "mapPlatforms": () => (/* binding */ mapPlatforms) /* harmony export */ }); const PLATFORM_MAP = { ps5: 'PS5', ps4: 'PS4', ps3: 'PS3', psvita: 'Vita', psvr: 'VR' }; function mapPlatforms(platforms) { const mapped = {}; if (platforms == null) { return mapped; } Object.keys(platforms).forEach((key) => { const platformFlagSet = platforms[key] === true; if (platformFlagSet) { mapped[key] = PLATFORM_MAP[key]; } }); return mapped; } /***/ }), /* 47 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Logger": () => (/* binding */ Logger) /* harmony export */ }); class Logger { constructor(enabled, marker) { this._enabled = enabled; this._marker = marker; } _getTag() { return `[PSNP+][${this._marker}]`; } log(...args) { if (this._enabled) { console.log(this._getTag(), ...args); } } warn(...args) { if (this._enabled) { console.warn(this._getTag(), ...args); } } error(...args) { if (this._enabled) { console.error(this._getTag(), ...args); } } debug(...args) { if (this._enabled) { console.debug(this._getTag(), ...args); } } } /***/ }), /* 48 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "FrontpageImmediate": () => (/* binding */ FrontpageImmediate) /* harmony export */ }); /* harmony import */ var _util_stylesheet__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(49); class FrontpageImmediate { constructor(settingsStorage) { this._settingsStorage = settingsStorage; } run() { console.debug('FrontpageImmediate module is running'); if (this._settingsStorage.get('resizePS5Icons')) { (0,_util_stylesheet__WEBPACK_IMPORTED_MODULE_0__.injectStylesheet)(_util_stylesheet__WEBPACK_IMPORTED_MODULE_0__.STYLESHEET_FRONTPAGE_RESIZE_PS5_ICONS); } } } /***/ }), /* 49 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "STYLESHEET_FRONTPAGE_RESIZE_PS5_ICONS": () => (/* binding */ STYLESHEET_FRONTPAGE_RESIZE_PS5_ICONS), /* harmony export */ "STYLESHEET_GLOBAL": () => (/* binding */ STYLESHEET_GLOBAL), /* harmony export */ "STYLESHEET_GLOBAL_FLOATING_MENU_STYLE": () => (/* binding */ STYLESHEET_GLOBAL_FLOATING_MENU_STYLE), /* harmony export */ "STYLESHEET_GUIDE": () => (/* binding */ STYLESHEET_GUIDE), /* harmony export */ "STYLESHEET_PROFILE_HIDE_RANK": () => (/* binding */ STYLESHEET_PROFILE_HIDE_RANK), /* harmony export */ "STYLESHEET_PROFILE_RESIZE_PS5_ICONS": () => (/* binding */ STYLESHEET_PROFILE_RESIZE_PS5_ICONS), /* harmony export */ "STYLESHEET_TROPHIES_HIDE_GUIDE_BANNER": () => (/* binding */ STYLESHEET_TROPHIES_HIDE_GUIDE_BANNER), /* harmony export */ "injectStylesheet": () => (/* binding */ injectStylesheet) /* harmony export */ }); /* harmony import */ var _J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); const STYLESHEET_GLOBAL = ` table.list-table .placeholder { height: 67px !important; } .psnpp-hide { display: none !important; } `; const STYLESHEET_GLOBAL_FLOATING_MENU_STYLE = ` @media only screen and (min-width: 1850px) { .psnpp-floating-menu { opacity: 1 !important; } } @media (hover: none) { .psnpp-floating-menu { opacity: 1 !important; } } .button.grey { background: #646464; } `; const STYLESHEET_FRONTPAGE_RESIZE_PS5_ICONS = ` div#content table.zebra tr > td:first-child { text-align: center !important; background-color: #292b2d !important; background-clip: content-box !important; } div#content table.zebra tr img.game { max-height: 56px !important; max-width: 100px !important; height: auto !important; width: auto !important; } picture.game { text-align: center !important; } picture.game > img { max-height: 56px !important; max-width: 100px !important; height: auto !important; width: auto !important; } `; // profile // trophy log, advisor, level history const STYLESHEET_PROFILE_RESIZE_PS5_ICONS = ` picture.game { text-align: center !important; } picture.game > img { max-height: 56px !important; max-width: 100px !important; height: auto !important; width: auto !important; } div#content table.zebra:not(.list-table):not(#gamesTable):not(#search-results) tr > td:first-child { text-align: center !important; background-color: #292b2d !important; background-clip: content-box !important; } div#content table.zebra:not(.list-table):not(#gamesTable):not(#search-results) tr img.game { max-height: 56px !important; max-width: 100px !important; height: auto !important; width: auto !important; } `; const STYLESHEET_PROFILE_HIDE_RANK = ` span.stat.rank, span.stat.country-rank { display: none !important; } `; const STYLESHEET_TROPHIES_HIDE_GUIDE_BANNER = ` div.guide-page-info { display: none !important; } `; const STYLESHEET_GUIDE = ` .psnpp-strikethrough-fade { text-decoration: line-through; opacity: 0.3; } .psnpp-highlight { background-color: #ecf8ea; border: 1px solid #dae9d7; } `; function injectStylesheet(stylesheet) { const target = _J__WEBPACK_IMPORTED_MODULE_0__.J.q('head').exists() ? _J__WEBPACK_IMPORTED_MODULE_0__.J.q('head') : new _J__WEBPACK_IMPORTED_MODULE_0__.J(document.body).exists() ? new _J__WEBPACK_IMPORTED_MODULE_0__.J(document.body) : new _J__WEBPACK_IMPORTED_MODULE_0__.J(document.documentElement); if (!target.exists()) { setTimeout(() => injectStylesheet(stylesheet), 50); return; } target .append(_J__WEBPACK_IMPORTED_MODULE_0__.J.c('style') .setAttribute('type', 'text/css') .setInnerHtml(stylesheet)); } /***/ }), /* 50 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Guide": () => (/* binding */ Guide) /* harmony export */ }); /* harmony import */ var _ui_FloatingMenu__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(51); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(13); /* harmony import */ var _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(20); /* harmony import */ var _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(21); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(34); /* harmony import */ var _util_user__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(19); /* harmony import */ var _features_lists_platforms__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(46); /* harmony import */ var _util_stylesheet__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(49); /* harmony import */ var _util_video__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(52); /* harmony import */ var _util_Logger__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(47); /* harmony import */ var _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(24); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(12); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(25); /* harmony import */ var _util_date__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(53); /* harmony import */ var _features_guide_GuideScraper__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(54); /* harmony import */ var _util_string__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(55); const LOAD_FROM_LINK_VALUE = '__psnpp_load_from_link__'; const ID_PROGRESS_LOADER_TITLE = 'psnpp-progress-loader-title'; const ID_PROGRESS_LOADER_TABLE = 'psnpp-progress-loader-table'; const ID_GUIDE_BREAKDOWN_TABLE = 'psnpp-guide-breakdown-table'; class Guide { constructor(subSection) { this._earnedTrophiesHidden = false; this._sidebarHidden = false; this._videosHidden = false; this._checklistsEnabled = false; this._tagHidden = false; this._subSection = undefined; this._settingsStorage = new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_2__.SettingsStorage(); this._logger = new _util_Logger__WEBPACK_IMPORTED_MODULE_11__.Logger(this._settingsStorage.get('enableScriptLogger'), 'Guide'); this._subSection = subSection; this._matchingGames = this._getMatchingGames(); this._logger.debug('Matching games for this guide:', this._matchingGames); this._selectedMatchingGameUrl = this._matchingGames.length > 0 ? this._matchingGames[0].url : LOAD_FROM_LINK_VALUE; this._trophyListLink = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('input') .setAttribute('type', 'text') .setAttribute('style', 'margin-top: 5px; width: 100%;') .setAttribute('placeholder', 'Trophy list link') .hide() .condition(this._selectedMatchingGameUrl === LOAD_FROM_LINK_VALUE, (el) => el.show()); const isSimpleMatchingEnabled = new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_5__.ScriptStateStorage().get('guideSimpleMatching'); this._simpleMatchingCheckbox = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('input') .setAttribute('type', 'checkbox') .condition(isSimpleMatchingEnabled, (el) => el.setAttribute('checked', 'checked')) .change(ev => { const checked = ev.currentTarget.checked; new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_5__.ScriptStateStorage().set('guideSimpleMatching', checked); }); } _getMatchingGames() { const fullTitle = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('title').getText(); const isDLCGuide = fullTitle.indexOf('DLC Trophy Guide') > -1; const gameName = isDLCGuide ? fullTitle.split(' • ')[0].split(' - ').slice(0, -1).join(' - ').trim() : fullTitle.split(' • ')[0].replace('Trophy Guide', '').trim(); const profileGames = new _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_4__.GameProgressStorage().get(); const matchingGames = profileGames .filter(game => { if (game.title == null || game.url == null) { return false; } return game.title.toLowerCase().includes(gameName.toLowerCase()) || gameName.toLowerCase().includes(game.title.toLowerCase()); }) // Sort by longest matching substring .sort((a, b) => { if (a.title == null || b.title == null) { return 0; } return (0,_util_string__WEBPACK_IMPORTED_MODULE_17__.levenshtein)(gameName, a.title) - (0,_util_string__WEBPACK_IMPORTED_MODULE_17__.levenshtein)(gameName, b.title); }); return matchingGames; } _toggleElement(el) { if (this._earnedTrophiesHidden) { el.hide(); } else { el.show(); } } _toggleEarnedTrophies() { // Main trophy list const earned = []; (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div[id^="SectionContainer"]').forEach((el) => { const hasTrophyEarned = el.clone().find('img.trophy.earned').exists(); if (!hasTrophyEarned) { return; } const navigationId = el.clone().find('div').getAttribute('id'); earned.push(`#${navigationId}`); this._toggleElement(el); }); // Overview (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div.guide.overview a.icon-sprite').forEach((el) => { const href = el.getAttribute('href'); if (earned.indexOf(href) > -1) { this._toggleElement(el); } }); // Sidebar (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('li[id^="TOCSection"].earned').forEach((el) => this._toggleElement(el)); // Roadmap (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div.roadmap-trophies > div.col-xs-6 > div.earned,div.roadmap-trophies > div.col-xs-12 > div.earned') .map((el) => el.parent()) .forEach((el) => this._toggleElement(el)); // Strikethrough all trophies inside texts const trophyLinks = (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('a') .filter(el => { const href = el.getAttribute('href'); return earned.some(e => href.indexOf(e) > -1); }); if (this._earnedTrophiesHidden) { trophyLinks.forEach(el => el.setCss('textDecoration', 'line-through').setCss('opacity', '0.3')); } else { trophyLinks.forEach(el => el.setCss('textDecoration', 'none').setCss('opacity', '1')); } } _highlightEarnedTrophies() { const earnedTrophies = (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('li[id^="TOCSection"].earned') .map(el => el.clone().find('a').getAttribute('href')); // This is the overview with tags (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div.guide.overview a.icon-sprite').forEach(el => { const href = el.getAttribute('href'); if (earnedTrophies.indexOf(href) > -1) { el.addClass('psnpp-highlight'); } }); // NOTE: Links with .title are those that appear inside trophy banners. // We don't need those. (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('#content #sections a:not(.title)').forEach(el => { const href = el.getAttribute('href'); if (earnedTrophies.some(e => href.endsWith(e))) { el.addClass('psnpp-highlight'); } }); } _clearProgress() { // Main trophy list (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div[id^="SectionContainer"]').forEach((mainItem) => { const hasTrophyImage = mainItem.clone().find('img.trophy').exists(); if (!hasTrophyImage) { return; } // Trophy icon border mainItem.clone().find('img.trophy').removeClass('earned').addClass('unearned'); // Date mainItem.clone().find('td', { eq: 2 }).find('center').remove(); }); // Sidebar (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('li[id^="TOCSection"]').forEach(sidebarItem => sidebarItem.removeClass('earned')); // Roadmap (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div.roadmap-trophies > div.col-xs-6 > div.trophy,div.roadmap-trophies > div.col-xs-12 > div.trophy') .forEach((roadmapItem) => roadmapItem.removeClass('earned')); (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('.psnpp-highlight').forEach(el => el.removeClass('psnpp-highlight')); } _markTrophyAsEarned(trophyRow) { const simpleMatchingIsEnabled = this._simpleMatchingCheckbox.get().checked; let trophyName = trophyRow.clone().find('a.title').getText().trim().toLowerCase(); if (simpleMatchingIsEnabled) { const numberString = trophyRow.clone().find('a.title').getAttribute('href').split('/').reverse()[0].match(/^[0-9]{1,3}/); if (numberString != null) { const number = parseInt(numberString[0], 10); (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div[id^="SectionContainer"] a.title').forEach(title => { const guideNumberString = title.clone().getAttribute('href').split('/').reverse()[0].match(/^[0-9]{1,3}/); if (guideNumberString != null) { const guideNumber = parseInt(guideNumberString[0], 10); if (number === guideNumber) { trophyName = title.clone().getText().trim().toLowerCase(); } } }); } } const date = trophyRow.clone().find('span.typo-top-date').getText(); const time = trophyRow.clone().find('span.typo-bottom-date').getText(); // Main trophy list (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div[id^="SectionContainer"]').forEach((mainItem) => { const hasTrophyImage = mainItem.clone().find('img.trophy').exists(); if (!hasTrophyImage) { return; } const text = mainItem.clone().find('a.title').getText().trim().toLowerCase(); if (text === trophyName) { mainItem.clone().find('img.trophy').removeClass('unearned').addClass('earned'); // Date mainItem.clone().find('td', { eq: 2 }).append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('center') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span').addClass('typo-top-date').append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('nobr').setText(date)), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span').addClass('typo-bottom-date').append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('nobr').setText(time)))); } }); // Sidebar (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('li[id^="TOCSection"]').forEach(sidebarItem => { const text = sidebarItem.clone().find('a').getText().trim().toLowerCase(); if (text === trophyName) { sidebarItem.addClass('earned'); } }); // Roadmap (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div.roadmap-trophies > div.col-xs-6 > div.trophy,div.roadmap-trophies > div.col-xs-12 > div.trophy') .forEach((roadmapItem) => { const text = roadmapItem.clone().find('a.title').getText().trim().toLowerCase(); if (text === trophyName) { roadmapItem.addClass('earned'); } }); } async _loadProgress() { try { const shouldRetoggleEarnedTrophies = this._earnedTrophiesHidden; const urlToLoad = this._selectedMatchingGameUrl === LOAD_FROM_LINK_VALUE ? this._trophyListLink.getValue() : this._selectedMatchingGameUrl; const trophyListDoc = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_3__.fetchDocument)(urlToLoad); const earnedTrophies = (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('#content.page > div.row > div.col-xs tr.completed', {}, trophyListDoc); if (shouldRetoggleEarnedTrophies) { _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('#psnpp-toggle-earned').triggerClick(); } this._clearProgress(); earnedTrophies.forEach(earnedTrophy => this._markTrophyAsEarned(earnedTrophy)); this._highlightEarnedTrophies(); if (shouldRetoggleEarnedTrophies) { _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('#psnpp-toggle-earned').triggerClick(); } } catch (e) { this._logger.error('Failed to load progress', e); // TODO: Replace this alert('PSNP+: Failed to load progress.'); } } _appendGuideLoader() { _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('div.game-image-holder') .next() .after(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .setAttribute('id', ID_PROGRESS_LOADER_TITLE) .addClass('title', 'flex', 'v-align') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('h3') .addClass('grow') .setText('Progress')), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('table') .setAttribute('id', ID_PROGRESS_LOADER_TABLE) .addClass('box', 'zebra') .setAttribute('style', 'margin-bottom: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tbody') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tr') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .setAttribute('style', 'padding-right: 5px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .addClass('form') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('label') .addClass('select') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('select') .change((e) => { if (e == null || e.target == null) { return; } this._selectedMatchingGameUrl = e.target.value; if (this._selectedMatchingGameUrl === LOAD_FROM_LINK_VALUE) { this._trophyListLink.show(); } else { this._trophyListLink.hide(); } }) .append(...this._matchingGames.map((game) => { const platformTags = Object.values((0,_features_lists_platforms__WEBPACK_IMPORTED_MODULE_8__.mapPlatforms)(game.platforms)); const itemText = game.title + ' (' + platformTags.join(', ') + ')' + (game.region == null ? '' : ' [' + game.region + ']'); return _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('option') .setAttribute('value', game.url + '?order=psn') .setText(itemText); }) .concat([ _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('option') .setAttribute('value', LOAD_FROM_LINK_VALUE) .setText('Load from link') ])), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('i')), this._trophyListLink, _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('label') .addClass('checkbox') .append(this._simpleMatchingCheckbox, _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('i'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .setText('Use simple matching') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_6__.tooltip)(el, 'Uses trophy numbers instead of trophy names to match progress from trophy list. You can use this when trophy list language does not match guide language or when the trophy names are different.'))), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .setAttribute('style', 'margin-top: 5px;') .addClass('button', 'green') .setText('Load') .click(async (e, el) => { e.preventDefault(); if (this._selectedMatchingGameUrl == null) { return; } el.addClass('state-disabled'); el.setText('Loading...'); await this._loadProgress(); el.removeClass('state-disabled'); el.setText('Load'); }))))))); } _appendMenu(lazyLoadInstance) { const menuWrapper = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div'); const toggleEarnedButton = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('id', 'psnpp-toggle-earned') .setAttribute('href', '#') .addClass('button', 'grey') .setText('🔴 Hide earned trophies') .click((e) => { e.preventDefault(); this._earnedTrophiesHidden = !this._earnedTrophiesHidden; if (this._earnedTrophiesHidden) { toggleEarnedButton.setText('🟢 Hide earned trophies'); } else { toggleEarnedButton.setText('🔴 Hide earned trophies'); } this._toggleEarnedTrophies(); }); const toggleSidebar = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .addClass('button', 'grey') .setAttribute('style', 'margin-top: 5px;') .setText('🔴 Hide sidebar') .click((e) => { e.preventDefault(); this._sidebarHidden = !this._sidebarHidden; if (this._sidebarHidden) { toggleSidebar.setText('🟢 Hide sidebar'); } else { toggleSidebar.setText('🔴 Hide sidebar'); } _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('div.col-xs-4.col-xs-max-320').toggleClass('psnpp-hide'); }); const hideVideos = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .addClass('button', 'grey') .setAttribute('style', 'margin-top: 5px;') .setText('🔴 Hide videos') .click((e) => { e.preventDefault(); this._videosHidden = !this._videosHidden; if (this._videosHidden) { hideVideos.setText('🟢 Hide videos'); } else { hideVideos.setText('🔴 Hide videos'); } (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('iframe[data-src^="https://www.youtube.com/embed"]').forEach(x => x.parent().toggleClass('psnpp-hide')); }); const enableChecklists = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .addClass('button', 'grey') .setAttribute('style', 'margin-top: 5px;') .setText('🔴 Enable checklists') .click((e) => { e.preventDefault(); this._checklistsEnabled = !this._checklistsEnabled; if (this._checklistsEnabled) { enableChecklists.setText('🟢 Enable checklists'); } else { enableChecklists.setText('🔴 Enable checklists'); } }); const refreshProgressButton = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .setAttribute('style', 'margin-top: 5px;') .addClass('button', 'grey') .setText('Refresh progress') .setAttribute('href', (0,_util_user__WEBPACK_IMPORTED_MODULE_7__.getUpdateProfileRedirectUrl)((0,_util_user__WEBPACK_IMPORTED_MODULE_7__.getPsnId)(), location.pathname)); const showAllSpoilersButton = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .setAttribute('style', 'margin-top: 5px;') .addClass('button', 'grey') .setText('Show all spoilers') .click((e) => { e.preventDefault(); (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('span.spoiler').forEach(el => el.triggerClick()); }); const loadAllLazyMedia = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .setAttribute('style', 'margin-top: 5px;') .addClass('button', 'grey') .setText('Load all media') .click((e) => { e.preventDefault(); lazyLoadInstance === null || lazyLoadInstance === void 0 ? void 0 : lazyLoadInstance.loadAll(); loadAllLazyMedia.remove(); }); menuWrapper.append(this._isGameplayGuide() ? null : toggleEarnedButton, this._isGameplayGuide() ? null : _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), toggleSidebar, _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), hideVideos, _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), enableChecklists, _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), refreshProgressButton, _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), showAllSpoilersButton, lazyLoadInstance == null ? null : _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), lazyLoadInstance == null ? null : loadAllLazyMedia); const floatingMenu = new _ui_FloatingMenu__WEBPACK_IMPORTED_MODULE_0__.FloatingMenu(menuWrapper); floatingMenu.insert(); } _markMissingInTheRoadmap() { const roadmapTrophies = (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div.roadmap-trophies a.title'); const sidebarTrophies = (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('li[id^="TOCSection"] span.icon-sprite').map(x => x.parent().find('a')); if (roadmapTrophies.length >= sidebarTrophies.length) { return; } const missingTrophies = sidebarTrophies.filter(x => !roadmapTrophies.some(r => r.getAttribute('href') === x.getAttribute('href'))); const taggedTrophiesContainer = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td'); _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('table.tags > tbody') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tr') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .addClass('tag') .setAttribute('style', 'background: #5865f2;') .setText('No Roadmap')), taggedTrophiesContainer)); missingTrophies.forEach(t => { const iconType = t.getAttribute('class'); const hashHref = t.getAttribute('href'); taggedTrophiesContainer .append(_util_constants__WEBPACK_IMPORTED_MODULE_14__.MAGIC_SPACE, _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('nobr') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .addClass('trophy', iconType) .condition(iconType === 'platinum', x => x.setAttribute('style', `background-position: 0 2px; background-size: 14px; background-repeat: no-repeat; background-image: url("${_util_constants__WEBPACK_IMPORTED_MODULE_14__.ICON_SPRITE}");`)) .condition(iconType !== 'platinum', x => x.addClass('icon-sprite')) .setAttribute('href', hashHref) .setText(t.getText().trim()))); const individualTrophy = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('#' + CSS.escape(hashHref.slice(1))); const tags = individualTrophy.clone().find('#tags'); if (!tags.exists()) { individualTrophy .clone() .find('div.section-original') .prepend(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .setAttribute('id', 'tags') .addClass('section-tags', 'box', 'light', 'clearfix', 'no-top-border') .setAttribute('style', 'padding: 5px 5px 5px 4px;')); } individualTrophy .clone() .find('#tags') .prepend(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .addClass('tag') .setAttribute('style', `background: ${_util_constants__WEBPACK_IMPORTED_MODULE_14__.COLOR_PURPLE};`) .setText('No Roadmap')); }); } _markUnobtainableTrophies() { if (!this._settingsStorage.get('markUnobtainableTrophies')) { return; } const unobtainableTrophies = new _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_12__.UnobtainableTrophiesStorage().get(); const firstTrophyPath = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('a.title[href^="/trophy/"]').getAttribute('href'); const trophyListId = parseInt((0,_util_url__WEBPACK_IMPORTED_MODULE_13__.getFirstLevelIdFromPathname)(firstTrophyPath), 10); const unobtainableTrophiesForList = unobtainableTrophies.data.list[trophyListId]; if (unobtainableTrophiesForList == null) { return; } const taggedTrophiesContainer = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td'); const unobtainableTag = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tr') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .addClass('tag') .setAttribute('style', 'background: #5865f2;') .setText('Unobtainable') .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_6__.tooltip)(el, 'Information comes from PSNP+ Unobtainable Trophies Master List'))), taggedTrophiesContainer); const tagsTable = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('table.tags > tbody'); const unattainableTag = tagsTable.clone().find('span.tag', { equalsText: 'Unattainable' }); if (unattainableTag.exists()) { unattainableTag.clone().parent().parent().after(unobtainableTag); } else { tagsTable.append(unobtainableTag); } let foundAtLeastOneTrophy = false; (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('a.title[href^="/trophy/"]') .sort((a, b) => { const trophyNameA = a.getText(); const trophyNameB = b.getText(); return trophyNameA.localeCompare(trophyNameB); }) .forEach(trophyLink => { const trophyPath = trophyLink.getAttribute('href'); const trophyName = trophyLink.getText(); const trophyId = parseInt((0,_util_url__WEBPACK_IMPORTED_MODULE_13__.getSecondLevelIdFromPathname)(trophyPath), 10); if (unobtainableTrophiesForList.includes(trophyId) || unobtainableTrophiesForList[0] === 0) { foundAtLeastOneTrophy = true; const upperContainer = trophyLink.clone() .parent().parent().parent().parent().parent().parent(); const isPlatinum = upperContainer.clone().find('img[alt="Platinum"]').exists(); if (isPlatinum) { return; } const tagsContainer = upperContainer.clone().find('#tags'); if (!tagsContainer.exists()) { upperContainer .clone() .find('div.section-original') .prepend(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .setAttribute('id', 'tags') .addClass('section-tags', 'box', 'light', 'clearfix', 'no-top-border') .setAttribute('style', 'padding: 5px 5px 5px 4px;')); } upperContainer.clone().find('#tags') .prepend(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .addClass('tag') .setAttribute('style', `background: ${_util_constants__WEBPACK_IMPORTED_MODULE_14__.COLOR_PURPLE};`) .setText('Unobtainable')); const iconClass = upperContainer.clone() .find('img[alt="Gold"],img[alt="Silver"],img[alt="Bronze"]') .getAttribute('alt') .toLowerCase(); taggedTrophiesContainer .append(_util_constants__WEBPACK_IMPORTED_MODULE_14__.MAGIC_SPACE, _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('nobr') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .addClass('icon-sprite', 'trophy', iconClass) .setAttribute('href', '#' + upperContainer.getAttribute('id')) .setText(trophyName))); } }); if (!foundAtLeastOneTrophy) { taggedTrophiesContainer .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .setAttribute('style', 'font-size: 15px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', `/trophies/${trophyListId}`) .setText('Trophy list'), ' contains unobtainable trophies not covered by this guide.')); } } _attachTagClickListeners() { const allTags = (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('table.tags span.tag'); allTags.forEach(el => { el.setCss('cursor', 'pointer'); el.click((ev, el) => { if (!this._tagHidden) { const nextTd = el.clone().parent().next(); const allTrophyNames = (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('a', undefined, nextTd.get()).map(el => el.getText()); this._hideByWhitelist(allTrophyNames); el.setCss('border', '2px dashed #44484b'); } else { this._hideByWhitelist(null); allTags.forEach(tag => tag.setCss('border', 'none')); } this._tagHidden = !this._tagHidden; }); }); } _hideByWhitelist(whitelist) { // Main trophy list (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div[id^="SectionContainer"]').forEach((el) => { const hasTrophyImage = el.clone().find('img.trophy').exists(); if (!hasTrophyImage) { return; } const trophyName = el.clone().find('a.title').getText(); if (whitelist != null && whitelist.indexOf(trophyName) === -1) { el.hide(); } else { el.show(); } }); // Overview (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div.guide.overview a.icon-sprite').forEach((el) => { const trophyName = el.getText(); if (whitelist != null && whitelist.indexOf(trophyName) === -1) { el.hide(); } else { el.show(); } }); // Sidebar (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('li[id^="TOCSection"] a').forEach((el) => { const trophyName = el.getText().trim(); if (whitelist != null && whitelist.indexOf(trophyName) === -1) { el.parent().hide(); } else { el.parent().show(); } }); // Roadmap (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div.roadmap-trophies > div.col-xs-6 > div.trophy,div.roadmap-trophies > div.col-xs-12 > div.trophy') .map((el) => el.parent()) .forEach((el) => { const trophyName = el.clone().find('a').getText(); if (whitelist != null && whitelist.indexOf(trophyName) === -1) { el.hide(); } else { el.show(); } }); } _checklistHelper() { (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('#sections ul > li, #sections ol > li, #sections table:not(.tags):not(.zebra) tr').forEach(checkableElement => { checkableElement.setCss('cursor', 'pointer'); checkableElement.click((_e, clickElement) => { if (this._checklistsEnabled) { clickElement.toggleClass('psnpp-strikethrough-fade'); } }); }); } _isGameplayGuide() { const firstTrophy = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('a.title[href^="/trophy/"]'); return !firstTrophy.exists(); } _switchHoursTo24HourFormat() { if (!new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_2__.SettingsStorage().get('use24HourTimeFormat')) { return; } (0,_util_date__WEBPACK_IMPORTED_MODULE_15__.switchHoursTo24HourFormat)(); } _appendGuideBreakdown() { const relatedGuidesExist = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('h3.grow', { equalsText: 'Related Guides' }).exists(); if (!relatedGuidesExist) { return; } const guidesPathname = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('div.title-bar').find('a[href^="/guides/"]').getAttribute('href'); _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('#' + ID_PROGRESS_LOADER_TABLE) .after(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .addClass('title', 'flex', 'v-align') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('h3') .addClass('grow') .setText('Guide Breakdown')), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('table') .setAttribute('id', ID_GUIDE_BREAKDOWN_TABLE) .addClass('box', 'zebra') .setAttribute('style', 'margin-bottom: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tbody') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tr') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('center') .setText('Click the Load button to load information about complexity from related guides.'))), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tr') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('center') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .addClass('button', 'green') .setAttribute('style', 'display: block;') .setText('Load') .click(async (e) => { e.preventDefault(); const guidesDocument = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_3__.fetchDocument)(guidesPathname); const allGuidesPathnames = (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('a[href^="/guide/"]', {}, guidesDocument) .map(el => el.getAttribute('href')); const tBody = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tbody'); const spinnerRow = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tr') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('center') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('i') .addClass('fa', 'fa-spinner', 'fa-spin', 'fa-fw') .setAttribute('aria-hidden', 'true'), 'Loading...'))); _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('#' + ID_GUIDE_BREAKDOWN_TABLE) .empty() .append(tBody .append(spinnerRow)); for (const guidePathname of [...allGuidesPathnames]) { const guideDoc = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_3__.fetchDocument)(guidePathname); const guideName = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('#desc-name', {}, guideDoc).getText(); const guideAuthors = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('div.title-author > a', {}, guideDoc).getText(); const isDlc = guideName.includes('DLC Trophy Guide'); const isGuideWithComplexity = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('a.title[href^="/trophy/"]', {}, guideDoc).exists(); const label = !isGuideWithComplexity ? 'Gameplay Guide' : isDlc ? 'DLC Guide' : 'Trophy Guide'; const guideInfo = new _features_guide_GuideScraper__WEBPACK_IMPORTED_MODULE_16__.GuideScraper(guideDoc).getFromGuidePage('0'); tBody .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tr') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .addClass('ellipsis') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .addClass('small-title') .setAttribute('href', guidePathname) .setText(guideName)), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .addClass('small-info', 'line-clamp', 'two') .append(' by ', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a').setAttribute('href', '/' + guideAuthors).setText(guideAuthors)), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .setAttribute('style', 'margin-top: 5px; font-size: 11px;') .condition(location.pathname === guidePathname, div => { div .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .setAttribute('style', 'background: #64a75c; color: black; padding: 1px 2px; border-radius: 50%;') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('i') .addClass('fa', 'fa-eye') .setAttribute('aria-hidden', 'true')) .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_6__.tooltip)(el, 'Currently viewed guide')), ' '); }) .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .setText(label) .setAttribute('style', 'background: #057fcc; color: white; padding: 1px 2px; border-radius: 2px;')) .condition(isGuideWithComplexity, div => { div.append(' ', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .setText(`${guideInfo.difficulty}/10`) .setAttribute('style', `${guideInfo.difficultyStyle}; color: white; padding: 1px 2px; border-radius: 2px;`) .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_6__.tooltip)(el, 'Difficulty')), ' ', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .setText(`${guideInfo.playthroughs}x`) .setAttribute('style', `${guideInfo.playthroughsStyle}; color: white; padding: 1px 2px; border-radius: 2px;`) .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_6__.tooltip)(el, 'Playthroughs')), ' ', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .setText(`${guideInfo.time}h`) .setAttribute('style', `${guideInfo.timeStyle}; color: white; padding: 1px 2px; border-radius: 2px;`) .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_6__.tooltip)(el, 'Time'))); })))); } spinnerRow.remove(); }))))))); } _makeCollapsibleHeaders() { (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div.box.section-holder').forEach(holder => { const isPlatinum = holder.clone().find('img[alt="Platinum"]').exists(); if (isPlatinum) { return; } holder.apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_6__.tooltip)(el, 'Click to collapse')); holder.setCss('cursor', 'pointer'); holder.click(e => { holder.clone().next().toggleClass('psnpp-hide'); e.preventDefault(); }); }); } async run() { this._logger.debug('Running'); if (this._subSection != null) { // Edit guide, comments and other stuff... return; } (0,_util_stylesheet__WEBPACK_IMPORTED_MODULE_9__.injectStylesheet)(_util_stylesheet__WEBPACK_IMPORTED_MODULE_9__.STYLESHEET_GUIDE); let lazyLoadInstance = null; if (this._settingsStorage.get('guideLazyLoadMedia')) { lazyLoadInstance = await (0,_util_video__WEBPACK_IMPORTED_MODULE_10__.applyLazyLoad)(); } this._appendMenu(lazyLoadInstance); this._switchHoursTo24HourFormat(); if (!this._isGameplayGuide()) { this._markMissingInTheRoadmap(); this._markUnobtainableTrophies(); this._highlightEarnedTrophies(); this._appendGuideLoader(); this._appendGuideBreakdown(); this._attachTagClickListeners(); this._makeCollapsibleHeaders(); } this._checklistHelper(); if (this._settingsStorage.get('guideAutomaticallyHideEarnedTrophies')) { _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('#psnpp-toggle-earned').triggerClick(); } } } /***/ }), /* 51 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "FloatingMenu": () => (/* binding */ FloatingMenu) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5); /* harmony import */ var _util_stylesheet__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(49); class FloatingMenu extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(content, onShow = () => { // Noop }, onHide = () => { // Noop }) { super('div'); this.addClass('psnpp-floating-menu'); this._baseStyle = [ 'position: fixed;', 'top: 20px;', 'left: 20px;', 'z-index: 2147483647;', 'background-color: #292b2d;', 'padding: 5px;', 'border: 1px solid #646464;', 'opacity: 0.2;', 'color: white;', 'border-radius: 5px;' ].join(' '); this._content = content; this._onShow = onShow; this._onHide = onHide; this._build(); } _build() { this .setAttribute('style', this._baseStyle) .mouseenter((_, el) => { el.setCss('opacity', '1'); this._onShow(); }) .mouseleave((_, el) => { el.setCss('opacity', '0.2'); this._onHide(); }) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div').append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText('PSNP+ Menu'))); } insert() { if (new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_1__.SettingsStorage().get('hideFloatingMenus')) { this.setCss('display', 'none'); } this.append(this._content); (0,_util_stylesheet__WEBPACK_IMPORTED_MODULE_2__.injectStylesheet)(_util_stylesheet__WEBPACK_IMPORTED_MODULE_2__.STYLESHEET_GLOBAL_FLOATING_MENU_STYLE); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('body').append(this); } } /***/ }), /* 52 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "applyLazyLoad": () => (/* binding */ applyLazyLoad) /* harmony export */ }); /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(25); /* harmony import */ var _fetch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(13); /* harmony import */ var _J__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3); function loadVanillaLazyload() { return (0,_fetch__WEBPACK_IMPORTED_MODULE_1__.loadScriptTag)(_constants__WEBPACK_IMPORTED_MODULE_0__.EXTERNAL_SCRIPT_URLS.VANILLA_LAZYLOAD); } function embedLazyYT() { (0,_J__WEBPACK_IMPORTED_MODULE_2__.all)('div.lazyYT').forEach((el) => { const videoId = el.getAttribute('data-youtube-id'); el .empty() .setAttribute('style', 'position: relative; padding-bottom: 56.25%; height: 0; margin: 0;') .append(_J__WEBPACK_IMPORTED_MODULE_2__.J.c('iframe') .addClass('lazy') .setAttribute('style', 'position: absolute; top: 0; left: 0; width: 100%; height: 100%;') .setAttribute('frameborder', '0') .setAttribute('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture') .setAttribute('allowfullscreen', 'allowfullscreen') .setAttribute('data-src', `https://www.youtube.com/embed/${videoId}`)); }); } async function applyLazyLoad(embed = false) { try { await loadVanillaLazyload(); if (embed) { embedLazyYT(); } return new LazyLoad(); } catch (e) { console.error('Failed to load youtube videos', e); return null; } } /***/ }), /* 53 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "formatCompletionTimeString": () => (/* binding */ formatCompletionTimeString), /* harmony export */ "formatStringToSupDate": () => (/* binding */ formatStringToSupDate), /* harmony export */ "getPrettyDate": () => (/* binding */ getPrettyDate), /* harmony export */ "parseCompletionTime": () => (/* binding */ parseCompletionTime), /* harmony export */ "parseSupDate": () => (/* binding */ parseSupDate), /* harmony export */ "switchHoursTo24HourFormat": () => (/* binding */ switchHoursTo24HourFormat) /* harmony export */ }); /* harmony import */ var _J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); const monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; // January 20th 2022 const format1Regex = /([a-zA-Z]+) ([\d]{1,2})(st|nd|rd|th) ([\d]{4})/; // 20th Jan 2022 const format2Regex = /([\d]+)(st|nd|rd|th) ([a-zA-Z]{3}) ([\d]{4})/; // 20th January 2022 const format3Regex = /([\d]{1,2})(st|nd|rd|th) ([a-zA-Z]+) ([\d]{4})/; function ordinalSuffixOf(i) { const j = i % 10; const k = i % 100; if (j == 1 && k != 11) { return 'st'; } if (j == 2 && k != 12) { return 'nd'; } if (j == 3 && k != 13) { return 'rd'; } return 'th'; } function getPrettyDate(timestamp) { const date = new Date(timestamp); const day = date.getDate(); const month = date.getMonth(); const year = date.getFullYear(); const monthName = monthNames[month]; const suffix = ordinalSuffixOf(day); return { day, month, monthName, year, suffix }; } function formatStringToSupDate(dateString) { if (format1Regex.test(dateString)) { const match = dateString.match(format1Regex); return [ match[1], ' ', match[2], _J__WEBPACK_IMPORTED_MODULE_0__.J.c('sup').setText(match[3]), ' ', match[4] ]; } else if (format2Regex.test(dateString)) { const match = dateString.match(format2Regex); return [ match[1], _J__WEBPACK_IMPORTED_MODULE_0__.J.c('sup').setText(match[2]), ' ', match[3], ' ', match[4] ]; } return []; } function parseSupDate(dateString) { const match = dateString.match(format3Regex); if (match == null) { return new Date(0); } const [, day, , month, year] = match; const dateToReturn = new Date(); dateToReturn.setDate(parseInt(day, 10)); dateToReturn.setMonth(monthNames.findIndex(x => x === month)); dateToReturn.setFullYear(parseInt(year, 10)); return dateToReturn; } function parseCompletionTime(timeString) { function getValueForRegex(timeString, regex) { const match = timeString.match(regex); if (match == null) { return 0; } return parseInt(match[1], 10); } const SECOND_VALUE = 1; const MINUTE_VALUE = 60 * SECOND_VALUE; const HOUR_VALUE = 60 * MINUTE_VALUE; const DAY_VALUE = 24 * HOUR_VALUE; const WEEK_VALUE = 7 * DAY_VALUE; const MONTH_VALUE = 30 * DAY_VALUE; const YEAR_VALUE = 365 * DAY_VALUE; const years = getValueForRegex(timeString, /([\d]+) year/) * YEAR_VALUE; const months = getValueForRegex(timeString, /([\d]+) month/) * MONTH_VALUE; const weeks = getValueForRegex(timeString, /([\d]+) week/) * WEEK_VALUE; const days = getValueForRegex(timeString, /([\d]+) day/) * DAY_VALUE; const hours = getValueForRegex(timeString, /([\d]+) hour/) * HOUR_VALUE; const minutes = getValueForRegex(timeString, /([\d]+) minute/) * MINUTE_VALUE; const seconds = getValueForRegex(timeString, /([\d]+) second/) * SECOND_VALUE; return years + months + weeks + days + hours + minutes + seconds; } function formatCompletionTimeString(completionTimeString) { const match = completionTimeString.match(/(Completed in|Platinum in) ([a-z0-9, ]+)/); if (match == null) { return []; } return [ match[1], ' ', _J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText(match[2]) ]; } function switchHoursTo24HourFormat() { (0,_J__WEBPACK_IMPORTED_MODULE_0__.all)('.typo-bottom-date > nobr').forEach(timestamp => { const currentTimestamp = timestamp.getText(); const newTime = currentTimestamp.replace(/^(?\d{1,2}):(?\d{1,2}):(?\d{1,2}) (?[AP]M)$/, (...args) => { const matches = args[7]; if (matches.meridiem === 'PM') { matches.hours = (parseInt(matches.hours, 10) + 12).toString(); } if (matches.hours === '12') { matches.hours = '0'; } if (matches.hours === '24') { matches.hours = '12'; } return matches.hours.padStart(2, '0') + ':' + matches.minutes + ':' + matches.seconds; }); timestamp.setText(newTime); }); } /***/ }), /* 54 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "GuideScraper": () => (/* binding */ GuideScraper) /* harmony export */ }); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(13); class GuideScraper { constructor(doc) { this._doc = doc; } _q(query, options = {}) { return _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q(query, options, this._doc); } getFromGuidePage(trophyListId) { const guidePathname = this._q('div.no-shrink.navigation li a').getAttribute('href'); const guideId = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getFirstLevelIdFromPathname)(guidePathname); const difficultyElement = this._q('.overview-info span:first-child .typo-top'); const playthroughsElement = this._q('.overview-info span:nth-child(2) .typo-top'); const timeElement = this._q('.overview-info span:last-child .typo-top'); const difficulty = parseInt(difficultyElement.getText().replace('/10', ''), 10); const difficultyStyle = difficultyElement.clone().parent().getAttribute('style'); const playthroughs = parseInt(playthroughsElement.getText(), 10); const playthroughsStyle = playthroughsElement.clone().parent().getAttribute('style'); const time = parseInt(timeElement.getText(), 10); const timeStyle = timeElement.clone().parent().getAttribute('style'); const onlineRequired = this._q('span.tag', { equalsText: 'Online Required' }).exists(); const multiplayerOnly = this._q('span.tag', { equalsText: 'Multiplayer Only' }).exists(); // NOTE: The '-' below is U+2011 instead of more common U+002d. const onlineCoop = this._q('span.tag', { equalsText: 'Online Co‑Op' }).exists(); const buggy = this._q('span.tag', { equalsText: 'Buggy' }).exists(); const timestamp = Date.now(); return { trophyListId, guideId, difficulty, difficultyStyle, playthroughs, playthroughsStyle, time, timeStyle, online: onlineRequired || multiplayerOnly || onlineCoop, buggy, timestamp }; } static async getFromUrl(url, trophyListId) { const doc = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_2__.fetchDocument)(url); return new GuideScraper(doc).getFromGuidePage(trophyListId); } } /***/ }), /* 55 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "levenshtein": () => (/* binding */ levenshtein) /* harmony export */ }); function levenshtein(initial, compared) { if (initial.length === 0) return compared.length; if (compared.length === 0) return initial.length; const arr = []; for (let i = 0; i <= compared.length; i++) { arr[i] = [i]; for (let j = 1; j <= initial.length; j++) { arr[i][j] = i === 0 ? j : Math.min(arr[i - 1][j] + 1, arr[i][j - 1] + 1, arr[i - 1][j - 1] + (initial[j - 1] === compared[i - 1] ? 0 : 1)); } } return arr[compared.length][initial.length]; } /***/ }), /* 56 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Profile": () => (/* binding */ Profile) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _ui_FloatingMenu__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(51); /* harmony import */ var _features_lists_ListTable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(57); /* harmony import */ var _util_user__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(19); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(12); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(34); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(5); /* harmony import */ var _features_sessions_SessionStorage__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(17); /* harmony import */ var _util_observe__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(35); /* harmony import */ var _util_date__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(53); /* harmony import */ var _features_game_progress_scrapeGameProgress__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(68); /* harmony import */ var _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(20); /* harmony import */ var _features_lists_ListManager__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(69); /* harmony import */ var _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(8); /* harmony import */ var _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(21); /* harmony import */ var _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(24); /* harmony import */ var _features_unobtainables_unobtainables_utils__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(64); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(25); /* harmony import */ var _features_guide_GuideStorage__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(29); /* harmony import */ var _ui_ui_utils__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(39); /* harmony import */ var _features_lists_ListPanel__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(70); /* harmony import */ var _util_Logger__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(47); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(13); /* harmony import */ var _features_donators_DonatorsStorage__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(43); /* harmony import */ var _features_lists_ListButtons__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(72); class Profile { constructor(isMe, username, section) { this._settingsStorage = new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_6__.SettingsStorage(); this._logger = new _util_Logger__WEBPACK_IMPORTED_MODULE_21__.Logger(this._settingsStorage.get('enableScriptLogger'), 'Profile'); this._isMe = isMe; this._username = username; this._section = location.hash !== '' ? location.hash : typeof section === 'undefined' ? 'games' : section; this._listsLink = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', _util_constants__WEBPACK_IMPORTED_MODULE_17__.HASH_GAME_LISTS) .setText('Game Lists'); } _insertMenu() { const menuWrapper = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div'); const updateProfileButton = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .addClass('button', 'grey') .setText('Update profile') .click((e) => { e.preventDefault(); (0,_util_url__WEBPACK_IMPORTED_MODULE_4__.redirect)((0,_util_user__WEBPACK_IMPORTED_MODULE_3__.getUpdateProfileRedirectUrl)(this._username, '/' + this._username)); }); menuWrapper.append(updateProfileButton); const refreshText = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div.sidebar > span.floatr > small').getText().replace(/\s\s+/g, ' ').split(' • '); const refreshContainer = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').hide(); if (!refreshText.some(t => t == null)) { menuWrapper.append(refreshContainer); refreshContainer.append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('small').setText(refreshText[0]).setAttribute('style', 'font-size: 10px;')); refreshContainer.append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('small').setText(refreshText[1]).setAttribute('style', 'font-size: 10px;')); } const floatingMenu = new _ui_FloatingMenu__WEBPACK_IMPORTED_MODULE_1__.FloatingMenu(menuWrapper, () => refreshContainer.show(), () => refreshContainer.hide()); floatingMenu.insert(); } _appendNavigation() { const toAppend = [ _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li').append(this._listsLink) ]; _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('ul.navigation > li', { eq: 0 }).after(...toAppend); } _renderLists() { var _a; _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('ul.navigation > li.active').removeClass('active'); this._listsLink.parent().addClass('active'); const listStorage = new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_13__.ListStorage(); const lists = listStorage.get().sort((a, b) => a.name.localeCompare(b.name)); const lastActiveGameList = new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_14__.ScriptStateStorage().get('lastActiveGameList'); let currentList = (_a = lists.find(list => list.id === lastActiveGameList)) !== null && _a !== void 0 ? _a : lists[0]; const otherLists = lists.filter(list => list.id !== currentList.id); const resizePS5Icons = this._settingsStorage.get('resizePS5Icons'); let listTable = lists.length > 0 ? new _features_lists_ListTable__WEBPACK_IMPORTED_MODULE_2__.ListTable(currentList, otherLists, (listItem) => { listStorage.removeGame(currentList.id, listItem.id); }, (oldIndex, newIndex) => { listStorage.sortGame(currentList.id, oldIndex, newIndex); }, (listItem, targetIndex) => { const movedToIndex = listStorage.moveToIndex(currentList.id, listItem.id, targetIndex); if (movedToIndex) { this._renderLists(); } }, (listItem, note) => { listItem.note = note; listStorage.addGameToList(currentList.id, listItem); }, (listItem, state) => { listItem.psplus = state; listStorage.addGameToList(currentList.id, listItem); }, (listItem, tags) => { listItem.tags = tags; listStorage.addGameToList(currentList.id, listItem); }, { showUrlRefreshButton: currentList.url != null && currentList.url != '', showActionsDropdown: true, isSortAllowed: currentList.orderBy == null || currentList.orderBy === 'custom', resizePS5Icons }) : null; const listManager = new _features_lists_ListManager__WEBPACK_IMPORTED_MODULE_12__.ListManager(lists, (listId) => { const list = listStorage.get().find(list => list.id === listId); if (list == null) { throw new Error('Invalid list ID'); } currentList = list; const otherLists = lists.filter(list => list.id !== currentList.id); if (listTable != null) { listTable.remove(); } listTable = new _features_lists_ListTable__WEBPACK_IMPORTED_MODULE_2__.ListTable(currentList, otherLists, (listItem) => { listStorage.removeGame(currentList.id, listItem.id); }, (oldIndex, newIndex) => { listStorage.sortGame(currentList.id, oldIndex, newIndex); }, (listItem, targetIndex) => { const movedToIndex = listStorage.moveToIndex(currentList.id, listItem.id, targetIndex); if (movedToIndex) { this._renderLists(); } }, (listItem, note) => { listItem.note = note; listStorage.addGameToList(currentList.id, listItem); }, (listItem, state) => { listItem.psplus = state; listStorage.addGameToList(currentList.id, listItem); }, (listItem, tags) => { listItem.tags = tags; listStorage.addGameToList(currentList.id, listItem); }, { showUrlRefreshButton: currentList.url != null && currentList.url != '', showActionsDropdown: true, isSortAllowed: currentList.orderBy == null || currentList.orderBy === 'custom', resizePS5Icons }); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div#content').append(listTable); }); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div#content').empty().append(listManager, listTable); } _displayPoints() { const platinum = parseInt(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('ul.profile-bar li.platinum').getText().trim().replace(/,/g, ''), 10); const gold = parseInt(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('ul.profile-bar li.gold').getText().trim().replace(/,/g, ''), 10); const silver = parseInt(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('ul.profile-bar li.silver').getText().trim().replace(/,/g, ''), 10); const bronze = parseInt(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('ul.profile-bar li.bronze').getText().trim().replace(/,/g, ''), 10); const points = (platinum * 300) + (gold * 90) + (silver * 30) + (bronze * 15); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('ul.profile-bar li.total').apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_5__.tooltip)(el, `${points.toLocaleString('en-US')} Points`)); } _checkDonatorStatus() { const donatorStatus = new _features_donators_DonatorsStorage__WEBPACK_IMPORTED_MODULE_23__.DonatorsStorage().getDonatorStatus(this._username); if (!donatorStatus.isDonator) { return; } const useCoffeeBadge = this._settingsStorage.get('profileUseCoffeeBadge'); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('span.username') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .setText(useCoffeeBadge ? '☕' : '🍺') .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_5__.tooltip)(el, `PSNP+ supporter - ${donatorStatus.count} ${useCoffeeBadge ? 'coffee' : 'beer'}${donatorStatus.count > 1 ? 's' : ''}`))); } _getAllGameRows() { return (0,_util_J__WEBPACK_IMPORTED_MODULE_0__.all)('#gamesTable:not([style*="display: none"]) tr, #search-results:not([style*="display: none"]) tr') .filter(row => { const id = row.getAttribute('id'); return id !== 'load-more' && id !== 'table-loading'; }) .filter(row => { return !row.clone().find('h2.center').exists(); }); } _getAllUnprocessedRows() { return this._getAllGameRows() .filter(row => { const alreadyEnhanced = row.getAttribute('data-psnpp-processed'); return alreadyEnhanced !== 'true'; }); } _markRowsAsProcessed(rows) { rows.forEach(row => { row.setAttribute('data-psnpp-processed', 'true'); }); } _removeGamesFromLists(games) { if (!this._isMe) { return; } const listStorage = new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_13__.ListStorage(); games.forEach(game => { const removed = listStorage.removeGameFromAllListsWithAutoRemoval(game); if (removed) { this._logger.log('Automatically removed game with id', game.id, 'from at least 1 list.'); } }); } _enhanceRowsWithSessions(rows) { if (!this._settingsStorage.get('gamingSessionsScraping')) { return; } const indexedSession = new _features_sessions_SessionStorage__WEBPACK_IMPORTED_MODULE_7__.SessionStorage().indexedByCdnCode(); rows .forEach(row => { const imageUrl = row.clone().find('td').find('img').getAttribute('src'); const cdnCode = (0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getCdnCodeFromImageUrl)(imageUrl); const activeSessions = indexedSession.get(cdnCode); if (activeSessions == null) { return; } const gamePath = row.clone().find('td', { eq: 1 }).find('a').getAttribute('href'); const titleSpan = row.clone().find('td', { eq: 1 }).find('span'); titleSpan.append(' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', gamePath.replace('trophies', 'sessions').replace(this._username, '')) .setAttribute('style', 'color:#646464;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i') .addClass('fa', 'fa-users', 'marker-session') .setAttribute('aria-hidden', 'true') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_5__.tooltip)(el, activeSessions.length + ' Active Gaming Session(s)')))); }); } _enhanceRowsWithUnobtainableTrophies(rows) { if (!this._settingsStorage.get('markUnobtainableTrophies')) { return; } const unobtainableTrophies = new _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_15__.UnobtainableTrophiesStorage().get(); rows .forEach(row => { const trophyListPathname = row.clone().find('a.title').getAttribute('href'); const trophyListId = (0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getFirstLevelIdFromPathname)(trophyListPathname); const unobtainableTrophiesForList = unobtainableTrophies.data.list[trophyListId]; if (unobtainableTrophiesForList == null) { return; } const titleSpan = row.clone().find('td', { eq: 1 }).find('span'); titleSpan.append(' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i') .addClass('fa', 'fa-exclamation-circle', 'marker-unobtainable-trophies') .setAttribute('aria-hidden', 'true') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_5__.tooltip)(el, (0,_features_unobtainables_unobtainables_utils__WEBPACK_IMPORTED_MODULE_16__.getUnobtainableTrophiesDescription)(unobtainableTrophiesForList)))); }); } _enhanceRowsWithGuideInfo(rows) { const guides = new _features_guide_GuideStorage__WEBPACK_IMPORTED_MODULE_18__.GuideStorage().indexedByTrophyListId(); rows .forEach(row => { const trophyListPathname = row.clone().find('a.title').getAttribute('href'); const trophyListId = (0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getFirstLevelIdFromPathname)(trophyListPathname); const guideInfo = guides.get(trophyListId); if (guideInfo == null) { return; } const target = row.clone().find('div.small-info'); target.append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('psnpp-guide-info-profile') .append(' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', `${(0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getWebsiteUrl)()}/guide/${guideInfo.guideId}`) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .setText(`${guideInfo.difficulty}/10`) .setAttribute('style', `${guideInfo.difficultyStyle}; font-size: 10px; color: white; padding: 1px 2px; border-radius: 2px;`), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .setText(`${guideInfo.playthroughs}x`) .setAttribute('style', `${guideInfo.playthroughsStyle}; font-size: 10px; color: white; padding: 1px 2px; border-radius: 2px;`), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .setText(`${guideInfo.time}h`) .setAttribute('style', `${guideInfo.timeStyle}; font-size: 10px; color: white; padding: 1px 2px; border-radius: 2px;`)))); }); } _enhanceRowsWithAddToListButton(rows) { if (!this._settingsStorage.get('profileShowAddToListButton')) { return; } const lastActiveGameList = new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_14__.ScriptStateStorage().get('lastActiveGameList'); if (lastActiveGameList == null) { return; } const listExists = new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_13__.ListStorage().has(lastActiveGameList); if (!listExists) { return; } rows .forEach(row => { const trophyListUrl = row.clone().find('a.title').getAttribute('href'); const trophyListId = (0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getFirstLevelIdFromPathname)(trophyListUrl); row.append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('separator', 'left') .append(new _features_lists_ListButtons__WEBPACK_IMPORTED_MODULE_24__.ListButtonSmall(trophyListId, trophyListUrl, lastActiveGameList, 'psnpp-list-button')))); }); } _enhanceRows(rows) { this._enhanceRowsWithSessions(rows); this._enhanceRowsWithUnobtainableTrophies(rows); this._enhanceRowsWithGuideInfo(rows); this._enhanceRowsWithAddToListButton(rows); this._markRowsAsProcessed(rows); } _scrapeProgress(rows) { if (!this._isMe || this._settingsStorage.get('profileDisableScraping')) { return []; } const games = (0,_features_game_progress_scrapeGameProgress__WEBPACK_IMPORTED_MODULE_10__.scrapeGameProgress)(rows); new _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_11__.GameProgressStorage().addMany(games); return games; } _orderGamesByCompletionTime() { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); this._getAllGameRows() .sort((rowA, rowB) => { const progressA = parseInt(rowA.clone().find('div.progress-bar').find('span').getText().replace('%', ''), 10); const completionTimeContainerA = rowA.clone().find('td', { eq: 1 }).find('div.small-info', { eq: 1 }).find('b'); const completionTimeA = completionTimeContainerA.exists() ? (0,_util_date__WEBPACK_IMPORTED_MODULE_9__.parseCompletionTime)(completionTimeContainerA.getText()) : null; const progressB = parseInt(rowB.clone().find('div.progress-bar').find('span').getText().replace('%', ''), 10); const completionTimeContainerB = rowB.clone().find('td', { eq: 1 }).find('div.small-info', { eq: 1 }).find('b'); const completionTimeB = completionTimeContainerB.exists() ? (0,_util_date__WEBPACK_IMPORTED_MODULE_9__.parseCompletionTime)(completionTimeContainerB.getText()) : null; if (completionTimeA == null && completionTimeB == null) { return progressB - progressA; } if (completionTimeA == null && completionTimeB != null) { return 1; } if (completionTimeA != null && completionTimeB == null) { return -1; } if (completionTimeA != null && completionTimeB != null) { return completionTimeB - completionTimeA; } return 0; }) .forEach(row => _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#gamesTable > tbody').append(row)); } _getRates(row) { const platinumpctElement = row.clone().find('span.completion-status').find('span.platinum'); const platinumpct = platinumpctElement.exists() ? parseFloat(platinumpctElement.getText().replace('%', '')) : undefined; const completepctElement = row.clone().find('span.completion-status').find('span.completion'); const completepct = completepctElement.exists() ? parseFloat(completepctElement.getText().replace('%', '')) : undefined; return { platinumpct, completepct }; } _orderGamesByPlatinumRate() { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); this._getAllGameRows() .sort((rowA, rowB) => { var _a, _b, _c, _d; const ratesA = this._getRates(rowA); const ratesB = this._getRates(rowB); const valueA = (_b = (_a = ratesA.platinumpct) !== null && _a !== void 0 ? _a : ratesA.completepct) !== null && _b !== void 0 ? _b : 0; const valueB = (_d = (_c = ratesB.platinumpct) !== null && _c !== void 0 ? _c : ratesB.completepct) !== null && _d !== void 0 ? _d : 0; return valueB - valueA; }) .forEach(row => _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#gamesTable > tbody').append(row)); } _orderGamesByCompletionRate() { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); this._getAllGameRows() .sort((rowA, rowB) => { var _a, _b, _c, _d; const ratesA = this._getRates(rowA); const ratesB = this._getRates(rowB); const valueA = (_b = (_a = ratesA.completepct) !== null && _a !== void 0 ? _a : ratesA.platinumpct) !== null && _b !== void 0 ? _b : 0; const valueB = (_d = (_c = ratesB.completepct) !== null && _c !== void 0 ? _c : ratesB.platinumpct) !== null && _d !== void 0 ? _d : 0; return valueB - valueA; }) .forEach(row => _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#gamesTable > tbody').append(row)); } _orderByRank() { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); this._getAllGameRows() .sort((rowA, rowB) => { // NOTE: Text is a single-character string from "SABCDEF". let rankA = rowA.clone().find('span.game-rank').getText(); let rankB = rowB.clone().find('span.game-rank').getText(); // NOTE: Using ASCII codes here. '0'(48) is lower than 'A' (65). if (rankA === 'S') rankA = '0'; if (rankB === 'S') rankB = '0'; return rankA.charCodeAt(0) - rankB.charCodeAt(0); }) .forEach(row => _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#gamesTable > tbody').append(row)); } _orderByNumberOfTrophies() { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); this._getAllGameRows() .sort((rowA, rowB) => { // NOTE: This matches first "small-info" const trophiesAMatch = rowA.clone().find('div.small-info').getText().match(/(\d+) Trophies/); const trophiesBMatch = rowB.clone().find('div.small-info').getText().match(/(\d+) Trophies/); let trophiesA = 0; if (trophiesAMatch != null) { trophiesA = parseInt(trophiesAMatch[1], 10); } let trophiesB = 0; if (trophiesBMatch != null) { trophiesB = parseInt(trophiesBMatch[1], 10); } return trophiesB - trophiesA; }) .forEach(row => _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#gamesTable > tbody').append(row)); } _orderByNumberOfUnearnedTrophies() { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); this._getAllGameRows() .sort((rowA, rowB) => { // NOTE: This matches first "small-info" const trophiesAMatch = rowA.clone().find('div.small-info').getText().replace(/\s+/g, ' ').trim().match(/(\d+) of (\d+) Trophies/); const trophiesBMatch = rowB.clone().find('div.small-info').getText().replace(/\s+/g, ' ').trim().match(/(\d+) of (\d+) Trophies/); let unearnedTrophiesA = 0; if (trophiesAMatch != null) { unearnedTrophiesA = parseInt(trophiesAMatch[2], 10) - parseInt(trophiesAMatch[1], 10); } let unearnedTrophiesB = 0; if (trophiesBMatch != null) { unearnedTrophiesB = parseInt(trophiesBMatch[2], 10) - parseInt(trophiesBMatch[1], 10); } return unearnedTrophiesB - unearnedTrophiesA; }) .forEach(row => _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#gamesTable > tbody').append(row)); } _orderByTime() { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); const guides = new _features_guide_GuideStorage__WEBPACK_IMPORTED_MODULE_18__.GuideStorage().indexedByTrophyListId(); this._getAllGameRows() .sort((rowA, rowB) => { var _a, _b, _c, _d; const aId = (0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getFirstLevelIdFromPathname)(rowA.clone().find('a.title').getAttribute('href')); const bId = (0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getFirstLevelIdFromPathname)(rowB.clone().find('a.title').getAttribute('href')); const aTime = (_b = (_a = guides.get(aId)) === null || _a === void 0 ? void 0 : _a.time) !== null && _b !== void 0 ? _b : 9999; const bTime = (_d = (_c = guides.get(bId)) === null || _c === void 0 ? void 0 : _c.time) !== null && _d !== void 0 ? _d : 9999; return aTime - bTime; }) .forEach(row => _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#gamesTable > tbody').append(row)); } _orderByDifficulty() { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); const guides = new _features_guide_GuideStorage__WEBPACK_IMPORTED_MODULE_18__.GuideStorage().indexedByTrophyListId(); this._getAllGameRows() .sort((rowA, rowB) => { var _a, _b, _c, _d; const aId = (0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getFirstLevelIdFromPathname)(rowA.clone().find('a.title').getAttribute('href')); const bId = (0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getFirstLevelIdFromPathname)(rowB.clone().find('a.title').getAttribute('href')); const aDifficulty = (_b = (_a = guides.get(aId)) === null || _a === void 0 ? void 0 : _a.difficulty) !== null && _b !== void 0 ? _b : 11; const bDifficulty = (_d = (_c = guides.get(bId)) === null || _c === void 0 ? void 0 : _c.difficulty) !== null && _d !== void 0 ? _d : 11; return aDifficulty - bDifficulty; }) .forEach(row => _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#gamesTable > tbody').append(row)); } _appendOtherButtons() { const all = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('All') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.other').setText('Other (all)'); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); const allGames = this._getAllGameRows(); allGames.forEach(row => row.show()); this._updateTitleWithGameCount(allGames.length); })); const withUnobtainableTrophies = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('With Unobtainables') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.other').setText('Other (w/ Unobtainables)'); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); const allGames = this._getAllGameRows(); let count = allGames.length; allGames.forEach(row => { row.show(); const containsUnobtainableTrophies = row.clone().find('.marker-unobtainable-trophies').exists(); if (!containsUnobtainableTrophies) { row.hide(); count--; } }); this._updateTitleWithGameCount(count); })); const withoutUnobtainableTrophies = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Without Unobtainables') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.other').setText('Other (w/o Unobtainables)'); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); const allGames = this._getAllGameRows(); let count = allGames.length; allGames.forEach(row => { row.show(); const containsUnobtainableTrophies = row.clone().find('.marker-unobtainable-trophies').exists(); if (containsUnobtainableTrophies) { row.hide(); count--; } }); this._updateTitleWithGameCount(count); })); const sessionAvailable = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Session available') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.other').setText('Other (Session)'); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); const allGames = this._getAllGameRows(); let count = allGames.length; allGames.forEach(row => { row.show(); const hasSessionGoing = row.clone().find('.marker-session').exists(); if (!hasSessionGoing) { row.hide(); count--; } }); this._updateTitleWithGameCount(count); })); const withPlatinum = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('With Platinum') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.other').setText('Other (w/ Platinum)'); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); const allGames = this._getAllGameRows(); let count = allGames.length; allGames.forEach(row => { row.show(); const hasPlatinumIcon = row.clone().find('img.icon-sprite.platinum-18').exists(); if (!hasPlatinumIcon) { row.hide(); count--; } }); this._updateTitleWithGameCount(count); })); const withoutPlatinum = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Without Platinum') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.other').setText('Other (w/o Platinum)'); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#load-more').remove(); const allGames = this._getAllGameRows(); let count = allGames.length; allGames.forEach(row => { row.show(); const hasPlatinumIcon = row.clone().find('img.icon-sprite.platinum-18').exists(); if (hasPlatinumIcon) { row.hide(); count--; } }); this._updateTitleWithGameCount(count); })); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div.row > div.col-xs-8 > div.title.flex.v-align > div.no-shrink') .prepend(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('dropdown', 'buttons') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('dropdown-toggle', 'other') .setAttribute('style', 'background-position: 4px -141px;') .setAttribute('data-toggle', 'dropdown') .setAttribute('href', '') .setText('Other (All)'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('ul') .addClass('dropdown-menu') .setAttribute('role', 'menu') .setAttribute('aria-labelledby', 'dLabel') .append(all, sessionAvailable, withUnobtainableTrophies, withoutUnobtainableTrophies, withPlatinum, withoutPlatinum))); } _appendLoadAllGamesButton() { if (!(0,_util_unsafe__WEBPACK_IMPORTED_MODULE_5__.gamesListCanBeExpanded)()) { return false; } let clicked = false; const loadAllGamesButton = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i') .addClass('fa', 'fa-arrow-circle-down') .setAttribute('aria-hidden', 'true')) .setAttribute('style', 'margin: 0; padding: 6px 8px 8px 8px;') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_5__.tooltip)(el, 'Load all games')) .click((e, el) => { e.preventDefault(); if (clicked) { return; } clicked = true; (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_5__.loadAllGames)(() => loadAllGamesButton.remove()); // NOTE: Need to manually hide tiptip, otherwise it stays visible _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div#tiptip_holder').hide(); el.clone().find('i') .removeClass('fa-arrow-circle-down') .addClass('fa-spinner', 'fa-spin', 'fa-fw'); }); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div.row > div.col-xs-8 > div.title.flex.v-align > div.no-shrink') .prepend(loadAllGamesButton); return true; } _appendRemoveMyGamesButton(shouldApplyLeftMargin) { const leftMargin = shouldApplyLeftMargin ? '5px' : '0'; const diffButton = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i') .addClass('fa', 'fa-eraser') .setAttribute('aria-hidden', 'true')) .setAttribute('style', `margin-left: ${leftMargin}; padding: 6px 8px 8px 8px;`) .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_5__.tooltip)(el, 'Remove my games')) .click((e) => { e.preventDefault(); const playedGames = new _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_11__.GameProgressStorage().indexedById(); const allRows = this._getAllGameRows(); let count = allRows.length; allRows.forEach(row => { const path = row.clone().find('a.title').getAttribute('href'); const id = (0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getFirstLevelIdFromPathname)(path); if (playedGames.has(id)) { row.remove(); count--; } }); this._updateTitleWithGameCount(count); }); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div.row > div.col-xs-8 > div.title.flex.v-align > div.no-shrink') .prepend(diffButton); } _appendOrderByButtons() { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.order') .parent() .find('ul.dropdown-menu') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Completion Time') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.order').setText('Order (Completion Time)'); this._orderGamesByCompletionTime(); })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Rank') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.order').setText('Order (Rank)'); this._orderByRank(); })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Trophies') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.order').setText('Order (Trophies)'); this._orderByNumberOfTrophies(); })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Unearned Trophies') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.order').setText('Order (Unearned Trophies)'); this._orderByNumberOfUnearnedTrophies(); })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Platinum Rate') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.order').setText('Order (Platinum Rate)'); this._orderGamesByPlatinumRate(); })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Completion Rate') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.order').setText('Order (Completion Rate)'); this._orderGamesByCompletionRate(); })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Guide Time') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.order').setText('Order (Guide Time)'); this._orderByTime(); })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .setAttribute('style', 'background: #e0e0e0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Difficulty') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('a.dropdown-toggle.order').setText('Order (Difficulty)'); this._orderByDifficulty(); }))); } _updateTitleWithGameCount(count) { _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#content > div > div.col-xs-8 > div.title > div > h3') .setText(`Games (${count}${(0,_util_unsafe__WEBPACK_IMPORTED_MODULE_5__.gamesListCanBeExpanded)() ? '+' : ''})`) .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_5__.tooltip)(el, 'Number of loaded games in this profile. Use "Load all games" button to load everything or scroll down to load more games.')); } _processRows() { const allGameRows = this._getAllGameRows(); this._updateTitleWithGameCount(allGameRows.length); const unprocessedRows = this._getAllUnprocessedRows(); const scrapedGames = this._scrapeProgress(unprocessedRows); this._enhanceRows(unprocessedRows); // This can be very slow, offloaded to next event loop cycle setTimeout(() => { this._removeGamesFromLists(scrapedGames); }, 0); } _watchGamesList() { const disconnect = (0,_util_observe__WEBPACK_IMPORTED_MODULE_8__.gamesObserve)(() => { disconnect(); this._processRows(); this._watchGamesList(); }); } _processHash() { if (location.hash.startsWith(_util_constants__WEBPACK_IMPORTED_MODULE_17__.HASH_GAME_LISTS)) { this._renderLists(); const hashSearchParams = (0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getSearchParamsFromHash)(); const url = hashSearchParams.get('import'); if (url != null) { (0,_ui_ui_utils__WEBPACK_IMPORTED_MODULE_19__.appendPanel)(new _features_lists_ListPanel__WEBPACK_IMPORTED_MODULE_20__.ListImportPanel(url)); } return; } } _observeHash() { window.addEventListener('hashchange', () => this._processHash()); } async _modifyRarestTrophiesWidget() { if (!this._settingsStorage.get('profileShowOnlyUniqueGamesInRarestTrophies')) { return; } const trophyLogPath = `/${this._username}/log?order=rarity&dir=asc`; this._logger.log('Going to fetch rarest trophies from:', trophyLogPath); try { const doc = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_22__.fetchDocument)(trophyLogPath); const rarest50Trophies = (0,_util_J__WEBPACK_IMPORTED_MODULE_0__.all)('table.zebra tr', {}, doc) .map(e => { const trophyListPath = e.clone().find('a[href^="/trophies/"]').getAttribute('href'); const trophyPath = e.clone().find('a[href^="/trophy/"]').getAttribute('href'); return { trophyListId: (0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getFirstLevelIdFromPathname)(trophyListPath), trophyListPath, trophyListTitle: e.clone().find('img.game').getAttribute('title'), trophyTitle: e.clone().find('a.title').getText(), trophyPath, image: e.clone().find('img.trophy').getAttribute('src'), rarity: e.clone().find('td', { eq: 8 }).find('span.typo-top').getText(), rarityType: e.clone().find('td', { eq: 8 }).find('span.typo-bottom nobr').getText(), trophyIcon: e.clone().find('td', { eq: 9 }).find('img').getAttribute('src'), trophyType: e.clone().find('td', { eq: 9 }).find('img').getAttribute('title') }; }) .sort((a, b) => { const trophyTypeMap = { Platinum: 0, Gold: 1, Silver: 2, Bronze: 3 }; if (a.rarity === b.rarity) { return trophyTypeMap[a.trophyType] - trophyTypeMap[b.trophyType]; } const rarityA = parseInt(a.rarity, 10); const rarityB = parseInt(b.rarity, 10); return rarityA - rarityB; }); const usedGames = new Set(); const rarestUniqueGameTrophies = rarest50Trophies.reduce((prev, current) => { if (!usedGames.has(current.trophyListId) && usedGames.size < 5) { prev.push(current); usedGames.add(current.trophyListId); } return prev; }, []); const header = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('h3', { equalsText: 'Rarest Trophies' }); header.setText('Rarest Unique Trophies'); const target = header .parent().parent().next() .find('table.zebra tbody'); target.empty(); target.append(...rarestUniqueGameTrophies.map(trophy => { return _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('tr') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'width: 1%;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', trophy.trophyPath) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('picture') .addClass('trophy') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('img').setAttribute('src', trophy.image)))), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'padding-left: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('ellipsis') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('small-title') .setAttribute('href', trophy.trophyPath) .setText(trophy.trophyTitle)), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('ellipsis') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', trophy.trophyListPath) .setAttribute('rel', 'nofollow') .setText(trophy.trophyListTitle))), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'width: 1%;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('center') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').addClass('typo-top').setText(trophy.rarity), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').addClass('typo-bottom').append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('nobr').setText(trophy.rarityType)))), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'width: 1%;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('separator', 'left') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('img') .setAttribute('src', trophy.trophyIcon)))); })); } catch (e) { this._logger.warn('Failed to fetch rarest trophies', e); } } // Trophy Log _markTrophyLogWithUnobtainableTrophies() { if (!this._settingsStorage.get('markUnobtainableTrophies')) { return; } const unobtainableTrophies = new _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_15__.UnobtainableTrophiesStorage().get(); (0,_util_J__WEBPACK_IMPORTED_MODULE_0__.all)('table.zebra tr').forEach(row => { const trophyPath = row.clone().find('a.title').getAttribute('href'); const trophyListId = parseInt((0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getFirstLevelIdFromPathname)(trophyPath), 10); const trophyId = parseInt((0,_util_url__WEBPACK_IMPORTED_MODULE_4__.getSecondLevelIdFromPathname)(trophyPath), 10); const unobtainableTrophiesForList = unobtainableTrophies.data.list[trophyListId]; if (unobtainableTrophiesForList == null) { return; } if (unobtainableTrophiesForList.includes(trophyId) || unobtainableTrophiesForList[0] === 0) { row.setCss('backgroundColor', _util_constants__WEBPACK_IMPORTED_MODULE_17__.COLOR_LIGHT_ORANGE); } }); } _switchHoursTo24HourFormat() { if (!this._settingsStorage.get('use24HourTimeFormat')) { return; } (0,_util_date__WEBPACK_IMPORTED_MODULE_9__.switchHoursTo24HourFormat)(); } _addAccurateTrophyNumbersInLog() { const filteredNumberMatch = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#content h3').getText().replace(',', '').match(/^Listing (\d+) Trophies$/); if (filteredNumberMatch == null) { return; } const filteredNumber = parseInt(filteredNumberMatch[1], 10); const highestNumber = parseInt(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('table.zebra tr b').getText().replace('#', '').replace(',', '')); if (filteredNumber === highestNumber) { return; } const currentPageNumberText = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('li a.typo-button.active').exists() ? _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('li a.typo-button.active').getText() : '1'; const currentPage = parseInt(currentPageNumberText, 10); const startingNumber = filteredNumber - ((currentPage - 1) * 50); (0,_util_J__WEBPACK_IMPORTED_MODULE_0__.all)('table.zebra tr').forEach((row, i) => { row.clone().find('b').parent() .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b') .setText('#' + (startingNumber - i).toLocaleString('en-US'))); }); } run() { this._logger.debug('Running'); this._insertMenu(); this._displayPoints(); this._checkDonatorStatus(); if (this._isMe) { this._appendNavigation(); this._observeHash(); this._processHash(); } if (this._section === 'games') { this._appendOtherButtons(); const appendedLoadAllGamesButton = this._appendLoadAllGamesButton(); this._appendOrderByButtons(); if (!this._isMe) { this._appendRemoveMyGamesButton(appendedLoadAllGamesButton); } this._processRows(); this._watchGamesList(); this._modifyRarestTrophiesWidget(); } if (this._section === 'log') { this._markTrophyLogWithUnobtainableTrophies(); this._switchHoursTo24HourFormat(); this._addAccurateTrophyNumbersInLog(); } } } /***/ }), /* 57 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ListTable": () => (/* binding */ ListTable) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _ui_DropdownMenu__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(58); /* harmony import */ var _ui_SearchBox__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(59); /* harmony import */ var _ui_NoSearchResults__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(60); /* harmony import */ var _ListTableTitle__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(61); /* harmony import */ var _ui_MultiDropdownMenu__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(62); /* harmony import */ var _ListTableRow__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(63); /* harmony import */ var _sessions_SessionStorage__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(17); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(12); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(34); /* harmony import */ var _game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(20); /* harmony import */ var _ui_ui_utils__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(39); /* harmony import */ var _util_transform__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(16); /* harmony import */ var _unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(24); /* harmony import */ var _guide_GuideStorage__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(29); /* harmony import */ var _ListRandomGamePanel__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(66); /* harmony import */ var _util_data__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(7); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(13); /* harmony import */ var _ListStorage__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(8); /* harmony import */ var _state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(21); /* harmony import */ var _platforms__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(46); /* harmony import */ var _util_user__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(19); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(25); /* harmony import */ var _util_date__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(53); /* harmony import */ var _MoveCopyPanel__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(67); const orderFunctions = { custom: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => 1 * d, timestamp: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => (a.timestamp - b.timestamp) * d, lastActivity: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => { var _a, _b; const lastActivityA = (_a = progressItemA === null || progressItemA === void 0 ? void 0 : progressItemA.lastActivity) !== null && _a !== void 0 ? _a : 0; const lastActivityB = (_b = progressItemB === null || progressItemB === void 0 ? void 0 : progressItemB.lastActivity) !== null && _b !== void 0 ? _b : 0; return (lastActivityA - lastActivityB) * d; }, completionTime: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => { var _a, _b; const completionTimeStringA = (_a = progressItemA === null || progressItemA === void 0 ? void 0 : progressItemA.completionTimeString) !== null && _a !== void 0 ? _a : ''; const completionTimeStringB = (_b = progressItemB === null || progressItemB === void 0 ? void 0 : progressItemB.completionTimeString) !== null && _b !== void 0 ? _b : ''; const completionTimeA = (0,_util_date__WEBPACK_IMPORTED_MODULE_23__.parseCompletionTime)(completionTimeStringA); const completionTimeB = (0,_util_date__WEBPACK_IMPORTED_MODULE_23__.parseCompletionTime)(completionTimeStringB); return (completionTimeA - completionTimeB) * d; }, alphabetical: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => { const titleA = a.title.toLowerCase(); const titleB = b.title.toLowerCase(); if (titleA < titleB) return -1 * d; if (titleA > titleB) return 1 * d; return 0; }, points: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => (a.points - b.points) * d, trophies: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => { const trophiesA = a.trophies.platinum + a.trophies.gold + a.trophies.silver + a.trophies.bronze; const trophiesB = b.trophies.platinum + b.trophies.gold + b.trophies.silver + b.trophies.bronze; return (trophiesA - trophiesB) * d; }, platinum: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => { var _a, _b, _c, _d; const completionA = (_b = (_a = a.platinumpct) !== null && _a !== void 0 ? _a : a.completepct) !== null && _b !== void 0 ? _b : 0; const completionB = (_d = (_c = b.platinumpct) !== null && _c !== void 0 ? _c : b.completepct) !== null && _d !== void 0 ? _d : 0; return (completionA - completionB) * d; }, full: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => { var _a, _b; const completionA = (_a = a.completepct) !== null && _a !== void 0 ? _a : 0; const completionB = (_b = b.completepct) !== null && _b !== void 0 ? _b : 0; return (completionA - completionB) * d; }, progress: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => { var _a, _b; const progressA = (_a = progressItemA === null || progressItemA === void 0 ? void 0 : progressItemA.progress) !== null && _a !== void 0 ? _a : 0; const progressB = (_b = progressItemB === null || progressItemB === void 0 ? void 0 : progressItemB.progress) !== null && _b !== void 0 ? _b : 0; return (progressA - progressB) * d; }, difficulty: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => { var _a, _b; const difficultyA = (_a = guideItemA === null || guideItemA === void 0 ? void 0 : guideItemA.difficulty) !== null && _a !== void 0 ? _a : 0; const difficultyB = (_b = guideItemB === null || guideItemB === void 0 ? void 0 : guideItemB.difficulty) !== null && _b !== void 0 ? _b : 0; return (difficultyA - difficultyB) * d; }, guideTime: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => { var _a, _b; const timeA = (_a = guideItemA === null || guideItemA === void 0 ? void 0 : guideItemA.time) !== null && _a !== void 0 ? _a : 0; const timeB = (_b = guideItemB === null || guideItemB === void 0 ? void 0 : guideItemB.time) !== null && _b !== void 0 ? _b : 0; return (timeA - timeB) * d; }, note: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => { var _a, _b; const noteA = (_a = a.note) !== null && _a !== void 0 ? _a : ''; const noteB = (_b = b.note) !== null && _b !== void 0 ? _b : ''; return noteA.localeCompare(noteB) * d; }, /** * @deprecated */ time: (a, progressItemA, guideItemA, b, progressItemB, guideItemB, d) => { var _a, _b; const timeA = (_a = guideItemA === null || guideItemA === void 0 ? void 0 : guideItemA.time) !== null && _a !== void 0 ? _a : 0; const timeB = (_b = guideItemB === null || guideItemB === void 0 ? void 0 : guideItemB.time) !== null && _b !== void 0 ? _b : 0; return (timeA - timeB) * d; }, }; const PSPLUS_TAG_VALUE = '__psnpp__psplus__tag__'; const GUIDE_AVAILABLE_TAG_VALUE = '__psnpp__guide_available__tag__'; const SESSION_AVAILABLE_TAG_VALUE = '__psnpp__session_available__tag__'; const UNOBTAINABLE_TROPHIES_TAG_VALUE = '__psnpp__unobtainable_trophies__tag__'; const ONLINE_TROPHIES_TAG_VALUE = '__psnpp__online_trophies__tag__'; const BUGGY_TROPHIES_TAG_VALUE = '__psnpp__buggy_trophies__tag__'; const HAS_NOT_TAG_VALUE = '__psnpp__has_note__tag__'; class ListTable extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(list, otherLists, onRowDeleted, onRowSorted, onRowMovedToIndex, onEditNote, onPsPlusToggled, onTagsChanged, listTableSettings) { super('div'); this._searchValue = ''; this._orderBy = 'custom'; this._platform = 'all'; this._completion = 'all'; this._direction = 'ascending'; this._selectedTags = []; this._list = list; this._games = (0,_util_transform__WEBPACK_IMPORTED_MODULE_12__.cloneDeep)(list.games); this._gamesFiltered = (0,_util_transform__WEBPACK_IMPORTED_MODULE_12__.cloneDeep)(list.games); this._tags = list.tags; this._otherLists = otherLists; this._orderBy = list.orderBy == null ? 'custom' : list.orderBy; this._direction = list.direction == null ? 'descending' : list.direction; this._onRowDeleted = onRowDeleted; this._onRowSorted = onRowSorted; this._onRowMovedToIndex = onRowMovedToIndex; this._onEditNote = onEditNote; this._onPsPlusToggled = onPsPlusToggled; this._onTagsChanged = onTagsChanged; this._listTableSettings = listTableSettings; this._listContainer = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('tbody'); this._noSearchResults = new _ui_NoSearchResults__WEBPACK_IMPORTED_MODULE_3__.NoSearchResults('No games found').hide(); this._listTableTitle = new _ListTableTitle__WEBPACK_IMPORTED_MODULE_4__.ListTableTitle([], new Map()); this._indexedSessions = new _sessions_SessionStorage__WEBPACK_IMPORTED_MODULE_7__.SessionStorage().indexedByCdnCode(); this._indexedGameProgress = new _game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_10__.GameProgressStorage().indexedById(); this._indexedGuides = new _guide_GuideStorage__WEBPACK_IMPORTED_MODULE_14__.GuideStorage().indexedByTrophyListId(); this._unobtainableTrophies = new _unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_13__.UnobtainableTrophiesStorage().get().data; this._build(); } _getExportDropdown() { return new _ui_DropdownMenu__WEBPACK_IMPORTED_MODULE_1__.DropdownMenu({ mainButton: _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i') .addClass('fa', 'fa-arrow-circle-up') .setAttribute('aria-hidden', 'true') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_9__.tooltip)(el, 'Export')), mainButtonIconClass: 'rarity', mainButtonStyle: 'background-image: none; padding-left: 10px; margin-left: 5px;', dropdownMenuClass: 'right', options: [ { text: 'JSON (can be imported)', value: 'json', selected: false }, { text: 'CSV (export only)', value: 'csv', selected: false }, { text: 'Copy as image', value: 'copypng', selected: false }, { text: 'Save as image', value: 'savepng', selected: false }, { text: 'Copy BBCode', value: 'bbcode', selected: false } ], onSelected: async (type) => { try { const normalizedListName = this._list.name .toLowerCase() .replace(/[^a-zA-Z0-9_\- ]{1}/g, '') .replace(/ /g, '_'); if (type === 'json') { (0,_util_data__WEBPACK_IMPORTED_MODULE_16__.downloadFile)(JSON.stringify(this._list, null, 2), `psnpp-${normalizedListName}.json`, 'application/json'); } else if (type === 'csv') { await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_17__.loadScriptTag)(_util_constants__WEBPACK_IMPORTED_MODULE_22__.EXTERNAL_SCRIPT_URLS.PAPAPARSE); const toExport = this._gamesFiltered .map(listItem => ({ row: listItem, profile: this._indexedGameProgress.get(listItem.id), guide: this._indexedGuides.get(listItem.id) })) .map(x => (0,_util_transform__WEBPACK_IMPORTED_MODULE_12__.flatten)(x)); if (toExport.length === 0) { return; } const sortedExport = (0,_util_transform__WEBPACK_IMPORTED_MODULE_12__.cloneDeep)(toExport) .sort((a, b) => Object.keys(b).length - Object.keys(a).length); const columns = Object.keys(sortedExport[0]); const csv = Papa.unparse(toExport, { columns }); (0,_util_data__WEBPACK_IMPORTED_MODULE_16__.downloadFile)(csv, `psnpp-${normalizedListName}.csv`, 'text/csv'); } else if (type === 'bbcode') { const html = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div').append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText(this._list.name + ' by ' + (0,_util_user__WEBPACK_IMPORTED_MODULE_21__.getPsnId)())), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('table') .setAttribute('border', '1') .setAttribute('cellspacing', '10') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('tr') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'padding: 10px;') .setAttribute('align', 'center') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText('Icon')), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'padding: 10px;') .setAttribute('align', 'center') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText('Game')), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'padding: 10px;') .setAttribute('align', 'center') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText('Platform')), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'padding: 10px;') .setAttribute('align', 'center') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText('Progress')), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'padding: 10px;') .setAttribute('align', 'center') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText('Rarities')), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'padding: 10px;') .setAttribute('align', 'center') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText('Completion')))) .append(...this._gamesFiltered.map(item => { const hasPlatinum = item.trophies.platinum > 0; const game = this._indexedGameProgress.get(item.id); const earnedTrophies = (game === null || game === void 0 ? void 0 : game.trophies) == null ? 0 : game.trophies.bronze + game.trophies.silver + game.trophies.gold + game.trophies.platinum; const platinumPct = item.platinumpct == null ? (hasPlatinum ? '🏆 0.00%' : '🏆 -') : '🏆 ' + item.platinumpct + '%'; const completePct = item.completepct == null ? '💯 -' : '💯 ' + item.completepct + '%'; return _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('tr') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('width', '100') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('img').setAttribute('src', item.image)), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'padding: 10px;') .setAttribute('align', 'center') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a').setAttribute('href', item.url + '/' + (0,_util_user__WEBPACK_IMPORTED_MODULE_21__.getPsnId)()).setText(' ' + item.title + ' ')), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'padding: 10px;') .setAttribute('align', 'center') .setText(Object.values((0,_platforms__WEBPACK_IMPORTED_MODULE_20__.mapPlatforms)(item.platforms)).join(', ')), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'padding: 10px;') .setAttribute('align', 'center') .setText(earnedTrophies + '/' + (item.trophies.bronze + item.trophies.silver + item.trophies.gold + item.trophies.platinum) + ' - ' + (game == null ? '0' : game.progress) + '%'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'padding: 10px;') .setAttribute('align', 'center') .setText(platinumPct + ' / ' + completePct), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'padding: 10px;') .setAttribute('align', 'center') .setText(game == null || game.progress === 0 ? '🟥' : game.progress !== 100 ? '🟦' : '🟩')); }))), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div').setText('🟥 = not started • 🟦 = started • 🟩 = complete'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div').append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i').setText('Generated with PSNP+'))) .getOuterHTML(); const clipboardItem = new ClipboardItem({ 'text/html': new Blob([html], { type: 'text/html' }), 'text/plain': new Blob([html], { type: 'text/plain' }) }); await navigator.clipboard.write([clipboardItem]); alert('BBCode was copied to clipboard. You can now paste it into a forum post.'); } else if (type === 'copypng') { await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_17__.loadScriptTag)(_util_constants__WEBPACK_IMPORTED_MODULE_22__.EXTERNAL_SCRIPT_URLS.HTML2CANVAS); const tableElement = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#content').setAttribute('style', 'min-height: 0;').get(); const canvas = await html2canvas(tableElement, { allowTaint: true, useCORS: true }); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore canvas.toBlob(async (blob) => { await navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]); alert('Image was copied to clipboard.'); }); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#content').removeAttribute('style'); } else if (type === 'savepng') { await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_17__.loadScriptTag)(_util_constants__WEBPACK_IMPORTED_MODULE_22__.EXTERNAL_SCRIPT_URLS.HTML2CANVAS); const tableElement = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#content').setAttribute('style', 'min-height: 0;').get(); const canvas = await html2canvas(tableElement, { allowTaint: true, useCORS: true }); const image = canvas.toDataURL('image/png', 1.0); (0,_util_data__WEBPACK_IMPORTED_MODULE_16__.downloadBlob)(image, `psnpp-${normalizedListName}.png`); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('#content').removeAttribute('style'); } } catch (e) { const typedE = e; if (typedE.message === 'ClipboardItem is not defined') { alert('Access to clipboard is forbidden.\n\nIf you are using Firefox, please enable "dom.events.asyncClipboard.clipboardItem" in "about:config".'); } else { console.log('Export failed:', typedE); alert('Export failed: ' + typedE.message); } } } }); } _getCompletionDropdown() { return new _ui_DropdownMenu__WEBPACK_IMPORTED_MODULE_1__.DropdownMenu({ mainButton: 'Completion', mainButtonIconClass: 'completion', options: [ { text: '100%', value: 'completion100percent', selected: false }, { text: 'Not 100%', value: 'completionNot100percent', selected: false }, { text: 'Not 100% or Platinum', value: 'completionNot100percentOrPlatinum', selected: false }, { text: 'Platinum', value: 'completionPlatinum', selected: false }, { text: 'Platinum, not 100%', value: 'completionPlatinumNot100%', selected: false }, { text: 'All', value: 'all', selected: true }, ], onSelected: (completion) => { this._completion = completion; this._renderList(); } }); } _getPlatformsDropdown() { return new _ui_DropdownMenu__WEBPACK_IMPORTED_MODULE_1__.DropdownMenu({ mainButton: 'Platform', mainButtonIconClass: 'platform', options: [ { text: 'PlayStation 5', value: 'ps5', selected: false }, { text: 'PlayStation 4', value: 'ps4', selected: false }, { text: 'PlayStation 3', value: 'ps3', selected: false }, { text: 'PlayStation Vita', value: 'psvita', selected: false }, { text: 'PlayStation VR', value: 'psvr', selected: false }, { text: 'All', value: 'all', selected: true }, ], onSelected: (platform) => { this._platform = platform; this._renderList(); } }); } _getOrderDropdown() { return new _ui_DropdownMenu__WEBPACK_IMPORTED_MODULE_1__.DropdownMenu({ mainButton: 'Order', mainButtonIconClass: 'order', options: [ { text: 'Custom', value: 'custom', selected: this._orderBy === 'custom' }, { text: 'Date Added', value: 'timestamp', selected: this._orderBy === 'timestamp' }, { text: 'Last Activity', value: 'lastActivity', selected: this._orderBy === 'lastActivity' }, { text: 'Completion Time', value: 'completionTime', selected: this._orderBy === 'completionTime' }, { text: 'Alphabetical', value: 'alphabetical', selected: this._orderBy === 'alphabetical' }, { text: 'Points', value: 'points', selected: this._orderBy === 'points' }, { text: 'Trophies', value: 'trophies', selected: this._orderBy === 'trophies' }, { text: 'Platinum Rate', value: 'platinum', selected: this._orderBy === 'platinum' }, { text: '100% Rate', value: 'full', selected: this._orderBy === 'full' }, { text: 'Progress', value: 'progress', selected: this._orderBy === 'progress' }, { text: 'Difficulty', value: 'difficulty', selected: this._orderBy === 'difficulty' }, { text: 'Guide Time', value: 'guideTime', selected: this._orderBy === 'guideTime' || this._orderBy === 'time' }, { text: 'Note', value: 'note', selected: this._orderBy === 'note' } ], onSelected: (order) => { this._listTableSettings.isSortAllowed = (order === 'custom'); this._orderBy = order; this._renderList(); } }); } _getDirectionDropdown() { return new _ui_DropdownMenu__WEBPACK_IMPORTED_MODULE_1__.DropdownMenu({ mainButton: 'Direction', mainButtonIconClass: 'direction', options: [ { text: 'Ascending', value: 'ascending', selected: this._direction === 'ascending' }, { text: 'Descending', value: 'descending', selected: this._direction === 'descending' }, ], onSelected: (direction) => { this._direction = direction; this._renderList(); } }); } _getTagsDropdown() { const options = [ { text: 'PS+', value: PSPLUS_TAG_VALUE, selected: false }, { text: 'Guide Available', value: GUIDE_AVAILABLE_TAG_VALUE, selected: false }, { text: 'Session Available', value: SESSION_AVAILABLE_TAG_VALUE, selected: false }, { text: 'Unobtainable Trophies', value: UNOBTAINABLE_TROPHIES_TAG_VALUE, selected: false }, { text: 'Online Trophies', value: ONLINE_TROPHIES_TAG_VALUE, selected: false }, { text: 'Buggy Trophies', value: BUGGY_TROPHIES_TAG_VALUE, selected: false }, { text: 'Has Note', value: HAS_NOT_TAG_VALUE, selected: false } ]; options.push(...this._tags.map(t => ({ text: t, value: t, selected: false }))); return new _ui_MultiDropdownMenu__WEBPACK_IMPORTED_MODULE_5__.MultiDropdownMenu({ mainButton: 'Tags', mainButtonIconClass: 'rarity', options, onSelectionChanged: (tags) => { this._selectedTags = tags; this._renderList(); } }); } _build() { this .addClass('col-xs-12') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('title', 'flex', 'v-align') .append(this._listTableTitle) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('no-shrink') .append(this._getExportDropdown(), this._listTableSettings.showUrlRefreshButton ? _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i') .addClass('fa', 'fa-refresh') .setAttribute('aria-hidden', 'true')) .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_9__.tooltip)(el, 'Reload from URL')) .click(async (e) => { try { e.preventDefault(); const continueReload = confirm('You are about to reload data in this list from a remote URL. All manual changes done by you will be lost.\n\nContinue?'); if (!continueReload) { return; } const url = this._list.url; const listId = this._list.id; const newList = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_17__.gmFetchJson)(url); newList.url = url; const listStorage = new _ListStorage__WEBPACK_IMPORTED_MODULE_18__.ListStorage(); const newListId = listStorage.createList(newList); listStorage.remove(listId); new _state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_19__.ScriptStateStorage().set('lastActiveGameList', newListId); location.reload(); } catch (e) { const typedE = e; alert('Failed to reload list! Error message: ' + typedE.message); } }) : null, this._games.length >= 2 ? _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i') .addClass('fa', 'fa-random') .setAttribute('aria-hidden', 'true')) .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_9__.tooltip)(el, 'Random game')) .click((e) => { e.preventDefault(); (0,_ui_ui_utils__WEBPACK_IMPORTED_MODULE_11__.appendPanel)(new _ListRandomGamePanel__WEBPACK_IMPORTED_MODULE_15__.ListRandomGamePanel(this._gamesFiltered)); }) : null, this._getPlatformsDropdown(), this._getOrderDropdown(), this._getDirectionDropdown(), this._getCompletionDropdown(), this._getTagsDropdown()))) .append(new _ui_SearchBox__WEBPACK_IMPORTED_MODULE_2__.SearchBox('Search your games', value => { this._searchValue = value; this._renderList(); })) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('box', 'no-top-border') .append(this._noSearchResults) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('table') .addClass('zebra', 'list-table') .append(this._listContainer))); this._renderList(); } _renderList() { const searchValue = this._searchValue; const orderBy = this._orderBy; const platform = this._platform; const completion = this._completion; const tags = this._selectedTags; const directionCoeficient = this._direction === 'ascending' ? 1 : -1; let listItems = this._games.reverse(); const totalNumberOfListItems = listItems.length; if (searchValue !== '') { listItems = listItems.filter((x) => x.title.toLowerCase().indexOf(searchValue.toLowerCase()) > -1); } if (platform !== 'all') { listItems = listItems.filter((x) => x.platforms[platform] === true); } if (tags.length > 0) { listItems = listItems.filter((x) => { const guide = this._indexedGuides.get(x.id); if (tags.indexOf(PSPLUS_TAG_VALUE) > -1 && x.psplus === true) { return true; } if (tags.indexOf(GUIDE_AVAILABLE_TAG_VALUE) > -1 && typeof x.guideurl === 'string') { return true; } if (tags.indexOf(SESSION_AVAILABLE_TAG_VALUE) > -1) { const sessions = this._indexedSessions.get((0,_util_url__WEBPACK_IMPORTED_MODULE_8__.getCdnCodeFromImageUrl)(x.image)); if (sessions != null) { return true; } } if (tags.indexOf(UNOBTAINABLE_TROPHIES_TAG_VALUE) > -1) { const unobtainableTrophies = this._unobtainableTrophies.list[x.id]; if (unobtainableTrophies != null) { return true; } } if (tags.indexOf(ONLINE_TROPHIES_TAG_VALUE) > -1) { return guide != null && guide.online === true; } if (tags.indexOf(BUGGY_TROPHIES_TAG_VALUE) > -1) { return guide != null && guide.buggy === true; } if (tags.indexOf(HAS_NOT_TAG_VALUE) > -1) { return x.note != null && x.note.length > 0; } if (typeof x.tags === 'undefined' || x.tags.length === 0) { return false; } // NOTE: Intersection length > 0 return tags.some((t) => { const gameTags = typeof x.tags === 'undefined' ? [] : x.tags; return gameTags.indexOf(t) > -1; }); }); } if (orderBy !== 'custom') { listItems.sort((a, b) => { const progressA = this._indexedGameProgress.get(a.id); const progressB = this._indexedGameProgress.get(b.id); const guideA = this._indexedGuides.get(a.id); const guideB = this._indexedGuides.get(b.id); return orderFunctions[orderBy](a, progressA, guideA, b, progressB, guideB, directionCoeficient); }); } if (completion !== 'all') { switch (completion) { case 'completion100percent': listItems = listItems.filter(item => { var _a; return ((_a = this._indexedGameProgress.get(item.id)) === null || _a === void 0 ? void 0 : _a.progress) === 100; }); break; case 'completionNot100percent': listItems = listItems.filter(item => { var _a; return ((_a = this._indexedGameProgress.get(item.id)) === null || _a === void 0 ? void 0 : _a.progress) !== 100; }); break; case 'completionNot100percentOrPlatinum': listItems = listItems.filter(item => { var _a; const gameProgressItem = this._indexedGameProgress.get(item.id); if (gameProgressItem == null) { return true; } return gameProgressItem.progress !== 100 && ((_a = gameProgressItem.trophies) === null || _a === void 0 ? void 0 : _a.platinum) === 0; }); break; case 'completionPlatinum': listItems = listItems.filter(item => { var _a, _b; return ((_b = (_a = this._indexedGameProgress.get(item.id)) === null || _a === void 0 ? void 0 : _a.trophies) === null || _b === void 0 ? void 0 : _b.platinum) === 1; }); break; case 'completionPlatinumNot100%': listItems = listItems.filter(item => { var _a; const gameProgressItem = this._indexedGameProgress.get(item.id); if (gameProgressItem == null) { return false; } return gameProgressItem.progress !== 100 && ((_a = gameProgressItem.trophies) === null || _a === void 0 ? void 0 : _a.platinum) === 1; }); break; default: break; } } this._gamesFiltered = listItems; this._listContainer.empty(); this._listTableTitle.update(listItems, this._indexedGameProgress); if (listItems.length === 0) { this._noSearchResults.setTitleText(`No games found (${totalNumberOfListItems} hidden)`); this._noSearchResults.show(); return; } else { this._noSearchResults.hide(); } listItems .map(item => { const sessions = this._indexedSessions.get((0,_util_url__WEBPACK_IMPORTED_MODULE_8__.getCdnCodeFromImageUrl)(item.image)); const game = this._indexedGameProgress.get(item.id); const guide = this._indexedGuides.get(item.id); const unobtainableTrophies = this._unobtainableTrophies.list[item.id]; return new _ListTableRow__WEBPACK_IMPORTED_MODULE_6__.ListRow(item, this._tags, sessions, game, guide, unobtainableTrophies, this._otherLists, async (movedCopiedRow, listItem, action) => { const shouldRemoveRow = await (0,_ui_ui_utils__WEBPACK_IMPORTED_MODULE_11__.appendPanelWait)(new _MoveCopyPanel__WEBPACK_IMPORTED_MODULE_24__.MoveCopyPanel(listItem, action, this._list)); if (shouldRemoveRow) { const itemIndex = this._games.findIndex((x) => x.id === listItem.id); this._games.splice(itemIndex, 1); movedCopiedRow.remove(); this._listTableTitle.update(this._games, this._indexedGameProgress); } }, (deletedRow, listItem) => { const result = confirm(`Are you sure you want to remove ${listItem.title}?`); if (!result) { return; } this._onRowDeleted(listItem); const itemIndex = this._games.findIndex((x) => x.id === listItem.id); this._games.splice(itemIndex, 1); deletedRow.remove(); this._listTableTitle.update(this._games, this._indexedGameProgress); }, (movedRow, listItem) => { // NOTE: Target indexes are switched here because games are rendered from bottom to top // 0 - bottom, length-1 - top this._onRowMovedToIndex(listItem, this._games.length - 1); }, (movedRow, listItem) => { // Same applies here this._onRowMovedToIndex(listItem, 0); }, this._onEditNote, this._onPsPlusToggled, this._onTagsChanged, this._listTableSettings); }) .forEach((el) => { this._listContainer.append(el); }); if (this._listTableSettings.isSortAllowed) { this.apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_9__.sortable)(el, (e, ui) => { const oldIndex = parseInt(ui.item.data('previndex'), 10); const newIndex = ui.item.index(); this._games.reverse(); (0,_util_transform__WEBPACK_IMPORTED_MODULE_12__.move)(this._games, oldIndex, newIndex); this._games.reverse(); this._onRowSorted(oldIndex, newIndex); })); } } } /***/ }), /* 58 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "DropdownMenu": () => (/* binding */ DropdownMenu) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); class DropdownMenu extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(dropdownOptions) { super('div'); this._build(dropdownOptions); } _getMainButtonText(mainText, menuItemText) { return `${mainText} (${menuItemText})`; } _build(dropdownOptions) { const mainButton = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('dropdown-toggle', dropdownOptions.mainButtonIconClass) .condition(typeof dropdownOptions.mainButtonStyle !== 'undefined', (el) => el.setAttribute('style', dropdownOptions.mainButtonStyle)) .setAttribute('data-toggle', 'dropdown') .setAttribute('href', ''); if (typeof dropdownOptions.mainButton === 'string') { const optionWithText = dropdownOptions.options.find(option => option !== 'divider' && option.selected); if (optionWithText != null && optionWithText !== 'divider') { mainButton.setText(this._getMainButtonText(dropdownOptions.mainButton, optionWithText.text)); } } else { mainButton.append(dropdownOptions.mainButton); } const optionsContainer = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('ul') .addClass('dropdown-menu') .setAttribute('role', 'menu') .setAttribute('aria-labelledby', 'dLabel'); if (dropdownOptions.dropdownMenuClass != null) { optionsContainer.addClass(dropdownOptions.dropdownMenuClass); } const options = dropdownOptions.options.map((option) => { if (option === 'divider') { return _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li').addClass('divider'); } return _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText(option.text) .click((e) => { e.preventDefault(); if (typeof dropdownOptions.mainButton === 'string') { mainButton.setText(this._getMainButtonText(dropdownOptions.mainButton, option.text)); } dropdownOptions.onSelected(option.value, option.context); })); }); optionsContainer.append(...options); return this .addClass('dropdown', 'buttons') .append(mainButton) .append(optionsContainer); } } /***/ }), /* 59 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "SearchBox": () => (/* binding */ SearchBox) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); class SearchBox extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(placeholder, onChange) { super('div'); this._searchValue = ''; this._onChange = onChange; this._build(placeholder); } _build(placeholder) { const form = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('form') .setAttribute('style', 'margin: 0 5px 5px;'); const label = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('label').addClass('input', 'focus'); const icon = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i').addClass('icon-prepend', 'fa-search'); const input = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('input') .setAttribute('type', 'text') .setAttribute('placeholder', placeholder) .keyup((_, el) => { const searchValue = el.getValue(); if (this._searchValue === searchValue) { return; } this._searchValue = searchValue; this._onChange(searchValue); }); label.append(icon, input); form.append(label); return this .addClass('box') .setAttribute('style', 'padding-top: 5px; border-bottom-width: 1px;') .append(form); } } /***/ }), /* 60 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "NoSearchResults": () => (/* binding */ NoSearchResults) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); class NoSearchResults extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(description) { super('table'); this._titleElement = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('h2') .addClass('center') .setText(description); this._build(); } _build() { const tbody = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('tbody'); const tr = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('tr'); const td = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td').setAttribute('style', 'padding: 20px;'); td.append(this._titleElement); tr.append(td); tbody.append(tr); return this .addClass('zebra', 'list-table') .append(tbody); } setTitleText(text) { this._titleElement.setText(text); } } /***/ }), /* 61 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ListTableTitle": () => (/* binding */ ListTableTitle) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); class ListTableTitle extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(listItems, games) { super('div'); this._listItems = listItems; this._games = games; this._build(); } _getNumbers() { const gameProgressItems = this._listItems .filter(x => { const gameProgressItem = this._games.get(x.id); return gameProgressItem != null && gameProgressItem.trophies != null; }) .map(x => this._games.get(x.id)); return { numberOfItems: this._listItems.length, earnedTrophies: gameProgressItems.reduce((acc, { trophies: { platinum, gold, silver, bronze } }) => acc + platinum + gold + silver + bronze, 0), totalTrophies: this._listItems.reduce((acc, { trophies: { platinum, gold, silver, bronze } }) => acc + platinum + gold + silver + bronze, 0), totalPoints: this._listItems.reduce((acc, current) => acc + current.points, 0) }; } _getText() { const { numberOfItems, earnedTrophies, totalTrophies, totalPoints } = this._getNumbers(); const plural = numberOfItems === 1 ? '' : 's'; const earnedText = earnedTrophies > 0 ? `${earnedTrophies.toLocaleString('en-US')} of ` : ''; return [ `${numberOfItems} Game${plural} `, _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ` ${earnedText}${totalTrophies.toLocaleString('en-US')} Trophies `, _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ` ${totalPoints.toLocaleString('en-US')} Points` ]; } _build() { const h3 = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('h3') .append(...this._getText()); this.addClass('grow').append(h3); } update(listItems, games) { this._listItems = listItems; this._games = games; const text = this._getText(); this.clone().find('h3').empty().append(...text); } } /***/ }), /* 62 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "MultiDropdownMenu": () => (/* binding */ MultiDropdownMenu) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); class MultiDropdownMenu extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(multiDropdownOptions) { super('div'); this._options = multiDropdownOptions; this._build(); } _getOptionsText(option) { const prefix = option.selected ? '✓ ' : ''; return `${prefix} ${option.text}`; } _build() { const mainButton = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('dropdown-toggle', this._options.mainButtonIconClass) .setAttribute('data-toggle', 'dropdown') .setAttribute('href', ''); if (typeof this._options.mainButton === 'string') { mainButton.setText(this._options.mainButton); } else { mainButton.append(this._options.mainButton); } const optionsContainer = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('ul') .addClass('dropdown-menu') .setAttribute('role', 'menu') .setAttribute('aria-labelledby', 'dLabel'); if (this._options.dropdownMenuClass != null) { optionsContainer.addClass(this._options.dropdownMenuClass); } const optionElements = this._options.options.map((option) => { return _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText(this._getOptionsText(option)) .click((e, el) => { e.preventDefault(); e.stopImmediatePropagation(); option.selected = !option.selected; el.setText(this._getOptionsText(option)); this._options.onSelectionChanged(this._options.options.filter(o => o.selected).map(o => o.value)); })); }); optionsContainer.append(...optionElements); optionsContainer.append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li').addClass('divider'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li').append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Select all') .click((e) => { e.preventDefault(); this._options.options.forEach((o, index) => { o.selected = true; optionElements[index].clone().find('a').setText(this._getOptionsText(o)); }); this._options.onSelectionChanged(this._options.options.map(o => o.value)); })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('li').append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .setText('Deselect all') .click((e) => { e.preventDefault(); this._options.options.forEach((o, index) => { o.selected = false; optionElements[index].clone().find('a').setText(this._getOptionsText(o)); }); this._options.onSelectionChanged([]); }))); return this .addClass('dropdown', 'buttons') .append(mainButton) .append(optionsContainer); } } /***/ }), /* 63 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ListRow": () => (/* binding */ ListRow) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _util_date__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(53); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(34); /* harmony import */ var _ui_MultiDropdownMenu__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(62); /* harmony import */ var _regions__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(14); /* harmony import */ var _ui_DropdownMenu__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(58); /* harmony import */ var _platforms__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(46); /* harmony import */ var _unobtainables_unobtainables_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(64); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(12); /* harmony import */ var _util_linkify__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(65); class ListImage extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(url, title, image, resizePS5Icons) { super('td'); this._build(url, title, image, resizePS5Icons); } _build(url, title, image, resizePS5Icons) { const pathname = new URL(url).pathname; this .setAttribute('style', 'width: 1%;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', pathname) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('picture') .setCss('textAlign', 'center') .addClass('game') .setAttribute('alt', title) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('img') .setAttribute('src', image) .condition(resizePS5Icons, (el) => { el.setCss('maxHeight', '56px') .setCss('maxWidth', '100px') .setCss('height', 'auto') .setCss('width', 'auto'); })))); } } class ListDescription extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(listItem, pathname, title, region, guideurl, totalTrophies, totalPoints, note, addedOn, game, activeSessions, unobtainableTrophies, guide, onEditNote) { super('td'); this._noteVisible = false; this._noteDiv = null; this._listItem = listItem; this._noteText = note !== null && note !== void 0 ? note : ''; this._onEditNote = onEditNote; this._build(pathname, title, region, guideurl, totalTrophies, totalPoints, addedOn, game, activeSessions, unobtainableTrophies, guide); } _createNoteDiv() { this._noteDiv = this._noteText.length > 0 ? _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .setAttribute('style', 'white-space: pre-wrap; font-size: 1.2rem; margin-top: 5px; border: 1px solid #e3e3e6; border-radius: 5px; padding: 5px; border-left: 3px solid #9b9ba5;') .append(...(0,_util_linkify__WEBPACK_IMPORTED_MODULE_9__.linkifyText)(this._noteText)) : null; } _build(pathname, title, region, guideurl, totalTrophies, totalPoints, addedOn, game, activeSessions, unobtainableTrophies, guide) { const additional = []; if (typeof region !== 'undefined') { additional.push(' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .setText(region) .apply((el) => { const tooltipText = (0,_regions__WEBPACK_IMPORTED_MODULE_4__.getDescritionFromCode)(region); if (typeof tooltipText !== 'undefined') { (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_2__.tooltip)(el, tooltipText); } })); } if (typeof guideurl !== 'undefined') { const guidePathname = new URL(guideurl).pathname; additional.push(' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', guidePathname) .setAttribute('style', 'color:#646464;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i') .addClass('fa', 'fa-book') .setAttribute('aria-hidden', 'true') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_2__.tooltip)(el, 'Trophy Guide')))); } if (activeSessions != null) { additional.push(' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', pathname.replace('trophies', 'sessions')) .setAttribute('style', 'color:#646464;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i') .addClass('fa', 'fa-users') .setAttribute('aria-hidden', 'true') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_2__.tooltip)(el, activeSessions.length + ' Active Gaming Session(s)')))); } if (unobtainableTrophies != null) { additional.push(' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i') .addClass('fa', 'fa-exclamation-circle') .setAttribute('aria-hidden', 'true') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_2__.tooltip)(el, (0,_unobtainables_unobtainables_utils__WEBPACK_IMPORTED_MODULE_7__.getUnobtainableTrophiesDescription)(unobtainableTrophies)))); } const titleElement = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('ellipsis') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('title') .setAttribute('href', pathname) .setText(title), ...additional)); const trophiesAndPoints = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('small-info') .setAttribute('style', 'margin-top: 4px;') .condition(game != null, el => { if (game == null || game.trophies == null) { return; } const earnedCount = game.trophies.bronze + game.trophies.silver + game.trophies.gold + game.trophies.platinum; if (earnedCount === 0) { return; } if (earnedCount === totalTrophies) { el.append('All '); } else { el.append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText(earnedCount.toString()), ' of '); } }) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText(totalTrophies.toString()), ' Trophies ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText(totalPoints.toLocaleString('en-US')), ' Points'); if (guide != null) { trophiesAndPoints.append(' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', `${(0,_util_url__WEBPACK_IMPORTED_MODULE_8__.getWebsiteUrl)()}/guide/${guide.guideId}`) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .setText(`${guide.difficulty}/10`) .setAttribute('style', `${guide.difficultyStyle}; font-size: 10px; color: white; padding: 1px 2px; border-radius: 2px;`), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .setText(`${guide.playthroughs}x`) .setAttribute('style', `${guide.playthroughsStyle}; font-size: 10px; color: white; padding: 1px 2px; border-radius: 2px;`), ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .setText(`${guide.time}h`) .setAttribute('style', `${guide.timeStyle}; font-size: 10px; color: white; padding: 1px 2px; border-radius: 2px;`)) .condition(guide.online === true, el => { el.append(' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .setText('Online') .setAttribute('style', 'background: #3a87ad; font-size: 10px; color: white; padding: 1px 2px; border-radius: 2px;')); }) .condition(guide.buggy === true, el => { el.append(' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .setText('Buggy') .setAttribute('style', 'background: #b94a48; font-size: 10px; color: white; padding: 1px 2px; border-radius: 2px;')); })); } const date = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('small-info') .setAttribute('style', 'margin-top: 4px;') .append('Added on', ` ${addedOn.day}`, _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('sup').setText(addedOn.suffix), ` ${addedOn.monthName} ${addedOn.year}`) .condition((game === null || game === void 0 ? void 0 : game.lastActivity) != null, (el) => { const lastActivity = (0,_util_date__WEBPACK_IMPORTED_MODULE_1__.getPrettyDate)(game === null || game === void 0 ? void 0 : game.lastActivity); el .append(' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' ', 'Last activity', ` ${lastActivity.day}`, _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('sup').setText(lastActivity.suffix), ` ${lastActivity.monthName} ${lastActivity.year}`); }) .condition((game === null || game === void 0 ? void 0 : game.completionTimeString) != null, (el) => { el .append(' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' ', ...(0,_util_date__WEBPACK_IMPORTED_MODULE_1__.formatCompletionTimeString)(game === null || game === void 0 ? void 0 : game.completionTimeString)); }); this._createNoteDiv(); this .setAttribute('style', 'width: 100%;') .append(titleElement, trophiesAndPoints, date, this._noteDiv); } editNote() { if (this._noteVisible) { return; } this._noteVisible = true; const textArea = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('textarea') .setAttribute('placeholder', 'Short notes, checklists and ideas can be stored here. You can also include clickable links as [Link Text](Link URL)') .setValue(this._noteText); const noteElement = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('form') .setAttribute('style', 'margin-top: 5px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('label') .addClass('textarea') .append(textArea)), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .setAttribute('style', 'margin-top: 5px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('button', 'green') .setAttribute('style', 'display: inline-block; margin-right: 5px;') .setAttribute('href', '#') .setText('Save') .click(e => { var _a; e.preventDefault(); this._noteText = textArea.getValue().trim(); noteElement.remove(); (_a = this._noteDiv) === null || _a === void 0 ? void 0 : _a.remove(); this._createNoteDiv(); this.append(this._noteDiv); this._onEditNote(this._listItem, this._noteText); this._noteVisible = false; }), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .addClass('button', 'red') .setAttribute('style', 'display: inline-block;') .setAttribute('href', '#') .setText('Close') .click(e => { e.preventDefault(); this._noteVisible = false; noteElement.remove(); }))); this.append(noteElement); } } class ListCustomColumn extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(item, tags, onPsPlusToggled, onTagsChanged) { super('td'); this._item = item; this._tags = tags; this._onPsPlusToggled = onPsPlusToggled; this._onTagsChanged = onTagsChanged; this._psPlusToggled = typeof this._item.psplus === 'undefined' ? false : this._item.psplus; this._hasItemTags = typeof this._item.tags === 'undefined' || this._item.tags.length === 0 ? false : true; this._psPlusImage = this._setupPsPlusImage(); this._tagsDropdown = this._setupTagsDropdown(); this._build(); } _setupPsPlusImage() { const image = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('img') .setAttribute('src', '/lib/img/icons/ps-plus.png') .setAttribute('width', '18') .setAttribute('height', '18') .setAttribute('style', 'margin-right: 8px;') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_2__.tooltip)(el, 'Toggle PS+ Tag')) .addClass('psnpp-toggle-psplus') .setCss('cursor', 'pointer') .click(() => { this._psPlusToggled = !this._psPlusToggled; this._onPsPlusToggled(this._item, this._psPlusToggled); }); if (!this._psPlusToggled) { image.hide(); } return image; } _setupTagsDropdown() { const availableTags = this._tags; const itemTags = typeof this._item.tags === 'undefined' ? [] : this._item.tags; if (availableTags.length === 0) { return null; } const dropdown = new _ui_MultiDropdownMenu__WEBPACK_IMPORTED_MODULE_3__.MultiDropdownMenu({ mainButton: _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i') .addClass('fa', 'fa-tags') .setAttribute('aria-hidden', 'true') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_2__.tooltip)(el, 'Manage Tags')), mainButtonIconClass: 'rarity', options: availableTags.map(t => ({ text: t, value: t, selected: itemTags.indexOf(t) > -1 })), onSelectionChanged: (tags) => { this._hasItemTags = tags.length > 0; this._onTagsChanged(this._item, tags); } }); if (!this._hasItemTags) { dropdown.hide(); } return dropdown; } _build() { this .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .setAttribute('style', 'width: 55px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('flex', 'v-align', 'center') .append(this._psPlusImage, this._tagsDropdown))); } showColumn() { this._psPlusImage.show(); if (this._tagsDropdown !== null) { this._tagsDropdown.show(); } } hideColumn() { if (!this._psPlusToggled) { this._psPlusImage.hide(); } if (!this._hasItemTags && this._tagsDropdown != null) { this._tagsDropdown.hide(); } } } class ListPlatforms extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(platforms) { super('td'); this._build(this._getPlatformElements(platforms)); } _getPlatformElements(platforms) { const platformTags = Object.entries((0,_platforms__WEBPACK_IMPORTED_MODULE_6__.mapPlatforms)(platforms)) .map(([key, value]) => _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('tag', 'platform', key) .setText(value)); return platformTags; } _build(platformElements) { const platforms = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('platforms') .setAttribute('style', 'width: 100%;'); platformElements.forEach((el) => { platforms.append(el); }); this .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('separator', 'left') .append(platforms)); } } class ListTrophies extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(trophies, game) { super('td'); this._build(trophies, game); } _build(trophies, game) { const gold = game != null && game.trophies != null ? game.trophies.gold.toString() : trophies.gold.toString(); const silver = game != null && game.trophies != null ? game.trophies.silver.toString() : trophies.silver.toString(); const bronze = game != null && game.trophies != null ? game.trophies.bronze.toString() : trophies.bronze.toString(); this .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('separator', 'left') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('trophy-count') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('flex', 'v-align', 'center') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').addClass('icon-sprite', 'gold'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').setText(gold), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').addClass('icon-sprite', 'silver'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').setText(silver), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').addClass('icon-sprite', 'bronze'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').setText(bronze)), typeof game === 'undefined' ? null : _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('progress-bar') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').setText(`${game.progress}%`), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div').setAttribute('style', `width: ${game.progress}%`))))); } } class ListCompletion extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(listItem, game) { super('td'); this._build(listItem, game); } _build(item, game) { var _a, _b; const hasPlatinum = item.trophies.platinum > 0; const hasEarnedPlatinum = game != null && game.trophies != null && game.trophies.platinum > 0; const hasEarned100pct = game != null && game.progress === 100; const extraElements = []; extraElements.push(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('br')); extraElements.push(hasPlatinum ? _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('platinum') .condition(hasEarnedPlatinum, el => el.addClass('earned')) .setText(`${((_a = item.platinumpct) !== null && _a !== void 0 ? _a : 0).toFixed(2)}%`) : null); // NOTE: Does not have platinum OR it has platinum but also DLC extraElements.push(((!hasPlatinum) || (hasPlatinum && typeof item.dlccount === 'number' && item.dlccount > 0)) ? _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('completion') .condition(hasEarned100pct, el => el.addClass('earned')) .setText(`${((_b = item.completepct) !== null && _b !== void 0 ? _b : 0).toFixed(2)}%`) .apply(el => { if (typeof item.dlccount !== 'undefined' && item.dlccount > 0) { (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_2__.tooltip)(el, 'Number of DLCs: ' + item.dlccount); } }) : null); this .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('separator', 'left', 'completion-status') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('img') .addClass('icon-sprite', hasPlatinum ? 'platinum-18' : 'completion') .condition(hasEarnedPlatinum || hasEarned100pct, el => el.addClass('earned')) .setAttribute('src', '/lib/img/layout/spacer.png'), ...extraElements)); } } class ListItemActions extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(otherLists, onClick) { super('td'); this._otherLists = otherLists; this._onClick = onClick; this._build(); } _build() { this.append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('separator', 'left') .append(new _ui_DropdownMenu__WEBPACK_IMPORTED_MODULE_5__.DropdownMenu({ mainButton: _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .addClass('button', 'blue') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i').addClass('fa', 'fa-caret-down').setAttribute('aria-hidden', 'true')), mainButtonIconClass: 'rarity', options: [ { text: 'Edit Note', value: 'editNote', selected: false, }, 'divider', { text: 'Move to list', value: 'moveToList', selected: false }, { text: 'Copy to list', value: 'copyToList', selected: false }, 'divider', { text: 'Move to top', value: 'moveToTop', selected: false }, { text: 'Move to bottom', value: 'moveToBottom', selected: false }, 'divider', { text: 'Delete', value: 'delete', selected: false } ], onSelected: (value, context) => { this._onClick(value, context); }, dropdownMenuClass: 'right' }))); } } class ListRow extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(listItem, tags, activeSessions, game, guide, unobtainableTrophies, otherLists, onMoveCopy, onDelete, onMoveToTop, onMoveToBottom, onEditNote, onPsPlusToggled, onTagsChanged, listTableSettings) { super('tr'); this._tags = tags; this._onMoveCopy = onMoveCopy; this._onDelete = onDelete; this._onMoveToTop = onMoveToTop; this._onMoveToBottom = onMoveToBottom; this._onEditNote = onEditNote; this._onPsPlusToggled = onPsPlusToggled; this._onTagsChanged = onTagsChanged; this._listTableSettings = listTableSettings; this._build(listItem, activeSessions, game, guide, unobtainableTrophies, otherLists); } _build(listItem, activeSessions, game, guide, unobtainableTrophies, otherLists) { const totalTrophies = listItem.trophies.platinum + listItem.trophies.gold + listItem.trophies.silver + listItem.trophies.bronze; const addedOn = (0,_util_date__WEBPACK_IMPORTED_MODULE_1__.getPrettyDate)(listItem.timestamp); const customColumn = new ListCustomColumn(listItem, this._tags, this._onPsPlusToggled, this._onTagsChanged); if (game != null && game.trophies != null) { if (game.trophies.platinum === 1) { this.addClass('platinum'); } else if (game.progress === 100) { this.addClass('completed'); } } const listDescription = new ListDescription(listItem, listItem.url, listItem.title, listItem.region, listItem.guideurl, totalTrophies, listItem.points, listItem.note, addedOn, game, activeSessions, unobtainableTrophies, guide, (listItem, note) => { this._onEditNote(listItem, note); }); this .append(this._listTableSettings.isSortAllowed ? _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('td') .setAttribute('style', 'width: 1%;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('draggable-list-handle') .setAttribute('style', 'height: 56px; width: 30px; background: url(/lib/img/icons/drag-handle.png) no-repeat center; cursor: ns-resize;')) : null, new ListImage(listItem.url, listItem.title, listItem.image, this._listTableSettings.resizePS5Icons), listDescription, customColumn, new ListPlatforms(listItem.platforms), new ListTrophies(listItem.trophies, game), new ListCompletion(listItem, game), this._listTableSettings.showActionsDropdown ? new ListItemActions(otherLists, (action) => { if (action === 'editNote') { listDescription.editNote(); } if (action === 'delete') { this._onDelete(this, listItem); } if (action === 'moveToTop') { this._onMoveToTop(this, listItem); } if (action === 'moveToBottom') { this._onMoveToBottom(this, listItem); } if (action === 'moveToList' || action === 'copyToList') { this._onMoveCopy(this, listItem, action); } }) : null) .mouseenter(() => customColumn.showColumn()) .mouseleave(() => customColumn.hideColumn()); } } /***/ }), /* 64 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "getUnobtainableTrophiesDescription": () => (/* binding */ getUnobtainableTrophiesDescription) /* harmony export */ }); function getUnobtainableTrophiesDescription(unobtainableTrophies) { const specifier = unobtainableTrophies.length > 0 ? unobtainableTrophies.length === 1 && unobtainableTrophies[0] === 0 ? 'only' : unobtainableTrophies.length : 'some'; const trophyPlural = specifier === 1 ? 'trophy' : 'trophies'; return `This trophy list contains ${specifier} unobtainable ${trophyPlural}`; } /***/ }), /* 65 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "linkifyText": () => (/* binding */ linkifyText) /* harmony export */ }); /* harmony import */ var _J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); function linkifyText(text) { // NOTE: [Link Text](http://link.url) const linkRegex = /\[(.+?)\]\((.+?)\)/g; let match; let startIndex = 0; const result = []; while ((match = linkRegex.exec(text)) != null) { result.push(text.substring(startIndex, match.index)); startIndex = match.index + match[0].length; result.push(_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a').setAttribute('href', match[2]).setText(match[1])); } result.push(text.substring(startIndex, text.length)); return result; } /***/ }), /* 66 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ListRandomGamePanel": () => (/* binding */ ListRandomGamePanel) /* harmony export */ }); /* harmony import */ var _ui_panel_Panel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(31); /* harmony import */ var _util_transform__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3); class ListRandomGamePanel extends _ui_panel_Panel__WEBPACK_IMPORTED_MODULE_0__.Panel { constructor(listItems) { super('Your random game is...'); this._listItems = listItems; this._textContainer = _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('span') .setAttribute('style', 'font-size: 20px;'); this._imageContainer = _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('img') .setAttribute('style', 'height: 176px; border-radius: 10px; background-color: #292b2d;'); this._addContent(); this._animate(); } _addContent() { this.addContent(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('div') .setAttribute('id', 'inner') .addClass('inner') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('center') .setAttribute('style', 'margin-bottom: 10px;') .append(this._textContainer, _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('br'), this._imageContainer), _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('center') .setAttribute('style', 'margin-bottom: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('a') .setAttribute('href', '#') .addClass('button', 'green') .setText('Reroll') .click((e) => { e.preventDefault(); this._animate(); })))); } _animate() { const ding = new Audio('https://psnprofiles.com/lib/sound/ding.mp3'); ding.setAttribute('preload', 'true'); const shuffledGames = (0,_util_transform__WEBPACK_IMPORTED_MODULE_1__.cloneDeep)(this._listItems).sort(() => Math.random() - 0.5); let index = 0; const interval = setInterval(() => { this._textContainer.setText(shuffledGames[index].title); this._imageContainer.setAttribute('src', shuffledGames[index].image); index++; if (index === shuffledGames.length) { index = 0; } }, 75); setTimeout(() => { clearInterval(interval); const index = Math.floor(Math.random() * shuffledGames.length); this._textContainer .setText('') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('a') .setAttribute('href', shuffledGames[index].url) .setText(shuffledGames[index].title)); this._imageContainer.setAttribute('src', shuffledGames[index].image); if (typeof Elevator === 'function') { ding.play(); } }, 1500); } } /***/ }), /* 67 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "MoveCopyPanel": () => (/* binding */ MoveCopyPanel) /* harmony export */ }); /* harmony import */ var _ui_panel_Panel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(31); /* harmony import */ var _ui_panel_PanelBottom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(37); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3); /* harmony import */ var _ListStorage__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8); class MoveCopyPanel extends _ui_panel_Panel__WEBPACK_IMPORTED_MODULE_0__.Panel { constructor(listItem, action, currentList) { super(`${action === 'moveToList' ? 'Move ' : 'Copy '} to another list`); this._listStorage = new _ListStorage__WEBPACK_IMPORTED_MODULE_3__.ListStorage(); this._listsToDisplay = this._listStorage .get() .sort((a, b) => a.name.localeCompare(b.name)) // NOTE: We don't want to move / copy to the same list .filter(list => list.id !== currentList.id); this._selectedList = this._listsToDisplay[0].id; this._addContent(listItem, action, currentList); } _addContent(listItem, action, currentList) { const listSelector = _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('div') .addClass('form', 'box') .setAttribute('style', 'padding: 5px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('label') .addClass('select') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('select') .change(e => { if (e == null || e.target == null) { return; } this._selectedList = e.target.value; }) .append(...this._listsToDisplay.map(list => { return _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('option') .setAttribute('value', list.id) .setText(`${list.name}${list.url != null && list.url !== '' ? ' [ 📡 ]' : ''}`); })), _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('i'))); this.addContent(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('div') .setAttribute('id', 'inner') .addClass('inner') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('center') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('img') .setAttribute('src', listItem.image) .setAttribute('style', 'max-width: 100px;'), _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('h2').setText(listItem.title), _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('span').setText(`${action === 'moveToList' ? 'Move ' : 'Copy '} to:`), _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('br'), listSelector)), new _ui_panel_PanelBottom__WEBPACK_IMPORTED_MODULE_1__.PanelBottom(action === 'moveToList' ? 'Move' : 'Copy', () => { const deleteOriginal = action === 'moveToList'; const actionDone = this._listStorage.moveCopyGame(currentList.id, this._selectedList, listItem, deleteOriginal); if (actionDone) { if (action === 'moveToList') { this.resolve(true); } this.remove(); } else { alert(`${listItem.title} cannot be ${action === 'moveToList' ? 'moved' : 'copied'} because it's already included in the selected list.`); } }, 'Close', () => this.remove())); } } /***/ }), /* 68 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "scrapeGameProgress": () => (/* binding */ scrapeGameProgress) /* harmony export */ }); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _util_date__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(53); function scrapeGameProgress(rows) { return rows.map(row => { const titleElement = row.clone().find('a.title'); const title = titleElement.getText(); const urlPath = titleElement.getAttribute('href'); const url = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getWebsiteUrl)() + urlPath; const id = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getFirstLevelIdFromPathname)(urlPath); const progress = parseInt(row.clone().find('div.progress-bar').find('span').getText().replace('%', ''), 10); const image = row.clone().find('picture img').getAttribute('src'); let region = titleElement.clone().parent().getText().split(' • ')[1]; if (region != null) { region = region.trim(); } const [lastActivityString, completionTimeString] = row.clone() .find('div.small-info', { eq: 1 }) .getText() .replace(/\s+/g, ' ') .trim() .split(' • '); const lastActivity = lastActivityString == '' ? undefined : (0,_util_date__WEBPACK_IMPORTED_MODULE_1__.parseSupDate)(lastActivityString).getTime(); const platinumIcon = row.clone().find('img.icon-sprite.platinum-18'); const platinum = platinumIcon.exists() && platinumIcon.hasClass('earned') ? 1 : 0; const gold = parseInt(row.clone().find('span.icon-sprite.gold').next().getText(), 10); const silver = parseInt(row.clone().find('span.icon-sprite.silver').next().getText(), 10); const bronze = parseInt(row.clone().find('span.icon-sprite.bronze').next().getText(), 10); const isPS5 = row.clone().find('span.tag.platform.ps5').exists(); const isPS4 = row.clone().find('span.tag.platform.ps4').exists(); const isPS3 = row.clone().find('span.tag.platform.ps3').exists(); const isPSVITA = row.clone().find('span.tag.platform.psvita').exists(); const isPSVR = row.clone().find('span.tag.platform.psvr').exists(); return { id, title, url, scrapetime: Date.now(), progress, image, region, lastActivity, completionTimeString, trophies: { platinum, gold, silver, bronze }, platforms: { ps5: isPS5, ps4: isPS4, ps3: isPS3, psvita: isPSVITA, psvr: isPSVR } }; }); } /***/ }), /* 69 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ListManager": () => (/* binding */ ListManager) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _ListPanel__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(70); /* harmony import */ var _util_linkify__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(65); /* harmony import */ var _ListStorage__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8); /* harmony import */ var _ui_ui_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(39); /* harmony import */ var _state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(21); class NoteRow extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor() { super('div'); this._noteContainer = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-12'); this._build(); } _build() { this .addClass('row') .append(this._noteContainer); } appendNote(...children) { this._noteContainer.empty(); this._noteContainer.append(...children); this.show(); } } class ListManager extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(lists, onListChanged) { var _a; super('div'); this._lists = lists; const lastActiveGameList = new _state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_5__.ScriptStateStorage().get('lastActiveGameList'); this._selectedList = (_a = lists.find(list => list.id === lastActiveGameList)) !== null && _a !== void 0 ? _a : lists[0]; this._noteRow = new NoteRow().hide(); if (this._selectedList != null && this._selectedList.note !== '') { this._noteRow.appendNote(...(0,_util_linkify__WEBPACK_IMPORTED_MODULE_2__.linkifyText)(this._selectedList.note)); } this._onListChanged = onListChanged; this._build(); } _build() { const noLists = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('center') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .setAttribute('style', 'padding-top: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .addClass('button', 'green') .setText('Create new list') .click(e => { e.preventDefault(); (0,_ui_ui_utils__WEBPACK_IMPORTED_MODULE_4__.appendPanel)(new _ListPanel__WEBPACK_IMPORTED_MODULE_1__.ListCreatePanel()); }))); const listSelector = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('form', 'box') .setAttribute('style', 'padding: 5px; margin-bottom: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('row') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-3') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('label') .addClass('select') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('select') .change(e => { if (e == null || e.target == null) { return; } const listId = e.target.value; const list = this._lists.find(list => list.id === listId); if (list == null) { throw new Error('Invalid list ID'); } new _state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_5__.ScriptStateStorage().set('lastActiveGameList', listId); this._selectedList = list; if (this._selectedList.note !== '') { this._noteRow.appendNote(...(0,_util_linkify__WEBPACK_IMPORTED_MODULE_2__.linkifyText)(this._selectedList.note)); } else { this._noteRow.hide(); } this._onListChanged(list.id); }) .append(...this._lists.map(list => { const option = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('option') .setAttribute('value', list.id) .setText(`${list.name} (${list.games.length})${list.url != null && list.url !== '' ? ' [ 📡 ]' : ''}`); if (this._selectedList != null && list.id === this._selectedList.id) { option.setAttribute('selected', 'selected'); } return option; })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i'))), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-1') .setAttribute('style', 'padding-top: 6px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .addClass('button', 'blue') .setText('Edit') .click((e) => { e.preventDefault(); if (typeof this._selectedList !== 'undefined') { (0,_ui_ui_utils__WEBPACK_IMPORTED_MODULE_4__.appendPanel)(new _ListPanel__WEBPACK_IMPORTED_MODULE_1__.ListCreatePanel(this._selectedList.id)); } })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-1') .setAttribute('style', 'padding-top: 6px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .addClass('button', 'red') .setText('Delete') .click((e) => { e.preventDefault(); const result = confirm('Are you sure you want to delete this list?'); if (result) { if (typeof this._selectedList !== 'undefined') { new _ListStorage__WEBPACK_IMPORTED_MODULE_3__.ListStorage().remove(this._selectedList.id); new _state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_5__.ScriptStateStorage().set('lastActiveGameList', null); } location.reload(); } })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-1', 'col-xs-offset-5') .setAttribute('style', 'padding-top: 6px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .addClass('button', 'green') .setText('Create') .click((e) => { e.preventDefault(); (0,_ui_ui_utils__WEBPACK_IMPORTED_MODULE_4__.appendPanel)(new _ListPanel__WEBPACK_IMPORTED_MODULE_1__.ListCreatePanel()); })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-1') .setAttribute('style', 'padding-top: 6px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .addClass('button', 'green') .setText('Import') .click((e) => { e.preventDefault(); (0,_ui_ui_utils__WEBPACK_IMPORTED_MODULE_4__.appendPanel)(new _ListPanel__WEBPACK_IMPORTED_MODULE_1__.ListImportPanel()); }))), this._noteRow); this.append(this._lists.length === 0 ? _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('center') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('h1').setText('Game Lists'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div').setText('This is your personal catalogue of games. Create your own game lists - backlogs, wishlists or community challenge lists.'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div').append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('br'), 'Start by creating your very first list.')) : null, this._lists.length === 0 ? noLists : listSelector); } } /***/ }), /* 70 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ListCreatePanel": () => (/* binding */ ListCreatePanel), /* harmony export */ "ListImportPanel": () => (/* binding */ ListImportPanel) /* harmony export */ }); /* harmony import */ var _ui_panel_Panel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(31); /* harmony import */ var _ui_panel_PanelSection__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(32); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3); /* harmony import */ var _ui_panel_PanelInput__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(33); /* harmony import */ var _ui_panel_PanelBottom__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(37); /* harmony import */ var _ListStorage__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(8); /* harmony import */ var _state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(21); /* harmony import */ var _ui_panel_PanelRadio__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(71); /* harmony import */ var _ui_panel_PanelSelect__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(38); /* harmony import */ var _util_data__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(7); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(13); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(12); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(25); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(34); class ListCreatePanel extends _ui_panel_Panel__WEBPACK_IMPORTED_MODULE_0__.Panel { constructor(listId = null) { super('PSNP+ List'); this._values = { name: '', tags: [], note: '', removeStartedGames: false, removeGames: 'never', orderBy: 'custom', direction: 'ascending', timestamp: Date.now(), url: '', games: [] }; this._listStorage = new _ListStorage__WEBPACK_IMPORTED_MODULE_5__.ListStorage(); this._listId = listId; this._mode = this._listId == null ? 'CREATE' : 'EDIT'; if (this._mode === 'EDIT') { const list = this._listStorage.getById(this._listId); this._values.name = list.name; this._values.tags = list.tags; this._values.note = list.note; this._values.url = list.url == null ? '' : list.url; this._values.removeGames = list.removeStartedGames ? 'started' : list.removeGames != null ? list.removeGames : 'never'; this._values.orderBy = list.orderBy == null ? 'custom' : list.orderBy; this._values.direction = list.direction == null ? 'descending' : list.direction; } this._addContent(); } _addContent() { const nameInput = new _ui_panel_PanelInput__WEBPACK_IMPORTED_MODULE_3__.PanelInput('Name', this._values.name, 'Name of your list, e.g. "Wishlist". This field cannot be empty.', (name) => name.trim() !== ''); const tagsInput = new _ui_panel_PanelInput__WEBPACK_IMPORTED_MODULE_3__.PanelInput('Tags', this._values.tags.join(', '), 'List of tags separated by ",". Tags starting with "@" will be added automatically to new items.'); const noteInput = new _ui_panel_PanelInput__WEBPACK_IMPORTED_MODULE_3__.PanelInput('Note', this._values.note, 'You can also include clickable links as [Link Text](Link URL)'); const urlInput = new _ui_panel_PanelInput__WEBPACK_IMPORTED_MODULE_3__.PanelInput('URL', this._values.url, 'URL which can be used to reload list. Useful if the list is hosted elsewhere.', (url) => url === '' || (0,_util_url__WEBPACK_IMPORTED_MODULE_11__.validateUrl)(url)); const defaultOrderBy = new _ui_panel_PanelSelect__WEBPACK_IMPORTED_MODULE_8__.PanelSelect('Order by', this._values.orderBy, { custom: 'Custom', timestamp: 'Date Added', lastActivity: 'Last Activity', completionTime: 'Completion Time', alphabetical: 'Alphabetical', points: 'Points', trophies: 'Trophies', platinum: 'Platinum Rate', full: '100% Rate', progress: 'Progress', difficulty: 'Difficulty', guideTime: 'Guide Time', note: 'Note' }); const defaultOrderDirection = new _ui_panel_PanelRadio__WEBPACK_IMPORTED_MODULE_7__.PanelRadio('Order direction', this._values.direction, [ { name: 'direction', value: 'ascending', text: 'Ascending' }, { name: 'direction', value: 'descending', text: 'Descending' } ]); const removeGamesRadio = new _ui_panel_PanelRadio__WEBPACK_IMPORTED_MODULE_7__.PanelRadio('Remove games', this._values.removeGames, [ { name: 'removeGames', value: 'never', text: 'Never', tooltip: 'Games will never be removed automatically from this list.' }, { name: 'removeGames', value: 'started', text: 'Started', tooltip: 'Games that appear in your profile will be automatically removed from this list.' }, { name: 'removeGames', value: 'platinum', text: 'Platinum', tooltip: 'Games with earned platinum trophy will be removed. Platinum-less games will be removed if you reach 100% completion.' }, { name: 'removeGames', value: 'completed', text: 'Completed', tooltip: 'Games with 100% completion will be automatically removed from this list.' } ]); this.addContent(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('div') .setAttribute('id', 'inner') .addClass('inner') .append(new _ui_panel_PanelSection__WEBPACK_IMPORTED_MODULE_1__.PanelSection('List Settings', nameInput, tagsInput, noteInput, urlInput, defaultOrderBy, defaultOrderDirection, removeGamesRadio)), new _ui_panel_PanelBottom__WEBPACK_IMPORTED_MODULE_4__.PanelBottom('Save & Reload', () => { const formInvalid = [ nameInput.validate(), tagsInput.validate(), urlInput.validate(), noteInput.validate() ].some(result => result === false); if (formInvalid) { return; } if (this._mode === 'EDIT') { const oldTags = this._values.tags; const newTags = tagsInput.commaSeparatedList(); const removedTags = oldTags.filter(o => newTags.indexOf(o) === -1); if (removedTags.length > 0) { this._listStorage.clearTags(this._listId, removedTags); } } const newList = { name: nameInput.serialize().trim(), timestamp: Date.now(), tags: tagsInput.commaSeparatedList(), orderBy: defaultOrderBy.serialize(), direction: defaultOrderDirection.serialize(), removeGames: removeGamesRadio.serialize(), note: noteInput.serialize().trim(), url: urlInput.serialize(), games: [], removeStartedGames: false }; if (this._mode === 'CREATE') { const listId = this._listStorage.createList(newList); new _state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_6__.ScriptStateStorage().set('lastActiveGameList', listId); } else if (this._mode === 'EDIT') { this._listStorage.updateList(this._listId, newList); } this.remove(); location.reload(); }, 'Close', () => this.remove())); } } class ListImportPanel extends _ui_panel_Panel__WEBPACK_IMPORTED_MODULE_0__.Panel { constructor(url) { super('PSNP+ List Import'); this._values = { url: '', }; this._listStorage = new _ListStorage__WEBPACK_IMPORTED_MODULE_5__.ListStorage(); this._scriptStateStorage = new _state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_6__.ScriptStateStorage(); if (url != null) { this._values.url = url; } this._addContent(); } _addContent() { const urlInput = new _ui_panel_PanelInput__WEBPACK_IMPORTED_MODULE_3__.PanelInput('URL', this._values.url, 'Exact URL that leads to previously exported list', (url) => (0,_util_url__WEBPACK_IMPORTED_MODULE_11__.validateUrl)(url), _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('a') .setAttribute('href', '#') .addClass('button', 'blue') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_13__.tooltip)(el, 'Copy shareable URL')) .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('i').addClass('fa', 'fa-clipboard').setAttribute('aria-hidden', 'true')) .click(async (e, el) => { e.preventDefault(); const validUrl = urlInput.validate(); if (!validUrl) { alert('Invalid URL: ' + urlInput.serialize()); return; } const websiteUrl = (0,_util_url__WEBPACK_IMPORTED_MODULE_11__.getWebsiteUrl)(); const urlToCopy = `${websiteUrl}${_util_constants__WEBPACK_IMPORTED_MODULE_12__.HASH_PROFILE}?hash=${_util_constants__WEBPACK_IMPORTED_MODULE_12__.HASH_GAME_LISTS.replace('#', '')}?import=${encodeURIComponent(encodeURIComponent(urlInput.serialize()))}`; try { await navigator.clipboard.writeText(urlToCopy); el.clone().find('i').removeClass('fa-clipboard').addClass('fa-check'); setTimeout(() => el.clone().find('i').removeClass('fa-check').addClass('fa-clipboard'), 1000); } catch (e) { const typedE = e; alert('Copying to clipboard failed: ' + typedE.message); console.error('Copy error', typedE); } })); const _handleLocalCopy = async () => { try { const url = urlInput.serialize(); const list = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_10__.gmFetchJson)(url); list.url = url; const id = this._listStorage.createList(list); this._scriptStateStorage.set('lastActiveGameList', id); location.hash = _util_constants__WEBPACK_IMPORTED_MODULE_12__.HASH_GAME_LISTS; location.reload(); } catch (e) { const typedE = e; alert('Failed to download list! Error message: ' + typedE.message); } }; const fileInput = _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('input') .setAttribute('type', 'file') .setAttribute('style', 'display: none;') .change(async (e) => { if (e == null || e.target == null) { return; } const target = e.target; if (target.files == null || target.files.length === 0) { return; } try { const id = await (0,_util_data__WEBPACK_IMPORTED_MODULE_9__.importList)(target.files[0]); this._scriptStateStorage.set('lastActiveGameList', id); location.reload(); } catch (e) { const typedE = e; alert('Failed to import list! Error message: ' + typedE.message); } }); this.addContent(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('div') .setAttribute('id', 'inner') .addClass('inner') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('div') .addClass('row', 'center-xs') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('div') .addClass('col-xs-2') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('a') .addClass('button', 'green') .setAttribute('href', '#') .setText('Import from JSON file') .click((e) => { e.preventDefault(); fileInput.triggerClick(); }))), _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('div') .addClass('row', 'center-xs') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('div') .addClass('col-xs-12') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('h3') .setAttribute('style', 'width: 100%; text-align: center; border-bottom: 1px solid #e3e3e6; line-height: 0.01em; margin: 10px 0 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('span') .setAttribute('style', 'background: #fafafa; padding: 0 10px;') .setText('or')))), _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('div') .addClass('form') .append(urlInput), _util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('div') .addClass('row') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('div') .addClass('col-xs-2', 'col-xs-offset-2') .append(_util_J__WEBPACK_IMPORTED_MODULE_2__.J.c('a') .addClass('button', 'green') .setAttribute('href', '#') .setText('Import from URL') .click((e) => { e.preventDefault(); _handleLocalCopy(); }))))); } } /***/ }), /* 71 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "PanelRadio": () => (/* binding */ PanelRadio) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(34); class PanelRadio extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(label, value, options) { super('div'); this._radioInputs = []; this._label = label; this._value = value; this._options = options; this._build(); } _build() { this .addClass('row', 'middle-xs') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-2') .setAttribute('style', 'text-align: right;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('small-title') .setText(this._label)), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-10') .setAttribute('style', 'display: flex;') .append(...this._options.map(option => { const input = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('input') .setAttribute('type', 'radio') .setAttribute('name', option.name) .setAttribute('value', option.value) .condition(option.value === this._value, el => el.setAttribute('checked', 'checked')); this._radioInputs.push(input); return _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('label') .addClass('radio') .setAttribute('style', 'display: flex; margin-right: 20px;') .append(input, _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .setText(option.text) .condition(option.tooltip != null, el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_1__.tooltip)(el.get(), option.tooltip))); }))); } serialize() { const checked = this._radioInputs.find(input => input.get().checked); if (checked != null) { return checked.getValue(); } return this._options[0].value; } } /***/ }), /* 72 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ListButton": () => (/* binding */ ListButton), /* harmony export */ "ListButtonSmall": () => (/* binding */ ListButtonSmall) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(34); /* harmony import */ var _lists_ListScraper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11); /* harmony import */ var _lists_ListStorage__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(8); /* harmony import */ var _state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(21); /* harmony import */ var _util_user__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(19); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(12); class ListButtonSmall extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(trophyListId, trophyListUrl, listId, buttonClass) { super('a'); this._type = 'add'; this._enabled = true; this._addProperties = { color: 'green', icon: 'plus' }; this._removeProperties = { color: 'red', icon: 'minus' }; this._trophyListId = trophyListId; this._trophyListUrl = trophyListUrl; this._listId = listId; this._buttonClass = buttonClass; this._listStorage = new _lists_ListStorage__WEBPACK_IMPORTED_MODULE_3__.ListStorage(); this._type = this._listStorage.hasInList(this._listId, this._trophyListId) ? 'remove' : 'add'; this._build(); } _setProperties() { const oldProps = this._type === 'add' ? this._removeProperties : this._addProperties; const newProps = this._type === 'add' ? this._addProperties : this._removeProperties; const getIconClass = (icon) => `fa-${icon}-circle`; this.removeClass(oldProps.color) .clone().find('i') .removeClass(getIconClass(oldProps.icon)); this.addClass(newProps.color) .clone().find('i') .addClass(getIconClass(newProps.icon)); } _build() { const lastActiveGameListName = this._listStorage.getById(this._listId).name; this .setAttribute('href', '#') .addClass('button', this._buttonClass) .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_1__.tooltip)(el, `Last active game list: ${lastActiveGameListName}`)) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i').addClass('fa')) .click(async (e) => { e.preventDefault(); if (!this._enabled) { return; } this._enabled = false; if (this._type === 'add') { try { const listItem = await _lists_ListScraper__WEBPACK_IMPORTED_MODULE_2__.ListScraper.getFromUrl(this._trophyListUrl); this._listStorage.addGameToList(this._listId, listItem, true); this._type = 'remove'; } catch (e) { console.warn('Adding to list failed', e); } } else { this._listStorage.removeGame(this._listId, this._trophyListId); this._type = 'add'; } this._setProperties(); this._enabled = true; }); this._setProperties(); } } class ListButton extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(listStorage, listItem) { var _a, _b; super('div'); this._selectedListId = ''; this._listStorage = listStorage; this._listItem = listItem; this._lists = this._listStorage .get() .filter(list => !list.games.some(game => game.id === this._listItem.id)) .sort((a, b) => a.name.localeCompare(b.name)); if (this._lists.length === 0) { this._buildRedirect(); return; } const lastActiveGameList = new _state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_4__.ScriptStateStorage().get('lastActiveGameList'); this._selectedListId = (_b = (_a = this._lists.find(list => list.id === lastActiveGameList)) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : this._lists[0].id; this._build(); } // Builds basic button which just redirects if user has 0 lists _buildRedirect() { this .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .addClass('button', 'green') .setText('Add to list') .click((e) => { e.preventDefault(); const psnId = (0,_util_user__WEBPACK_IMPORTED_MODULE_5__.getPsnId)(); (0,_util_url__WEBPACK_IMPORTED_MODULE_6__.redirect)('/' + psnId + '#gamelists'); })); } _build() { this .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('form') .setAttribute('style', 'padding: 5px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('row') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-8') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('label') .addClass('select') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('select') .change((e) => { if (e == null || e.target == null) { return; } this._selectedListId = e.target.value; new _state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_4__.ScriptStateStorage().set('lastActiveGameList', this._selectedListId); }) .append(...this._lists.map(list => { const option = _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('option') .setAttribute('value', list.id) .setText(list.name + ' (' + list.games.length + ')'); if (this._selectedListId === list.id) { option.setAttribute('selected', 'selected'); } return option; })), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('i'))), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('col-xs-4') .setAttribute('style', 'padding-top: 6px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', '#') .addClass('button', 'green') .setText('Add to list') .click((e) => { e.preventDefault(); this._listStorage.addGameToList(this._selectedListId, this._listItem, true); location.reload(); }))))); } } /***/ }), /* 73 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ProfileImmediate": () => (/* binding */ ProfileImmediate) /* harmony export */ }); /* harmony import */ var _util_stylesheet__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(49); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5); class ProfileImmediate { run() { console.debug('ProfileImmediate module is running'); const settingsStorage = new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_1__.SettingsStorage(); if (settingsStorage.get('resizePS5Icons')) { (0,_util_stylesheet__WEBPACK_IMPORTED_MODULE_0__.injectStylesheet)(_util_stylesheet__WEBPACK_IMPORTED_MODULE_0__.STYLESHEET_PROFILE_RESIZE_PS5_ICONS); } if (settingsStorage.get('hideRank')) { (0,_util_stylesheet__WEBPACK_IMPORTED_MODULE_0__.injectStylesheet)(_util_stylesheet__WEBPACK_IMPORTED_MODULE_0__.STYLESHEET_PROFILE_HIDE_RANK); } } } /***/ }), /* 74 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Trophies": () => (/* binding */ Trophies) /* harmony export */ }); /* harmony import */ var _features_lists_ListScraper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(11); /* harmony import */ var _features_plat_prices_PlatPricesStorage__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30); /* harmony import */ var _ui_FloatingMenu__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(51); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3); /* harmony import */ var _features_lists_ListButtons__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(72); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(5); /* harmony import */ var _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(8); /* harmony import */ var _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(21); /* harmony import */ var _util_user__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(19); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(12); /* harmony import */ var _features_plat_prices_PlatPricesAPI__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(23); /* harmony import */ var _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(24); /* harmony import */ var _features_lists_platforms__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(46); /* harmony import */ var _features_unobtainables_unobtainables_utils__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(64); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(25); /* harmony import */ var _features_compare_plus_TrophyListProgressScraper__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(75); /* harmony import */ var _util_promise__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(15); /* harmony import */ var _features_compare_plus_ProgressBox__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(76); /* harmony import */ var _features_compare_plus_ComparePlusStorage__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(27); /* harmony import */ var _util_date__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(53); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(34); /* harmony import */ var _features_guide_GuideScraper__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(54); /* harmony import */ var _features_guide_GuideStorage__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(29); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(13); /* harmony import */ var _util_Logger__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(47); /* harmony import */ var _util_linkify__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(65); class RarityBox extends _util_J__WEBPACK_IMPORTED_MODULE_3__.JC { constructor(rarityInfo, onClick) { super('table'); this.setAttribute('id', 'rarity-box'); this._rarityInfo = rarityInfo; this._onClick = onClick; this._build(); } _getCell(value, rarity, sprite) { return _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td') .setAttribute('style', 'text-align: center; font-weight: 700;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('img').addClass('icon-sprite', 'rarity', sprite).setAttribute('src', '/lib/img/layout/spacer.png'), ' ', value.toString()) .click(e => { e.preventDefault(); this._onClick(rarity); }); } _build() { const cells = [ this._getCell(this._rarityInfo.ultraRare, 'ultra-rare', 'ultra-rare').apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'Ultra Rare')), this._getCell(this._rarityInfo.veryRare, 'very-rare', 'very-rare').apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'Very Rare')), this._getCell(this._rarityInfo.rare, 'rare', 'rare').apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'Rare')), this._getCell(this._rarityInfo.uncommon, 'uncommon', 'common').apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'Uncommon')), this._getCell(this._rarityInfo.common, 'common', 'common').apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'Baby Stuff 👶🍼')) ]; this.addClass('zebra') .setAttribute('style', 'border-top: 1px solid #e3e3e6;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tbody') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tr') .setAttribute('style', 'cursor: pointer;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td').setAttribute('style', 'text-align: center;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('img') .addClass('icon-sprite', 'level') .setAttribute('src', '/lib/img/layout/spacer.png') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'All')) .click((e) => { e.preventDefault(); this._onClick('all'); })), ...cells))); } } class ListInfo extends _util_J__WEBPACK_IMPORTED_MODULE_3__.JC { constructor(listStorage, listItem) { super('div'); this._inLists = listStorage .get() .filter(list => list.games.some(game => game.id === listItem.id)); if (this._inLists.length > 0) { this._build(); } } _build() { this .setAttribute('style', 'padding-left: 5px; padding-top: 5px; text-align: initial;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div').setText('You have added this trophy list to:'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('ul') .append(...this._inLists.map(list => { return _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('li') .setCss('cursor', 'pointer') .setText(list.name) .click(e => { e.preventDefault(); new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_7__.ScriptStateStorage().set('lastActiveGameList', list.id); const psnId = (0,_util_user__WEBPACK_IMPORTED_MODULE_8__.getPsnId)(); (0,_util_url__WEBPACK_IMPORTED_MODULE_9__.redirect)('/' + psnId + '#gamelists'); }); }))); } } class Trophies { constructor(psnId) { this._trophyListId = (0,_util_url__WEBPACK_IMPORTED_MODULE_9__.getFirstLevelIdFromPathname)(window.location.pathname); this._logger = new _util_Logger__WEBPACK_IMPORTED_MODULE_24__.Logger(new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_5__.SettingsStorage().get('enableScriptLogger'), 'Trophies'); this._psnId = psnId; this._showGeometricMeanRarity = true; } _appendListButton() { const listItem = new _features_lists_ListScraper__WEBPACK_IMPORTED_MODULE_0__.ListScraper(document).getFromTrophiesPage(); const listStorage = new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_6__.ListStorage(); _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div.game-image-holder') .after(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .setAttribute('style', 'text-align: center; border: 2px solid #e3e3e6; border-top: none; padding: 5px;') .append(new _features_lists_ListButtons__WEBPACK_IMPORTED_MODULE_4__.ListButton(listStorage, listItem), new ListInfo(listStorage, listItem))); } _getTrophyCountBox() { return _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#content.page > div.row > div.col-xs-4 > div.box.no-top-border') .find('div.trophy-count'); } _getTotalTrophyCount() { const numberText = this._getTrophyCountBox().find('span.small-info.floatr').find('b').getText(); return parseInt(numberText, 10); } _getCompletedTrophies() { const completedElements = (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('tr.completed'); let completed = 0; let points = 0; completedElements.forEach((el) => { const isSummary = el.clone().find('div.trophy-count').exists(); if (isSummary) return; const isBronze = el.clone().find('img[title="Bronze"]').exists(); const isSilver = el.clone().find('img[title="Silver"]').exists(); const isGold = el.clone().find('img[title="Gold"]').exists(); const isPlatinum = el.clone().find('img[title="Platinum"]').exists(); if (isBronze) points += 15; if (isSilver) points += 30; if (isGold) points += 90; if (isPlatinum) points += 300; completed++; }); return { completed, points }; } _appendCompareLink() { const myPsnId = (0,_util_user__WEBPACK_IMPORTED_MODULE_8__.getPsnId)(); if (this._psnId == null || this._psnId === myPsnId) { return; } const currentUrl = location.origin + location.pathname; // NOTE: Check if currentUrl isn't compareUrl already const compareUrl = currentUrl.indexOf(',' + myPsnId) > -1 ? currentUrl : currentUrl + ',' + myPsnId; const forumLink = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('ul.navigation > li > a', { equalsText: 'Forum' }); const forumLinkParentPrevSibling = forumLink.parent().prev(); forumLinkParentPrevSibling.after(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('li') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a').setAttribute('href', compareUrl).setText('Compare'))); } _appendTrophiesAndPointsEarnedSoFar() { const totalTrophyCount = this._getTotalTrophyCount(); const completedTrophies = this._getCompletedTrophies(); if (completedTrophies.completed > 0 && completedTrophies.completed < totalTrophyCount) { this._getTrophyCountBox() .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .addClass('small-info', 'floatr') .setAttribute('style', 'margin-top: 5px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('b').setText(completedTrophies.completed.toString()), ' Trophies ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('b').setText(completedTrophies.points.toLocaleString('en-US')), ' Points') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'Trophies and points earned so far'))); } } _getAllTrophyRows() { return (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('#content.page > div.row > div.col-xs tr') .filter(e => e.clone().find('img[title="Platinum"], img[title="Gold"], img[title="Silver"], img[title="Bronze"]').exists()); } _appendRarityBox() { const psnRarityElementIsVisible = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('td.hover-hide nobr img.icon-sprite.rarity').exists(); if (psnRarityElementIsVisible) { return; } _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#rarity-box').remove(); const rarityInfo = { ultraRare: (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('td.hover-hide nobr', { equalsText: 'Ultra Rare' }).length, veryRare: (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('td.hover-hide nobr', { equalsText: 'Very Rare' }).length, rare: (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('td.hover-hide nobr', { equalsText: 'Rare' }).length, uncommon: (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('td.hover-hide nobr', { equalsText: 'Uncommon' }).length, common: (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('td.hover-hide nobr', { equalsText: 'Common' }).length }; const rarityBox = new RarityBox(rarityInfo, (type) => { const textMap = { 'ultra-rare': 'Ultra Rare', 'very-rare': 'Very Rare', 'rare': 'Rare', 'uncommon': 'Uncommon', 'common': 'Common', }; if (type === 'all') { this._getAllTrophyRows().forEach(e => e.show()); } else { this._getAllTrophyRows().forEach(e => e.hide()); (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('td.hover-hide nobr', { equalsText: textMap[type] }).forEach((e) => { // big oof e.parent().parent().parent().parent().show(); }); } }); _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div#content > div.row > div.col-xs-4 > div.box.no-top-border > table.zebra') .after(rarityBox); } _removeMetadataByAttribution() { _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('td', { containsText: 'Metadata by ' }).parent().remove(); } _appendAverageRarity() { let target = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('table.gameInfo.zebra > tbody'); if (!target.exists()) { target = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div#content > div.row > div.col-xs-4 > div.box.no-top-border > table.zebra'); } const textContainerId = 'psnpp-avg-rarity-text'; const detailContainerId = 'psnpp-avg-rarity-detail'; const rarityElements = (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('td.hover-hide span.typo-top'); const rarities = rarityElements .map((el) => parseFloat(el.getText().replace('%', ''))) .sort((a, b) => a - b); const middle = Math.floor(rarities.length / 2); const median = rarities.length % 2 === 1 ? rarities[middle] : (rarities[middle - 1] + rarities[middle]) / 2.0; const sum = rarities.reduce((prev, current) => prev + current, 0); const average = sum / rarities.length; const low = rarities[0]; const high = rarities[rarities.length - 1]; const mainText = `${average.toFixed(2)}% `; const detailText = `(${low.toFixed(2)}% / ${high.toFixed(2)}% / ${median.toFixed(2)}%)`; const textContainer = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#' + textContainerId); if (textContainer.exists()) { textContainer.setText(mainText); _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#' + detailContainerId).setText(detailText); } else { target.append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tr').append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td').setText('Avg. Rarity'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td').append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .setAttribute('id', textContainerId) .setText(mainText), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .setAttribute('id', detailContainerId) .setAttribute('style', 'font-size: 11px;') .setText(detailText) .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'low / high / median'))))); } } _appendComplexity() { let target = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('table.gameInfo.zebra > tbody'); if (!target.exists()) { target = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div#content > div.row > div.col-xs-4 > div.box.no-top-border > table.zebra'); } const guideStorage = new _features_guide_GuideStorage__WEBPACK_IMPORTED_MODULE_22__.GuideStorage(); const guide = guideStorage.getByTrophyListId(this._trophyListId); if (guide == null) { return; } target.append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tr').append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td').setText('Complexity'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td').append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', `${(0,_util_url__WEBPACK_IMPORTED_MODULE_9__.getWebsiteUrl)()}/guide/${guide.guideId}`) .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .setText(`${guide.difficulty}/10`) .setAttribute('style', `${guide.difficultyStyle}; color: white; padding: 1px 2px; border-radius: 2px;`) .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'Difficulty')), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .setText(`${guide.playthroughs}x`) .setAttribute('style', `${guide.playthroughsStyle}; color: white; padding: 1px 2px; border-radius: 2px;`) .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'Playthroughs')), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .setText(`${guide.time}h`) .setAttribute('style', `${guide.timeStyle}; color: white; padding: 1px 2px; border-radius: 2px;`) .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'Time'))) .condition(guide.online === true, el => { el.append(' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .setText('Online') .setAttribute('style', 'background: #3a87ad; color: white; padding: 1px 2px; border-radius: 2px;')); }) .condition(guide.buggy === true, el => { el.append(' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .setText('Buggy') .setAttribute('style', 'background: #b94a48; color: white; padding: 1px 2px; border-radius: 2px;')); })))); } _appendSearchLinks() { const title = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('meta[name="Description"]').getAttribute('content').split(' • ')[0].replace(' Trophy List', ''); let target = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('table.gameInfo.zebra > tbody'); if (!target.exists()) { target = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div#content > div.row > div.col-xs-4 > div.box.no-top-border > table.zebra'); } target.append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tr').append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td').setText('Search'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td').append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', `https://www.google.com/search?q=${encodeURIComponent(`${title} game`)}`) .setAttribute('target', '_blank') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'Google')) .setText('G'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', `https://www.youtube.com/results?search_query=${encodeURIComponent(`${title} gameplay`)}`) .setAttribute('target', '_blank') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'YouTube')) .setText('YT'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', `https://www.google.com/search?q=${encodeURIComponent(`${title} site:playstationtrophies.org/game`)}`) .setAttribute('target', '_blank') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'PlayStationTrophies.org')) .setText('PST'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', `https://www.powerpyx.com/?s=${encodeURIComponent(title)}`) .setAttribute('target', '_blank') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'PowerPyx.com')) .setText('PP'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', `https://www.truetrophies.com/searchresults.aspx?search=${encodeURIComponent(title)}`) .setAttribute('target', '_blank') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'TrueTrophies.com')) .setText('TT'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', `https://www.trueachievements.com/searchresults.aspx?search=${encodeURIComponent(title)}`) .setAttribute('target', '_blank') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'TrueAchievements.com')) .setText('TA')))); } _collectOtherPlatformsAndRegionsPathnames() { const heading = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('h3', { equalsText: 'Other Platforms and Regions' }); if (!heading.exists()) { return []; } const tableContainer = heading .parent() // div .parent() // div .next(); // table const allLinkElements = (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('span > a', {}, tableContainer.get()); return allLinkElements .map(el => el.getAttribute('href')); } _appendPrices() { if (!new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_5__.SettingsStorage().get('platPricesIntegration') || new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_7__.ScriptStateStorage().isPlatPricesCooldownActive()) { return; } let target = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('table.gameInfo.zebra > tbody'); if (!target.exists()) { target = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div#content > div.row > div.col-xs-4 > div.box.no-top-border > table.zebra'); } const otherPlatformsAndRegionsIdentifiers = this._collectOtherPlatformsAndRegionsPathnames(); const trophyListIdentifiers = [ (0,_util_url__WEBPACK_IMPORTED_MODULE_9__.getPathSegmentsFromPathname)(window.location.pathname)[1], ...otherPlatformsAndRegionsIdentifiers.map(x => (0,_util_url__WEBPACK_IMPORTED_MODULE_9__.getPathSegmentsFromPathname)(x)[1]) ]; const priceStorage = new _features_plat_prices_PlatPricesStorage__WEBPACK_IMPORTED_MODULE_1__.PlatPricesStorage(); priceStorage.getById(this._trophyListId, trophyListIdentifiers) .then(price => { const priceRow = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tr'); const basePriceSpan = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span'); const priceRowStrings = [ basePriceSpan.setText(price.formattedBasePrice).apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'Standard price')) ]; if (price.formattedSalePrice !== price.formattedBasePrice) { priceRowStrings.push(' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('b').setText(price.formattedSalePrice).apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'Sale price'))); basePriceSpan.setCss('textDecoration', 'line-through'); priceRow.setCss('backgroundColor', _util_constants__WEBPACK_IMPORTED_MODULE_14__.COLOR_LIGHT_YELLOW); } if (price.formattedPlusPrice !== price.formattedBasePrice && price.formattedPlusPrice !== price.formattedSalePrice) { priceRowStrings.push(' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('b').setText(price.formattedPlusPrice).apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'PS+ price'))); basePriceSpan.setCss('textDecoration', 'line-through'); priceRow.setCss('backgroundColor', _util_constants__WEBPACK_IMPORTED_MODULE_14__.COLOR_LIGHT_YELLOW); } target.append(priceRow.append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td').setText('Price'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td').append(...priceRowStrings)), price.PSPExtra === '1' || price.PSPPremium === '1' ? _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tr').append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('img') .setAttribute('src', '/lib/img/icons/ps-plus.png') .setAttribute('width', '15')), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td') .append('Available on ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('b') .setCss('borderRadius', '2px') .setCss('padding', '1px 2px') .setCss('backgroundColor', price.PSPExtra === '1' ? '#f0c117' : 'black') .setCss('color', price.PSPExtra === '1' ? 'black' : '#f0c117') .setText(price.PSPExtra === '1' ? 'Extra' : 'Premium'))) : null, _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tr').append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td').setText('Store'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td').append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', price.PSStoreURL) .setAttribute('target', '_blank') .setText('PSN'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', price.PlatPricesURL) .setAttribute('target', '_blank') .setText('PlatPrices')))); }) .catch(e => { this._logger.warn(e); // Invalid key -> disable integration if (e.getErrorCode() === _features_plat_prices_PlatPricesAPI__WEBPACK_IMPORTED_MODULE_10__.IPlatPricesError.UNAUTHORIZED) { new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_5__.SettingsStorage().disablePlatPricesIntegration(); } // API limit reached -> set global cooldown if (e.getErrorCode() === _features_plat_prices_PlatPricesAPI__WEBPACK_IMPORTED_MODULE_10__.IPlatPricesError.FORBIDDEN) { new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_7__.ScriptStateStorage().set('platPricesCooldownTriggerTime', Date.now()); } target.append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tr').append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td').setText('Price'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td').append(e.getNiceErrorMessage()))); }); } _buildForumHeader() { const forumLink = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('.title-bar').find('a', { equalsText: 'Forum' }).getAttribute('href'); const forumHeader = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('h3').setText('Recent Forum Posts'); const forumHeaderContainer = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .addClass('title', 'flex', 'v-align') .setAttribute('style', 'margin-top: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .addClass('grow') .append(forumHeader), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .addClass('no-shrink') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', forumLink) .setText('More'))); const emptyTable = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('table') .addClass('box', 'zebra', 'no-top-border') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tbody') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tr') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('center') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span').setText('Forum for this stack is empty')))))); _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('h3', { equalsText: 'Other Platforms and Regions' }) .parent() .parent() .before(forumHeaderContainer, emptyTable); return forumHeader; } _appendForumLoaderButton() { const alreadyAdded = new Set(); const otherStacks = this._collectOtherPlatformsAndRegionsPathnames().reverse(); if (otherStacks.length === 0) { return; } let forumHeader = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('h3', { equalsText: 'Recent Forum Posts' }); if (!forumHeader.exists()) { forumHeader = this._buildForumHeader(); } else { const currentForumPosts = forumHeader.clone().parent().parent().next().getInnerHtml(); alreadyAdded.add(currentForumPosts); } const target = forumHeader.clone().parent().parent().next(); let clicked = false; forumHeader .parent() .after(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .addClass('no-shrink') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', '#') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'Load forum posts from other stacks')) .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('i') .addClass('fa', 'fa-comments-o') .setAttribute('aria-hidden', 'true')) .click(async (e, el) => { e.preventDefault(); if (clicked) { return; } clicked = true; el.clone() .find('i') .removeClass('fa-comments-o') .addClass('fa-spinner', 'fa-spin', 'fa-fw'); try { let firstAppended = false; for (let i = 0; i < otherStacks.length; i++) { const trophyListDoc = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_23__.fetchDocument)(otherStacks[i]); const forumPostsTitle = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('h3', { equalsText: 'Recent Forum Posts' }, trophyListDoc); if (!forumPostsTitle.exists()) { continue; } const toAppend = forumPostsTitle.parent().parent().next().getInnerHtml(); if (alreadyAdded.has(toAppend)) { continue; } else { alreadyAdded.add(toAppend); } target .addClass('no-bottom-border') .after(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('table') .addClass('box', 'zebra') .condition(firstAppended, (el) => el.addClass('no-bottom-border')) .setAttribute('style', 'border-top-color: darkgrey;') .setInnerHtml(toAppend)); firstAppended = true; } } catch (e) { const typedE = e; alert('Failed to load forum posts: ' + typedE.message); this._logger.error('Failed to load error posts', typedE); } el.parent().remove(); // NOTE: Need to manually hide tiptip, otherwise it stays visible _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div#tiptip_holder').hide(); }))); } _recalculateUnobtainableTrophiesToReport() { const trophyList = new _features_lists_ListScraper__WEBPACK_IMPORTED_MODULE_0__.ListScraper(document).getFromTrophiesPage(); const platforms = (0,_features_lists_platforms__WEBPACK_IMPORTED_MODULE_12__.mapPlatforms)(trophyList.platforms); const allCheckedTrophies = (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('input[name="unobtainable-trophies"]:checked'); const allTrophiesAreChecked = (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('input[name="unobtainable-trophies"]').length === allCheckedTrophies.length; const trophies = []; if (allTrophiesAreChecked) { trophies.push(0); } else { allCheckedTrophies .map(el => { const row = el.parent().parent().parent().parent(); // oof const trophyPath = row.clone().find('a.title').getAttribute('href'); const trophyId = [...trophyPath.matchAll(/\/([0-9]+)-/g)][1][1]; return { path: trophyPath, id: parseInt(trophyId, 10) }; }) .sort((a, b) => a.id - b.id) .forEach(x => { trophies.push(x.id); }); } const note = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-report-unobtainable-trophies-note').getValue().trim(); const newReport = { title: trophyList.title, platforms: Object.values(platforms), region: trophyList.region, submitter: (0,_util_user__WEBPACK_IMPORTED_MODULE_8__.getPsnId)(), note, trophies, timestamp: Date.now() }; const prefix = `"${trophyList.id}": `; const postfix = ','; _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-report-unobtainable-trophies-textarea') .setValue(prefix + JSON.stringify(newReport, null, 2) + postfix); } async _appendComparePlusBox() { const url = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('meta[property="og:url"]').getAttribute('content'); const target = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div#content > div.row > div.col-xs-4.col-xs-max-320'); const value = await new _features_compare_plus_ComparePlusStorage__WEBPACK_IMPORTED_MODULE_18__.ComparePlusStorage().getByTrophyListId(this._trophyListId); target .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .addClass('title', 'flex', 'v-align') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('h3') .addClass('grow') .setText('Compare+')), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('table') .addClass('box', 'zebra') .setAttribute('style', 'margin-bottom: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tbody') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tr') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td') .setAttribute('style', 'padding-right: 5px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .setAttribute('style', 'text-align: justify; margin-bottom: 8px;') .setText('Playing this game in co-op or side-by-side with your friends? Enter PSN IDs of up to 4 players in the text box below (including your own and separated with comma) to see better comparison.'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .addClass('form') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('label') .addClass('input') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('input') .setAttribute('type', 'text') .setAttribute('id', 'psnpp-compare-plus-psnids') .setValue(value), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('i')), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', '#') .setAttribute('style', 'margin-top: 5px;') .addClass('button', 'green') .setText('Show') .click((e) => { e.preventDefault(); const value = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-compare-plus-psnids') .getValue(); const psnIds = value .split(',') .map((x) => x.trim()) .filter((x) => x !== ''); if (psnIds.length < 2) { alert('You need to enter at least 2 PSN IDs.'); return; } if (psnIds.length > 4) { alert('You can enter maximum of 4 PSN IDs.'); return; } new _features_compare_plus_ComparePlusStorage__WEBPACK_IMPORTED_MODULE_18__.ComparePlusStorage().set(this._trophyListId, value); location.href = url + '/' + psnIds[0] + ',' + psnIds[1] + _util_constants__WEBPACK_IMPORTED_MODULE_14__.HASH_COMPARE_PLUS + '?psnId=' + psnIds.join('&psnId='); }))))))); } _appendCreateUnobtainablesReport() { _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#flagUserLink').click(() => { _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-report-unobtainable-trophies').remove(); }); const target = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div#content > div.row > div.col-xs-4.col-xs-max-320'); target.append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('table') .addClass('zebra', 'box') .setAttribute('style', 'margin-top: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tbody') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('tr') .setAttribute('id', 'psnpp-report-unobtainable-trophies') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td') .setAttribute('colspan', '2') .setAttribute('style', 'padding: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('center') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('style', `color: ${_util_constants__WEBPACK_IMPORTED_MODULE_14__.COLOR_DARK_ORANGE}; font-weight: 500;`) .setAttribute('href', '#') .setText('Report unobtainable trophies') .click((e) => { e.preventDefault(); _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-report-unobtainable-trophies-form').show(); _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div.flag-user').parent().parent().remove(); (0,_util_fetch__WEBPACK_IMPORTED_MODULE_23__.fetchJson)(_util_constants__WEBPACK_IMPORTED_MODULE_14__.LINK_UNOBTAINABLE_TROPHIES_MASTER_LIST_FULL) .then(result => { var _a; const details = result.list[this._trophyListId]; if (details == null) { return; } const value = (_a = details.note) !== null && _a !== void 0 ? _a : ''; _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-report-unobtainable-trophies-note').setValue(value); _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-report-unobtainable-trophies-note-length').setText(value.length + '/' + _util_constants__WEBPACK_IMPORTED_MODULE_14__.UNOBTAINABLE_TROPHIES_REPORT_NOTE_MAXLEN); }) .catch(e => { alert('Failed to preload note in the report.'); this._logger.error('Failed to preload note in the report.', e); }); (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('td.check.form').forEach(td => { td.clone().find('span.separator').remove(); const isAlreadyMarked = td.clone().parent().find('picture.unobtainable').exists(); const isPlatinum = td.clone().parent().find('img[title="Platinum"]').exists(); const isPlatinumGroup = !td.clone().parent().parent().parent().parent().prev().find('h3').getText().startsWith('DLC Trophy Pack'); td .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .addClass('separator', 'left') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('label') .addClass('checkbox') .condition(isPlatinum, el => el.setAttribute('style', 'cursor: not-allowed;')) .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('input') .setAttribute('name', 'unobtainable-trophies') .setAttribute('type', 'checkbox') .condition(isPlatinum, (el) => el .setAttribute('disabled', 'disabled') .setAttribute('id', 'psnpp-report-unobtainable-trophies-platinum-trophy')) .condition(!isPlatinum && isPlatinumGroup, (el) => el.setAttribute('data-group', 'psnpp-platinum-group')) .condition(isAlreadyMarked, (el) => el.setAttribute('checked', 'checked')) .click(() => { const platinumShouldBeChecked = (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('input[data-group="psnpp-platinum-group"]:checked').length > 0; if (platinumShouldBeChecked) { _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-report-unobtainable-trophies-platinum-trophy').setAttribute('checked', 'checked'); } else { _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-report-unobtainable-trophies-platinum-trophy').removeAttribute('checked'); } this._recalculateUnobtainableTrophiesToReport(); }), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('i'), '\u00A0'))); td.show(); }); this._recalculateUnobtainableTrophiesToReport(); })))), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .setAttribute('id', 'psnpp-report-unobtainable-trophies-form') .setAttribute('style', 'display: none; margin-top: 5px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .addClass('row', 'form') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .addClass('col-xs-12') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('label') .addClass('input') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('input') .setAttribute('id', 'psnpp-report-unobtainable-trophies-note') .setAttribute('style', 'margin-bottom: 5px;') .setAttribute('type', 'text') .setAttribute('placeholder', 'Note') .apply(e => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(e, 'Required. Clickable links can be included as: [text](URL)')) .keyup((ev, el) => { const value = el.getValue(); _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-report-unobtainable-trophies-note-length').setText(value.length + '/' + _util_constants__WEBPACK_IMPORTED_MODULE_14__.UNOBTAINABLE_TROPHIES_REPORT_NOTE_MAXLEN); if (value.length < 1 || value.length > _util_constants__WEBPACK_IMPORTED_MODULE_14__.UNOBTAINABLE_TROPHIES_REPORT_NOTE_MAXLEN) { el.setCss('borderColor', '#ffb6c1'); } else { el.setCss('borderColor', '#e3e3e6'); } this._recalculateUnobtainableTrophiesToReport(); }), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .setAttribute('id', 'psnpp-report-unobtainable-trophies-note-length') .addClass('small-info') .setText('0/' + _util_constants__WEBPACK_IMPORTED_MODULE_14__.UNOBTAINABLE_TROPHIES_REPORT_NOTE_MAXLEN)), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('label') .addClass('textarea') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('textarea') .setAttribute('id', 'psnpp-report-unobtainable-trophies-textarea') .setAttribute('readonly', 'readonly') .setAttribute('wrap', 'off') .setAttribute('style', 'width: 100%; height: 200px; font-family: monospace; margin-top: 10px;')), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('center') .setAttribute('style', 'padding-top: 5px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', '#') .addClass('button', 'green') .setAttribute('style', 'display: inline-block;') .setText('Copy') .click(async (e, el) => { e.preventDefault(); const noteLength = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-report-unobtainable-trophies-note').getValue().trim().length; if (noteLength === 0) { alert('Note cannot be empty.'); return; } if (noteLength > _util_constants__WEBPACK_IMPORTED_MODULE_14__.UNOBTAINABLE_TROPHIES_REPORT_NOTE_MAXLEN) { alert(`Note cannot be longer than ${_util_constants__WEBPACK_IMPORTED_MODULE_14__.UNOBTAINABLE_TROPHIES_REPORT_NOTE_MAXLEN} characters.`); return; } const stringToCopy = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-report-unobtainable-trophies-textarea').getValue(); try { await navigator.clipboard.writeText(stringToCopy); el.setText('Copied!'); setTimeout(() => el.setText('Copy'), 1000); } catch (e) { alert('Copying to clipboard failed. Select the text and press Ctrl+C. 😅'); this._logger.error('Copy error', e); } }), ' and ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', 'https://forum.psnprofiles.com/topic/118915-psnp-unobtainable-trophies-master-list/') .setAttribute('target', '_blank') .setText('report here')))))))))); } _updateSeriesLink() { if (this._psnId == null) { return; } (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('a.series-info').forEach(seriesInfoBox => { const currentUrl = seriesInfoBox.getAttribute('href'); seriesInfoBox.setAttribute('href', `${currentUrl}/${this._psnId}`); }); } _modifyRecentPlayers() { const { url } = new _features_lists_ListScraper__WEBPACK_IMPORTED_MODULE_0__.ListScraper(document).getFromTrophiesPage(); const recentPlayersHeader = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('h3', { equalsText: 'Recent Players' }); if (!recentPlayersHeader.exists()) { return; } const tableBelow = recentPlayersHeader.parent().parent().next(); const allRecentPlayers = (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('a.small-title', {}, tableBelow.get()); allRecentPlayers.forEach(player => { const currentUrl = player.getAttribute('href'); player.setAttribute('href', url + currentUrl); }); } _recalcDlcRarities() { function getRarityType(rarity) { if (rarity <= 5) { return 'Ultra Rare'; } if (rarity <= 10) { return 'Very Rare'; } if (rarity <= 20) { return 'Rare'; } if (rarity <= 50) { return 'Uncommon'; } return 'Common'; } const gameOwnersText = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('span', { equalsText: 'Game Owners' }).parent().getText() .replace('Game Owners', '') .replace(/,/g, ''); const gameOwners = parseInt(gameOwnersText, 10); const allDlcHeaders = (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('div[id^="DLC-"]'); // For each DLC allDlcHeaders.forEach(dlcHeader => { const dlcTable = dlcHeader.clone().next(); const dlcOwnersText = dlcTable.clone().find('span.typo-top').getText().replace(/,/g, ''); const dlcOwners = parseInt(dlcOwnersText, 10); // Process each trophy (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('td.hover-hide span.rarity', {}, dlcTable.get()).forEach(raritySpan => { const pctSpan = raritySpan.clone().find('span.typo-top'); const rarityText = pctSpan.getText().replace('%', ''); const rarityValue = parseFloat(rarityText) / 100; const newValue = (Math.sqrt(gameOwners * dlcOwners) * rarityValue) / gameOwners * 100; const newValueText = newValue.toFixed(2) + '%'; raritySpan.setAttribute('data-rarity', newValueText); raritySpan.setAttribute('data-rarity-type', getRarityType(newValue)); }); }); } _swapDlcRarities() { (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('span[data-rarity]').forEach(raritySpan => { const typoTop = raritySpan.clone().find('span.typo-top'); const typoBottom = raritySpan.clone().find('span.typo-bottom nobr'); const toSwapRarity = raritySpan.getAttribute('data-rarity'); const toSwapRarityType = raritySpan.getAttribute('data-rarity-type'); const toStoreRarity = typoTop.getText(); const toStoreRarityType = typoBottom.getText(); typoTop.setText(toSwapRarity); typoBottom.setText(toSwapRarityType); raritySpan.setAttribute('data-rarity', toStoreRarity); raritySpan.setAttribute('data-rarity-type', toStoreRarityType); }); } _markUnobtainableTrophies() { if (!new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_5__.SettingsStorage().get('markUnobtainableTrophies')) { return; } const utStorage = new _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_11__.UnobtainableTrophiesStorage(); const unobtainableTrophies = utStorage.getByTrophyListId(this._trophyListId); if (unobtainableTrophies == null) { return; } let showDetails = false; let detailsLoaded = false; const detailsContainer = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .setAttribute('id', 'psnpp-unobtainable-trophies-details-container') .setAttribute('style', 'text-align: left; font-size: 13px;') .hide(); const unobtainablesToggle = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', '#') .setAttribute('target', '_blank') .setText('Show details') .click((e, el) => { e.preventDefault(); showDetails = !showDetails; if (showDetails) { el.setText('Hide details'); this._getAllTrophyRows() .forEach(row => { const isUnobtainable = row.clone().find('picture.unobtainable').exists(); if (!isUnobtainable) { row.addClass('psnpp-hide'); } }); if (!detailsLoaded) { detailsLoaded = true; detailsContainer .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('i') .addClass('fa', 'fa-spinner', 'fa-spin', 'fa-fw') .setAttribute('aria-hidden', 'true')); (0,_util_fetch__WEBPACK_IMPORTED_MODULE_23__.fetchJson)(_util_constants__WEBPACK_IMPORTED_MODULE_14__.LINK_UNOBTAINABLE_TROPHIES_MASTER_LIST_FULL) .then(result => { detailsContainer.empty(); const details = result.list[this._trophyListId]; if (details == null) { detailsContainer .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span').setText('Details not found. PSNP+ is most likely showing outdated information which will disappear in the next 24 hours.')); return; } detailsContainer .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('b').setText('Submitted by:'), ' ', details.submitter == null ? '-' : _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a').setAttribute('href', '/' + details.submitter).setText(details.submitter), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('b').setText('Date:'), ' ', details.timestamp == null ? '-' : new Date(details.timestamp).toString(), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('b').setText('Note:'), ' '); if (details.note == null) { detailsContainer.append('-'); } else { detailsContainer.append(...(0,_util_linkify__WEBPACK_IMPORTED_MODULE_25__.linkifyText)(details.note)); } detailsContainer .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', '/games' + _util_constants__WEBPACK_IMPORTED_MODULE_14__.HASH_UNOBTAINABLES) .setText('[ All games with unobtainable trophies ]'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', _util_constants__WEBPACK_IMPORTED_MODULE_14__.LINK_UNOBTAINABLE_TROPHIES_THREAD) .setAttribute('target', '_blank') .setText('[ You can report outdated information in our forum thread ]')); }) .catch(e => { alert('Failed to load details: ' + e.message); }); } detailsContainer.show(); } else { el.setText('Show details'); detailsContainer.hide(); (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('div.col-xs table.zebra tr').forEach(row => row.removeClass('psnpp-hide')); } }); _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div#content > .row > .col-xs').prepend(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .addClass('box', 'information', 'center') .setAttribute('style', 'padding: 10px; font-size: 15px; line-height: 15px; margin-bottom: 10px;') .setCss('backgroundColor', _util_constants__WEBPACK_IMPORTED_MODULE_14__.COLOR_LIGHT_ORANGE) .setCss('border', `2px solid ${_util_constants__WEBPACK_IMPORTED_MODULE_14__.COLOR_DARK_ORANGE}`) .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('b').setText('WARNING: '), (0,_features_unobtainables_unobtainables_utils__WEBPACK_IMPORTED_MODULE_13__.getUnobtainableTrophiesDescription)(unobtainableTrophies), ' ', _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('bullet').setText('•'), ' ', unobtainablesToggle, detailsContainer)); const allValidRows = (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('#content.page > div.row > div.col-xs tr') .filter(e => { const platinumImage = e.clone().find('img[title="Platinum"]').exists(); const goldImage = e.clone().find('img[title="Gold"]').exists(); const silverImage = e.clone().find('img[title="Silver"]').exists(); const bronzeImage = e.clone().find('img[title="Bronze"]').exists(); return platinumImage || goldImage || silverImage || bronzeImage; }); allValidRows.forEach(row => { const trophyId = parseInt(row.clone().find('a').getAttribute('href').split('/')[3].split('-')[0], 10); if (unobtainableTrophies.indexOf(trophyId) > -1 || unobtainableTrophies[0] === 0) { const isCompleted = row.hasClass('completed'); row.clone().find('picture').setCss('borderColor', _util_constants__WEBPACK_IMPORTED_MODULE_14__.COLOR_DARK_ORANGE).addClass('unobtainable'); if (!isCompleted) { (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('td', {}, row.get()).forEach(td => td.setCss('backgroundColor', _util_constants__WEBPACK_IMPORTED_MODULE_14__.COLOR_LIGHT_ORANGE)); } } }); } _refreshListItem() { const newScrape = new _features_lists_ListScraper__WEBPACK_IMPORTED_MODULE_0__.ListScraper(document).getFromTrophiesPage(); const refreshed = new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_6__.ListStorage().refreshGame(newScrape); if (refreshed) { _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div.game-image-holder') .after(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .setAttribute('style', 'background: #ecf8ea; color: #61bf19; text-align: center; border: 2px solid #e3e3e6; padding: 5px;') .setText('List data has been refreshed') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'PSNP+ automatically refreshes data (such as platinum rate, guide availability, etc.) every time you visit a trophy list that is included in any of your game lists.'))); } } async _refreshGuideInfo() { if (!new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_5__.SettingsStorage().get('guideScrapeComplexity')) { return; } const guideBanner = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div.guide-page-info'); const trophyGuideExists = guideBanner.exists(); if (trophyGuideExists) { const guideStorage = new _features_guide_GuideStorage__WEBPACK_IMPORTED_MODULE_22__.GuideStorage(); if (!guideStorage.shouldUpdate(this._trophyListId)) { return; } const trophyGuideUrl = guideBanner.clone().find('a').getAttribute('href'); try { const guideItem = await _features_guide_GuideScraper__WEBPACK_IMPORTED_MODULE_21__.GuideScraper.getFromUrl(trophyGuideUrl, this._trophyListId); guideStorage.add(guideItem); _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div.game-image-holder') .after(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .setAttribute('style', 'background: #ecf8ea; color: #61bf19; text-align: center; border: 2px solid #e3e3e6; padding: 5px;') .setText('Guide data has been collected') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_20__.tooltip)(el, 'PSNP+ automatically collects guide data (difficulty, completion time and playthroughs) every time you visit a trophy list but only once every 24 hours for each game.'))); } catch (e) { this._logger.error('Failed to scrape guide info', e); } } } _insertMenu() { const psnRarityElementIsVisible = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('td.hover-hide nobr img.icon-sprite.rarity').exists(); const atLeastOneDlcExists = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div#DLC-1').exists(); const shouldAppendDlcRaritiesButton = !psnRarityElementIsVisible && atLeastOneDlcExists; const psnIdToUse = this._psnId == null ? (0,_util_user__WEBPACK_IMPORTED_MODULE_8__.getPsnId)() : this._psnId; const toggleDlcRaritiesButton = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', '#') .addClass('button', 'grey') .setAttribute('style', 'margin-top: 5px;') .setText('🔴 Global DLC rarities') .click((e) => { e.preventDefault(); this._showGeometricMeanRarity = !this._showGeometricMeanRarity; if (this._showGeometricMeanRarity) { toggleDlcRaritiesButton.setText('🔴 Global DLC rarities'); } else { toggleDlcRaritiesButton.setText('🟢 Global DLC rarities'); } this._swapDlcRarities(); this._appendRarityBox(); this._appendAverageRarity(); }); const refreshProgressButton = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', '#') .addClass('button', 'grey') .setText('Refresh progress') .setAttribute('href', (0,_util_user__WEBPACK_IMPORTED_MODULE_8__.getUpdateProfileRedirectUrl)(psnIdToUse, location.pathname)); const menuWrapper = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .append(refreshProgressButton, shouldAppendDlcRaritiesButton ? _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br') : null, shouldAppendDlcRaritiesButton ? toggleDlcRaritiesButton : null); const floatingMenu = new _ui_FloatingMenu__WEBPACK_IMPORTED_MODULE_2__.FloatingMenu(menuWrapper); floatingMenu.insert(); } _isCompareMode() { return _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('meta[property="og:title"]').getAttribute('content').startsWith('Comparing '); } _isComparePlusMode() { return location.hash.startsWith(_util_constants__WEBPACK_IMPORTED_MODULE_14__.HASH_COMPARE_PLUS); } async _startComparePlus() { _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('div.col-xs-4.col-xs-max-320').remove(); _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#content div.button-bar.flex').remove(); const trophyListUrl = _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('meta[property="og:url"]').getAttribute('content'); const urlParams = (0,_util_url__WEBPACK_IMPORTED_MODULE_9__.getSearchParamsFromHash)(); const psnIds = urlParams.getAll('psnId').slice(0, 4); _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#content div.col-xs').prepend(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('div') .setAttribute('style', 'display: block; text-align: center; font-size: 20px; margin-bottom: 10px;') .setAttribute('id', 'psnpp-compare-plus-loading') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('h3').setText('[Compare+] Loading... (0 / ' + psnIds.length + ')'))); const results = []; for (const [index, psnId] of psnIds.entries()) { const url = trophyListUrl + '/' + psnId + '?order=psn'; const result = await _features_compare_plus_TrophyListProgressScraper__WEBPACK_IMPORTED_MODULE_15__.TrophyListProgressScraper.getFromUrl(url); if (result != null) { results.push(result); } _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-compare-plus-loading h3').setText('[Compare+] Loading... (' + (index + 1) + ' / ' + psnIds.length + ')'); if (index + 1 < psnIds.length) { await (0,_util_promise__WEBPACK_IMPORTED_MODULE_16__.sleep)(1000); } } if (results.length < 2) { _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-compare-plus-loading h3').setText('[Compare+] Unable to load player data.'); } else { _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#psnpp-compare-plus-loading').remove(); } // Progress boxes results.forEach((res, index) => { if (index <= 1) { _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#content table.box', { eq: index }).find('a.title').setAttribute('href', res.url + '/' + res.username); } else { _util_J__WEBPACK_IMPORTED_MODULE_3__.J.q('#content table.box', { eq: index - 1 }).after(new _features_compare_plus_ProgressBox__WEBPACK_IMPORTED_MODULE_17__.ProgressBox(res)); } }); (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('div.box.no-top-border').forEach((subList, index) => { const table = results[0].dlcCount === 0 ? subList.clone().find('table.zebra') : index === 0 ? subList.clone().find('table.zebra', { eq: 2 }) : subList.clone().find('table.zebra', { eq: 1 }); const playerRow = results[0].dlcCount === 0 ? table.clone().find('tr') : table.clone().find('tr', { eq: 1 }); playerRow .append(...results.filter((_res, index) => index > 1).map(res => { return _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td') .addClass('center') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .addClass('separator', 'left') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .setAttribute('href', '/' + res.username) .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('img') .addClass('trophy', 'md') .setAttribute('style', 'margin-bottom: 5px;') .setAttribute('src', res.avatar)), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('nobr') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('a') .addClass('title') .setAttribute('href', '/' + res.username) .setText(res.username)))); })); (0,_util_J__WEBPACK_IMPORTED_MODULE_3__.all)('tr', {}, subList.get()).slice(results[0].dlcCount === 0 ? 1 : 3).forEach(row => { const trophyPath = row.clone().find('a.title').getAttribute('href'); const trophyId = parseInt([...trophyPath.matchAll(/\/([0-9]+)-/g)][1][1], 10); const trophyIndex = trophyId - 1; row.clone().find('td', { eq: 5 }).remove(); row.clone().find('td', { eq: 4 }).remove(); row .append(...results.map(res => { const currentTrophy = res.trophies[trophyIndex]; return _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('td') .append(currentTrophy.completed ? _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .addClass('separator', 'left') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('img') .setAttribute('alt', 'earned') .setAttribute('title', currentTrophy.trophyGrade) .setAttribute('src', `/lib/img/icons/40-${currentTrophy.trophyGrade}.png`), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('small') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('b') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('center') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .addClass('typo-top-date') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('nobr') .append(...(0,_util_date__WEBPACK_IMPORTED_MODULE_19__.formatStringToSupDate)(currentTrophy.date))), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .addClass('typo-bottom-date') .append(_util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('nobr') .setText(currentTrophy.time)))))) : _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('span') .addClass('separator', 'left') .append(currentTrophy.progress !== '' ? _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('b') .setAttribute('style', 'font-size: 18px;') .setText(currentTrophy.progress) : _util_J__WEBPACK_IMPORTED_MODULE_3__.J.c('img') .setAttribute('alt', 'unearned') .setAttribute('src', '/lib/img/icons/40-lock.png'))); })); }); }); } _switchHoursTo24HourFormat() { if (!new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_5__.SettingsStorage().get('use24HourTimeFormat')) { return; } (0,_util_date__WEBPACK_IMPORTED_MODULE_19__.switchHoursTo24HourFormat)(); } async run() { this._logger.debug('Running'); if (this._isCompareMode()) { if (this._isComparePlusMode()) { this._startComparePlus(); } return; } this._switchHoursTo24HourFormat(); this._removeMetadataByAttribution(); this._appendCompareLink(); this._appendListButton(); this._appendTrophiesAndPointsEarnedSoFar(); this._appendRarityBox(); // Sidebar this._appendAverageRarity(); this._appendComplexity(); this._appendSearchLinks(); this._appendPrices(); this._appendForumLoaderButton(); this._markUnobtainableTrophies(); await this._appendComparePlusBox(); this._appendCreateUnobtainablesReport(); this._updateSeriesLink(); this._modifyRecentPlayers(); this._refreshListItem(); this._refreshGuideInfo(); this._recalcDlcRarities(); this._insertMenu(); } } /***/ }), /* 75 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "TrophyListProgressScraper": () => (/* binding */ TrophyListProgressScraper) /* harmony export */ }); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); class TrophyListProgressScraper { constructor(doc) { this._doc = doc; } _q(query, options = {}) { return _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q(query, options, this._doc); } _getProgressBox() { return this._q('#content table.box'); } _allTrophyRows() { return (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('#content.page > div.row > div.col-xs tr', {}, this._doc) .filter(e => e.clone().find('img[title="Platinum"], img[title="Gold"], img[title="Silver"], img[title="Bronze"]').exists()); } getFromTrophiesPage() { const hasProgress = this._q('#content div.col-xs table.box div.progress-bar').exists(); if (!hasProgress) { return null; } const url = this._q('meta[property="og:url"]').getAttribute('content'); const username = this._q('.title-bar').find('a').getText(); const avatar = this._q('#content img.trophy').getAttribute('src'); const lastActive = this._getProgressBox().find('span.small-info').getText().trim().replace(/[0-9]{1,2} of [0-9]{1,3} Trophies/, '').trim(); const rank = this._getProgressBox().find('span.game-rank').getText(); const progress = this._getProgressBox().find('div.progress-bar span').getText(); const dlcCount = (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('[id^="DLC-"]', {}, this._doc).length; const trophies = this._allTrophyRows().map((row, index) => { const subListName = row .clone() .parent() .parent() .parent() .find('span.title') .getText() .trim(); const subListIcon = row.clone().parent().parent().parent().find('img').getAttribute('src'); const completed = row.hasClass('completed'); const image = row.clone().find('picture > img').getAttribute('src'); const path = row.clone().find('a.title').getAttribute('href'); const name = row.clone().find('a.title').getText(); const description = row .clone() .find('td', { eq: 1 }) .getText() .replace(name, '') .replace(/[\t\n\r]/g, ''); const date = row.clone().find('span.typo-top-date').getText(); const time = row.clone().find('span.typo-bottom-date').getText(); const progress = row.clone().find('span.typo-top').getText().includes('/') ? row.find('span.typo-top').getText() : ''; const trophyGrade = row .clone() .find('img[title="Platinum"], img[title="Gold"], img[title="Silver"], img[title="Bronze"]') .getAttribute('title') .toLowerCase(); const trophyGradeIcon = row .clone() .find('img[title="Platinum"], img[title="Gold"], img[title="Silver"], img[title="Bronze"]') .getAttribute('src'); const rarity = row.clone().find('td.hover-hide span.typo-top').getText(); const rarityGrade = row.clone().find('td.hover-hide span.typo-bottom').getText(); return { id: index + 1, subListName, subListIcon, completed, image, path, name, description, date, time, progress, rarity, rarityGrade, trophyGrade, trophyGradeIcon }; }); return { url, username, avatar, lastActive, rank, progress, dlcCount, trophies }; } static async getFromUrl(url) { const doc = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_0__.fetchDocument)(url); return new TrophyListProgressScraper(doc).getFromTrophiesPage(); } } /***/ }), /* 76 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "ProgressBox": () => (/* binding */ ProgressBox) /* harmony export */ }); /* harmony import */ var _util_date__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(53); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); class ProgressBox extends _util_J__WEBPACK_IMPORTED_MODULE_1__.JC { constructor(trophyListProgress) { super('table'); this._progress = trophyListProgress; this._build(); } _build() { this .addClass('box') .setAttribute('style', 'margin-bottom: 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tbody') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tr') .condition(this._progress.trophies.some(t => t.trophyGrade === 'platinum' && t.completed), el => el.addClass('platinum')) .condition(!this._progress.trophies.some(t => t.trophyGrade === 'platinum') && this._progress.trophies.every(t => t.completed), el => el.addClass('completed')) .append( // 1 _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '/' + this._progress.username) .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('img') .addClass('trophy') .setAttribute('src', this._progress.avatar))), // 2 _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .setAttribute('style', 'width: 100%;') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .addClass('title') .setAttribute('href', this._progress.url + '/' + this._progress.username) .setAttribute('rel', 'nofollow') .setText(this._progress.username), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .addClass('small-info') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('b') .setText(this._progress.trophies.filter(x => x.completed).length.toString()), ' of ', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('b') .setText(this._progress.trophies.length.toString()), ' Trophies', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), ...(0,_util_date__WEBPACK_IMPORTED_MODULE_0__.formatStringToSupDate)(this._progress.lastActive))), // 3 _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('center') .setAttribute('style', 'padding: 0 10px; border-right: 1px solid #dddddd;') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .addClass('game-rank', this._progress.rank) .setText(this._progress.rank), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .addClass('typo-bottom') .setText('RANK'))), // 4 _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .addClass('separator') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('img') .setAttribute('width', '21') .condition(this._progress.trophies.some(x => x.trophyGrade === 'platinum'), el => { el.setAttribute('src', `/lib/img/icons/platinum-icon${this._progress.trophies.some(t => t.trophyGrade === 'platinum' && t.completed) ? '' : '-off'}.png`); }) .condition(!this._progress.trophies.some(x => x.trophyGrade === 'platinum'), el => { el.setAttribute('src', `/lib/img/icons/complete-icon${this._progress.trophies.every(t => t.completed) ? '' : '-off'}.png`); }))), // 5 _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .addClass('separator', 'left') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .addClass('trophy-count') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('ul') .addClass('floatr') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('li') .addClass('icon-sprite', 'gold') .setText(this._progress.trophies.filter(t => t.trophyGrade === 'gold' && t.completed).length.toString()), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('li') .addClass('icon-sprite', 'silver') .setText(this._progress.trophies.filter(t => t.trophyGrade === 'silver' && t.completed).length.toString()), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('li') .addClass('icon-sprite', 'bronze') .setText(this._progress.trophies.filter(t => t.trophyGrade === 'bronze' && t.completed).length.toString())), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .addClass('progress-bar') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .setText(this._progress.progress), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .setAttribute('style', `width: ${this._progress.progress};`)))))))); } } /***/ }), /* 77 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "TrophiesImmediate": () => (/* binding */ TrophiesImmediate) /* harmony export */ }); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5); /* harmony import */ var _util_stylesheet__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(49); class TrophiesImmediate { run() { console.debug('TrophiesImmediate module is running'); if (new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_0__.SettingsStorage().get('trophyListHideTrophyGuideBanner')) { (0,_util_stylesheet__WEBPACK_IMPORTED_MODULE_1__.injectStylesheet)(_util_stylesheet__WEBPACK_IMPORTED_MODULE_1__.STYLESHEET_TROPHIES_HIDE_GUIDE_BANNER); } } } /***/ }), /* 78 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "GameLeaderboard": () => (/* binding */ GameLeaderboard) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(12); /* harmony import */ var _util_date__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(53); class GameLeaderboard { constructor(settingsStorage) { this._settingsStorage = settingsStorage; } _highlightPlayers(countries) { let count = 0; (0,_util_J__WEBPACK_IMPORTED_MODULE_0__.all)('tr').forEach((el) => { const country = el.clone().find('img.round-flags').getAttribute('title'); if (countries.indexOf(country) > -1) { count++; el.setCss('backgroundColor', 'rgb(236, 248, 234)'); } }); _util_J__WEBPACK_IMPORTED_MODULE_0__.J.q('div.title-bar > div.grow').append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('h3').setText(`(Highlighted: ${count})`)); } _adjustPlayerLinks() { const url = (0,_util_url__WEBPACK_IMPORTED_MODULE_1__.getUrl)(); const trophyList = url .replace('game-leaderboard', 'trophies') .replace(/\?page=[0-9]+$/, ''); (0,_util_J__WEBPACK_IMPORTED_MODULE_0__.all)('tr').forEach((el) => { const usernameLink = el.clone().find('a.title'); const usernameHref = usernameLink.getAttribute('href'); usernameLink.setAttribute('href', trophyList + usernameHref); }); } _switchHoursTo24HourFormat() { if (!this._settingsStorage.get('use24HourTimeFormat')) { return; } (0,_util_date__WEBPACK_IMPORTED_MODULE_2__.switchHoursTo24HourFormat)(); } run() { console.debug('Game Leaderboard module is running'); this._switchHoursTo24HourFormat(); this._highlightPlayers(this._settingsStorage.get('gameLeaderboardHighlightedCountries')); this._adjustPlayerLinks(); } } /***/ }), /* 79 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Games": () => (/* binding */ Games) /* harmony export */ }); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _features_lists_ListButtons__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(72); /* harmony import */ var _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(21); /* harmony import */ var _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8); /* harmony import */ var _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(20); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(25); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(5); /* harmony import */ var _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(24); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(34); /* harmony import */ var _features_unobtainables_unobtainables_utils__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(64); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(13); /* harmony import */ var _util_linkify__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(65); class Games { constructor() { const listStorage = new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_4__.ListStorage(); const scriptStateStorage = new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_3__.ScriptStateStorage(); const allLists = listStorage.get(); this._lastActiveGameList = scriptStateStorage.get('lastActiveGameList'); if (this._lastActiveGameList == null && allLists.length > 0) { this._lastActiveGameList = allLists[0].id; } } _appendListButtons() { if (this._lastActiveGameList == null) { return; } (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('table#game_list tr').forEach((el) => { const pathname = el.clone().find('a.title').getAttribute('href'); const trophyListId = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getFirstLevelIdFromPathname)(pathname); const trophyListUrl = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getWebsiteUrl)() + pathname; el.append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .addClass('separator', 'left') .append(new _features_lists_ListButtons__WEBPACK_IMPORTED_MODULE_2__.ListButtonSmall(trophyListId, trophyListUrl, this._lastActiveGameList, 'psnpp-list-button')))); }); } _addProgress() { const gameProgressStorage = new _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_5__.GameProgressStorage(); const gameProgressList = gameProgressStorage.indexedById(); (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('table#game_list tr').forEach(el => { const pathname = el.clone().find('a.title').getAttribute('href'); const trophyListId = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getFirstLevelIdFromPathname)(pathname); const gameProgress = gameProgressList.get(trophyListId); if (gameProgress == null) { return; } el.clone().find('a.title').setCss('fontWeight', 'bold'); if (gameProgress.trophies != null && gameProgress.trophies.platinum === 1) { el.addClass('platinum'); } else if (gameProgress.progress === 100) { el.addClass('completed'); } else { // NOTE: Game was found in the profile, let's mark it el.setCss('backgroundColor', _util_constants__WEBPACK_IMPORTED_MODULE_6__.COLOR_LIGHT_YELLOW); } }); } _enhanceRowsWithUnobtainableTrophies() { if (!new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_7__.SettingsStorage().get('markUnobtainableTrophies')) { return; } const unobtainableTrophies = new _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_8__.UnobtainableTrophiesStorage().get(); (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('table#game_list tr').forEach(el => { const trophyListPathname = el.clone().find('a.title').getAttribute('href'); const trophyListId = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getFirstLevelIdFromPathname)(trophyListPathname); const unobtainableTrophiesForList = unobtainableTrophies.data.list[trophyListId]; if (unobtainableTrophiesForList == null) { return; } const titleSpan = el.clone().find('td', { eq: 1 }).find('span'); titleSpan .append(' ', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('i') .addClass('fa', 'fa-exclamation-circle', 'marker-unobtainable-trophies') .setAttribute('aria-hidden', 'true') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_9__.tooltip)(el, (0,_features_unobtainables_unobtainables_utils__WEBPACK_IMPORTED_MODULE_10__.getUnobtainableTrophiesDescription)(unobtainableTrophiesForList)))); }); } _appendSeriesLink() { _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('div.banner-overlay div.navigation') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('li') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '/series') .setText('Series')), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('li') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#unobtainables') .setText('Unobtainables'))); } async _showGamesWithUnobtainableTrophies() { try { await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_11__.loadCssSheet)(_util_constants__WEBPACK_IMPORTED_MODULE_6__.EXTERNAL_SCRIPT_URLS.DATA_TABLES_CSS); await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_11__.loadScriptTag)(_util_constants__WEBPACK_IMPORTED_MODULE_6__.EXTERNAL_SCRIPT_URLS.DATA_TABLES_JS); (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('div.banner-overlay div.no-shrink').forEach(x => x.remove()); _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('#content').empty(); _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('div.title-bar > div.grow') .empty() .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('h3').setText('Games with unobtainable trophies')); const result = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_11__.fetchJson)(_util_constants__WEBPACK_IMPORTED_MODULE_6__.LINK_UNOBTAINABLE_TROPHIES_MASTER_LIST_FULL); _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('#content') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('table') .setAttribute('id', 'unobtainables-table') .setAttribute('style', 'border-collapse: collapse;') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('thead') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tr') .setAttribute('style', 'border-bottom: 2px solid black; font-weight: bold;') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('th').setText('List ID'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('th').setText('Title'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('th').setText('# of Trophies'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('th').setText('Platforms'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('th').setText('Submitted by'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('th').setText('Note'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('th').setText('Date'))), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tbody') .append(...Object.keys(result.list).reverse().map((id, index) => { const resultRow = result.list[id]; const row = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('tr') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td').setText(id), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td').append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '/trophies/' + id) .setText(resultRow.title)), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td').setText(resultRow.trophies[0] === 0 ? 'all' : resultRow.trophies.length.toString()), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td').setText(resultRow.platforms.join(', ')), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td').append(resultRow.submitter == null ? '-' : _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a').setAttribute('href', '/' + resultRow.submitter).setText(resultRow.submitter))); if (resultRow.note == null) { row.append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td').setText('-')); } else { row.append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td').append(...(0,_util_linkify__WEBPACK_IMPORTED_MODULE_12__.linkifyText)(resultRow.note))); } row .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .setAttribute('data-order', resultRow.timestamp == null ? '0' : resultRow.timestamp.toString()) .setText(resultRow.timestamp == null ? '-' : new Date(resultRow.timestamp).toString())); return row; })))); new DataTable('#unobtainables-table', { order: [[0, 'desc']], pagingType: 'full_numbers' }); } catch (err) { alert('Failed to load unobtainables: ' + err.message); } } _observeHash() { window.addEventListener('hashchange', () => this._processHash()); } _processHash() { if (location.hash.startsWith(_util_constants__WEBPACK_IMPORTED_MODULE_6__.HASH_UNOBTAINABLES)) { this._showGamesWithUnobtainableTrophies(); return; } } run() { console.debug('Games module is running'); this._observeHash(); this._processHash(); if (this._lastActiveGameList != null) { this._appendListButtons(); } this._appendSeriesLink(); this._addProgress(); this._enhanceRowsWithUnobtainableTrophies(); } } /***/ }), /* 80 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Search": () => (/* binding */ Search) /* harmony export */ }); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _util_observe__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(35); /* harmony import */ var _features_lists_ListButtons__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(72); /* harmony import */ var _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(21); /* harmony import */ var _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(8); /* harmony import */ var _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(20); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(25); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(5); /* harmony import */ var _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(24); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(34); /* harmony import */ var _features_unobtainables_unobtainables_utils__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(64); /* harmony import */ var _util_Logger__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(47); const LIST_BUTTON_CLASS = 'psnpp-list-button'; class Search { constructor(section) { this._section = section; this._settingsStorage = new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_8__.SettingsStorage(); this._logger = new _util_Logger__WEBPACK_IMPORTED_MODULE_12__.Logger(this._settingsStorage.get('enableScriptLogger'), 'Search'); const listStorage = new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_5__.ListStorage(); const scriptStateStorage = new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_4__.ScriptStateStorage(); const gameProgressStorage = new _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_6__.GameProgressStorage(); this._gameProgressList = gameProgressStorage.indexedById(); const allLists = listStorage.get(); this._lastActiveGameList = scriptStateStorage.get('lastActiveGameList'); if (this._lastActiveGameList == null && allLists.length > 0) { this._lastActiveGameList = allLists[0].id; } } _appendRefineSearchButton() { const searchForm = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('#content > div.form'); searchForm.setAttribute('style', 'margin-bottom: 10px; display: flex;'); searchForm.clone().find('label').setAttribute('style', 'width: 90%;'); searchForm.clone().find('label') .after(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .addClass('button', 'green') .setAttribute('style', 'width: 10%;margin: auto 0 auto 20px;padding-top: 6px;height: fit-content;') .setText('Refine') .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_10__.tooltip)(el, 'Refined search provides narrowed-down results that are more accurate in most cases.')) .click((e) => { e.preventDefault(); const searchBox = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('#search'); const oldValue = searchBox.getValue().replace(/[ ]{2,}/g, ' ').trim(); this._logger.debug('Old search value:', oldValue); if (oldValue.includes(' AND ')) { alert('Search value is already refined.'); return; } const newValue = oldValue.split(' ').length === 1 ? `OR ${oldValue} OR` : oldValue.split(' ').join(' AND '); this._logger.debug('New search value:', newValue); searchBox.setValue(newValue); searchBox.triggerKeypress('Enter'); })); } _appendListButtons() { if (this._lastActiveGameList == null) { return; } (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('#search-results tr').forEach((el) => { const alreadyAdded = el.clone().find('.' + LIST_BUTTON_CLASS).exists(); if (alreadyAdded) { return; } const pathname = el.clone().find('a.title').getAttribute('href'); const trophyListId = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getFirstLevelIdFromPathname)(pathname); const trophyListUrl = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getWebsiteUrl)() + pathname; el.append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .addClass('separator', 'left') .append(new _features_lists_ListButtons__WEBPACK_IMPORTED_MODULE_3__.ListButtonSmall(trophyListId, trophyListUrl, this._lastActiveGameList, LIST_BUTTON_CLASS)))); }); } _addProgress() { (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('#search-results tr').forEach((el) => { const pathname = el.clone().find('a.title').getAttribute('href'); const trophyListId = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getFirstLevelIdFromPathname)(pathname); const gameProgress = this._gameProgressList.get(trophyListId); if (gameProgress == null) { return; } el.clone().find('a.title').setCss('fontWeight', 'bold'); if (gameProgress.trophies != null && gameProgress.trophies.platinum === 1) { el.addClass('platinum'); } else if (gameProgress.progress === 100) { el.addClass('completed'); } else { // NOTE: Game was found in the profile, let's mark it el.setCss('backgroundColor', _util_constants__WEBPACK_IMPORTED_MODULE_7__.COLOR_LIGHT_YELLOW); } }); } _enhanceRowsWithUnobtainableTrophies() { if (!new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_8__.SettingsStorage().get('markUnobtainableTrophies')) { return; } const unobtainableTrophies = new _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_9__.UnobtainableTrophiesStorage().get(); (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('#search-results tr') .filter(el => el.getAttribute('data-psnpp-unobtainable-processed') !== 'true') .forEach(el => { const trophyListPathname = el.clone().find('a.title').getAttribute('href'); const trophyListId = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getFirstLevelIdFromPathname)(trophyListPathname); el.setAttribute('data-psnpp-unobtainable-processed', 'true'); const unobtainableTrophiesForList = unobtainableTrophies.data.list[trophyListId]; if (unobtainableTrophiesForList == null) { return; } const titleBr = el.clone().find('td', { eq: 1 }).find('br'); titleBr .before(' ', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('i') .addClass('fa', 'fa-exclamation-circle', 'marker-unobtainable-trophies') .setAttribute('aria-hidden', 'true') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_10__.tooltip)(el, (0,_features_unobtainables_unobtainables_utils__WEBPACK_IMPORTED_MODULE_11__.getUnobtainableTrophiesDescription)(unobtainableTrophiesForList)))); }); } _observeSearchResults() { const destroy = (0,_util_observe__WEBPACK_IMPORTED_MODULE_2__.observe)(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('#search-results'), () => { destroy(); this._appendListButtons(); this._enhanceRowsWithUnobtainableTrophies(); this._addProgress(); this._observeSearchResults(); }); } run() { this._logger.debug('Running'); // NOTE: Missing search section defaults to "games" if (this._section !== 'games' && this._section != null) { return; } this._appendRefineSearchButton(); this._appendListButtons(); this._enhanceRowsWithUnobtainableTrophies(); this._addProgress(); this._observeSearchResults(); } } /***/ }), /* 81 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Sessions": () => (/* binding */ Sessions) /* harmony export */ }); /* harmony import */ var _ui_DropdownMenu__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(58); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _ui_SearchBox__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(59); /* harmony import */ var _features_sessions_SessionScraper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(18); /* harmony import */ var _util_user__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(19); /* harmony import */ var _util_transform__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(16); /* harmony import */ var _ui_FloatingMenu__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(51); /* harmony import */ var _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(20); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(12); const HOST_ANYONE_VALUE = '__psnpp__anyone__'; const HOST_ME_VALUE = '__psnpp__me__'; class Sessions { constructor() { this._hideFinished = false; this._hidePlatinumed = false; this._host = HOST_ANYONE_VALUE; this._platform = 'all'; this._searchValue = ''; this._sessions = []; this._gameProgress = new _features_game_progress_GameProgressStorage__WEBPACK_IMPORTED_MODULE_7__.GameProgressStorage().indexedByCdnCode(); } _getPlatformsDropdown() { return new _ui_DropdownMenu__WEBPACK_IMPORTED_MODULE_0__.DropdownMenu({ mainButton: 'Platform', mainButtonIconClass: 'platform', options: [ { text: 'All', value: 'all', selected: true }, { text: 'PlayStation 5', value: 'ps5', selected: false }, { text: 'PlayStation 4', value: 'ps4', selected: false }, { text: 'PlayStation 3', value: 'ps3', selected: false }, { text: 'PlayStation Vita', value: 'psvita', selected: false }, { text: 'PlayStation VR', value: 'psvr', selected: false } ], onSelected: (platform) => { this._platform = platform; this._filterSessions(); } }); } _getHostDropdown() { const usernames = (0,_util_transform__WEBPACK_IMPORTED_MODULE_5__.unique)(this._sessions.map(x => x.session.host)) .sort((a, b) => a.localeCompare(b)); return new _ui_DropdownMenu__WEBPACK_IMPORTED_MODULE_0__.DropdownMenu({ mainButton: 'Host', mainButtonIconClass: 'language', options: [ { text: 'Anyone', value: HOST_ANYONE_VALUE, selected: true }, { text: 'Me', value: HOST_ME_VALUE, selected: false }, 'divider', ...usernames.map(username => ({ text: username, value: username, selected: false })) ], onSelected: (host) => { this._host = host; this._filterSessions(); } }); } _filterSessions() { const platform = this._platform; const searchValue = this._searchValue; const host = this._host; const myUsername = (0,_util_user__WEBPACK_IMPORTED_MODULE_4__.getPsnId)(); this._sessions.forEach(session => { var _a; const sessionItem = session.session; const gameProgressItem = this._gameProgress.get((0,_util_url__WEBPACK_IMPORTED_MODULE_8__.getCdnCodeFromImageUrl)(sessionItem.image)); const titleMatchSearch = sessionItem.title.toLowerCase().indexOf(searchValue.toLowerCase()) > -1; const hostMatchSearch = sessionItem.host.toLowerCase().indexOf(searchValue.toLowerCase()) > -1; const platformMatch = platform === 'all' || sessionItem.platforms[platform] === true; const hostMatch = host === HOST_ANYONE_VALUE || (host === HOST_ME_VALUE && sessionItem.host === myUsername) || host === sessionItem.host; const isHiddenViaFinishedToggle = this._hideFinished && (gameProgressItem === null || gameProgressItem === void 0 ? void 0 : gameProgressItem.progress) === 100; const isHiddenViaPlatinumToggle = this._hidePlatinumed && ((_a = gameProgressItem === null || gameProgressItem === void 0 ? void 0 : gameProgressItem.trophies) === null || _a === void 0 ? void 0 : _a.platinum) === 1; const shouldBeVisible = (titleMatchSearch || hostMatchSearch) && platformMatch && hostMatch && !isHiddenViaFinishedToggle && !isHiddenViaPlatinumToggle; if (shouldBeVisible) { session.el.show(); } else { session.el.hide(); } }); } _appendDropdowns() { _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('div.row > div.col-xs-12 > div.title.flex.v-align > div.no-shrink') .prepend(this._getHostDropdown(), this._getPlatformsDropdown()); } _appendSearchBox() { _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('div.row > div.col-xs-12 > div.title.flex.v-align') .after(new _ui_SearchBox__WEBPACK_IMPORTED_MODULE_2__.SearchBox('Search by game or host', value => { this._searchValue = value; this._filterSessions(); })); } _scrapeSessions() { this._sessions = new _features_sessions_SessionScraper__WEBPACK_IMPORTED_MODULE_3__.SessionScraper(document).getFromSessionsPageWithElements(); } _insertMenu() { const menuWrapper = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div'); const togglePlatinumedButton = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .addClass('button', 'grey') .setText('🔴 Hide platinumed') .click((e) => { e.preventDefault(); this._hidePlatinumed = !this._hidePlatinumed; if (this._hidePlatinumed) { togglePlatinumedButton.setText('🟢 Hide platinumed'); } else { togglePlatinumedButton.setText('🔴 Hide platinumed'); } this._filterSessions(); }); const toggleFinishedButton = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .setAttribute('href', '#') .addClass('button', 'grey') .setAttribute('style', 'margin-top: 5px;') .setText('🔴 Hide 100%') .click((e) => { e.preventDefault(); this._hideFinished = !this._hideFinished; if (this._hideFinished) { toggleFinishedButton.setText('🟢 Hide 100%'); } else { toggleFinishedButton.setText('🔴 Hide 100%'); } this._filterSessions(); }); menuWrapper.append(togglePlatinumedButton, _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('br'), toggleFinishedButton); const floatingMenu = new _ui_FloatingMenu__WEBPACK_IMPORTED_MODULE_6__.FloatingMenu(menuWrapper); floatingMenu.insert(); } run() { console.debug('Sessions module is running'); this._scrapeSessions(); this._insertMenu(); this._appendDropdowns(); this._appendSearchBox(); } } /***/ }), /* 82 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Series": () => (/* binding */ Series) /* harmony export */ }); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _features_lists_ListButtons__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(72); /* harmony import */ var _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(21); /* harmony import */ var _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(8); /* harmony import */ var _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(24); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(34); /* harmony import */ var _features_unobtainables_unobtainables_utils__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(64); class Series { constructor(username) { this._username = username; const listStorage = new _features_lists_ListStorage__WEBPACK_IMPORTED_MODULE_4__.ListStorage(); this._scriptStateStorage = new _features_state_ScriptStateStorage__WEBPACK_IMPORTED_MODULE_3__.ScriptStateStorage(); const allLists = listStorage.get(); this._lastActiveGameList = this._scriptStateStorage.get('lastActiveGameList'); if (this._lastActiveGameList == null && allLists.length > 0) { this._lastActiveGameList = allLists[0].id; } } _getAllRows() { return (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('table.series:not(.legend) tr'); } _appendListButtons() { this._getAllRows().forEach((el) => { const pathname = el.clone().find('a.title').getAttribute('href'); const trophyListId = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getFirstLevelIdFromPathname)(pathname); const trophyListUrl = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getWebsiteUrl)() + pathname; const toAppend = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('td') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .addClass('separator', 'left') .append(new _features_lists_ListButtons__WEBPACK_IMPORTED_MODULE_2__.ListButtonSmall(trophyListId, trophyListUrl, this._lastActiveGameList, 'psnpp-list-button'))); const seriesCompletionTdExists = el.clone().find('td.series').exists(); if (seriesCompletionTdExists) { el.clone().find('td.series').prev().after(toAppend); } else { el.append(toAppend); } }); } _updateTrophyListLinks() { if (this._username == null) { return; } this._getAllRows().forEach((el) => { const target = el.clone().find('a.title'); const pathname = target.getAttribute('href'); const slash = pathname[pathname.length - 1] === '/' ? '' : '/'; target.setAttribute('href', pathname + slash + this._username); }); } _markUnobtainableTrophies() { const unobtainableTrophies = new _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_5__.UnobtainableTrophiesStorage().get(); this._getAllRows().forEach((el) => { const pathname = el.clone().find('a.title').getAttribute('href'); const trophyListId = (0,_util_url__WEBPACK_IMPORTED_MODULE_0__.getFirstLevelIdFromPathname)(pathname); const unobtainableTrophiesForList = unobtainableTrophies.data.list[trophyListId]; if (unobtainableTrophiesForList != null) { const titleSpan = el.clone().find('a.title').parent(); titleSpan.append(' ', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('bullet').setText('•'), ' ', _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('i') .addClass('fa', 'fa-exclamation-circle', 'marker-unobtainable-trophies') .setAttribute('aria-hidden', 'true') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_6__.tooltip)(el, (0,_features_unobtainables_unobtainables_utils__WEBPACK_IMPORTED_MODULE_7__.getUnobtainableTrophiesDescription)(unobtainableTrophiesForList)))); } }); } _collapseSeries() { const isSeriesDoNotCollapseNoStageEnabled = this._scriptStateStorage.get('seriesDoNotCollapseNoStage'); (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('table.series.basic-completion:not(.legend)').forEach(table => { const containsNoStageElement = table.clone().find('span.typo-top', { equalsText: 'NO' }).exists() && table.clone().find('span.typo-bottom', { equalsText: 'Stage' }).exists(); if (isSeriesDoNotCollapseNoStageEnabled && containsNoStageElement) { return; } const stageInfoTd = table.clone().find('span.separator').parent(); const stageCompletionBadgeTd = table.clone().find('td.series'); const rowsToBeRemoved = (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('tr:not(.platinum):not(.completed)', {}, table.get()); table.addClass('full-completion').removeClass('basic-completion'); table.clone().find('td.basic-completion').addClass('full-completion').removeClass('basic-completion'); table.clone().find('td.series img.completion').addClass('completion-star').removeClass('completion'); table.clone().find('td.series') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .addClass('center') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span') .setAttribute('style', 'font-size: 11px;') .apply(el => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_6__.tooltip)(el, 'Number of collapsed trophy lists')) .setText(`(${rowsToBeRemoved.length})`))); rowsToBeRemoved.forEach(el => el.remove()); table.clone().find('tr').prepend(stageInfoTd); table.clone().find('tr').append(stageCompletionBadgeTd); }); _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('table.series.basic-completion.legend').remove(); } _appendCollapseButton() { const isSeriesAutoCollapseEnabled = this._scriptStateStorage.get('seriesAutoCollapse'); const isSeriesDoNotCollapseNoStageEnabled = this._scriptStateStorage.get('seriesDoNotCollapseNoStage'); const collapseButton = _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('a') .addClass('button', 'green') .setAttribute('href', '#') .setText('Collapse') .click((e, el) => { e.preventDefault(); this._collapseSeries(); el.setText('Stages are collapsed'); }); _util_J__WEBPACK_IMPORTED_MODULE_1__.J.q('table.series.legend.incomplete').after(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .addClass('form', 'center') .setAttribute('style', 'margin-top: 20px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('label') .setAttribute('style', 'text-align: left;') .addClass('checkbox') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('input') .setAttribute('type', 'checkbox') .condition(isSeriesAutoCollapseEnabled, (el) => el.setAttribute('checked', 'checked')) .change((ev) => { const checked = ev.currentTarget.checked; this._scriptStateStorage.set('seriesAutoCollapse', checked); }), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('i'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span').setText('Autocollapse')), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('label') .setAttribute('style', 'text-align: left;') .addClass('checkbox') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('input') .setAttribute('type', 'checkbox') .condition(isSeriesDoNotCollapseNoStageEnabled, (el) => el.setAttribute('checked', 'checked')) .change((ev) => { const checked = ev.currentTarget.checked; this._scriptStateStorage.set('seriesDoNotCollapseNoStage', checked); }), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('i'), _util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('span').setText('Do not collapse "No Stage"')), collapseButton)); return collapseButton; } run() { console.debug('Series module is running'); const collapseButton = this._appendCollapseButton(); if (this._scriptStateStorage.get('seriesAutoCollapse')) { collapseButton.triggerClick(); } if (this._lastActiveGameList != null) { this._appendListButtons(); } this._markUnobtainableTrophies(); this._updateTrophyListLinks(); } } /***/ }), /* 83 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "HundredClub": () => (/* binding */ HundredClub) /* harmony export */ }); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _util_date__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(53); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(12); class HundredClub { _adjustPlayerLinks() { const url = (0,_util_url__WEBPACK_IMPORTED_MODULE_3__.getUrl)(); const trophyList = url .replace('100-club', 'trophies') .replace(/\?page=[0-9]+$/, ''); (0,_util_J__WEBPACK_IMPORTED_MODULE_1__.all)('tr').forEach((el) => { const usernameLink = el.clone().find('a.title'); const usernameHref = usernameLink.getAttribute('href'); usernameLink.setAttribute('href', trophyList + usernameHref); }); } _switchHoursTo24HourFormat() { if (!new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_0__.SettingsStorage().get('use24HourTimeFormat')) { return; } (0,_util_date__WEBPACK_IMPORTED_MODULE_2__.switchHoursTo24HourFormat)(); } run() { console.debug('100% Club module is running'); this._switchHoursTo24HourFormat(); this._adjustPlayerLinks(); } } /***/ }), /* 84 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "Trophy": () => (/* binding */ Trophy) /* harmony export */ }); /* harmony import */ var _features_guide_GuideBanner__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(85); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(5); /* harmony import */ var _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(24); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25); /* harmony import */ var _util_fetch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(13); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(3); /* harmony import */ var _util_Logger__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(47); /* harmony import */ var _util_unsafe__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(34); /* harmony import */ var _util_url__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(12); /* harmony import */ var _util_video__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(52); class Trophy { constructor() { this._settingsStorage = new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_1__.SettingsStorage(); this._logger = new _util_Logger__WEBPACK_IMPORTED_MODULE_6__.Logger(this._settingsStorage.get('enableScriptLogger'), 'Trophy'); } _getTrophyListLinkElement() { return _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('ul.navigation > li > a', { equalsText: 'Trophies' }); } _getGuidesLinkElement() { return _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('ul.navigation > li > a', { equalsText: 'Guides' }); } _getTrophyGuideLinkElement() { return _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('ul.navigation > li > a', { equalsText: 'Trophy Guide' }); } _getGuidesPathname() { const trophyGuidesLink = this._getGuidesLinkElement(); if (trophyGuidesLink.exists()) { return trophyGuidesLink.getAttribute('href'); } const trophyGuideLink = this._getTrophyGuideLinkElement(); if (trophyGuideLink.exists()) { return this._getTrophyListLinkElement().getAttribute('href').replace('trophies', 'guides'); } return null; } async _loadGuide() { var _a; this._logger.debug('Loading guide info'); const guidesPathname = this._getGuidesPathname(); if (guidesPathname == null) { // NOTE: We should never get here since the button should not be visible at this point. return; } const trophyPathname = (0,_util_url__WEBPACK_IMPORTED_MODULE_8__.getUrlObject)().pathname; const trophyId = (0,_util_url__WEBPACK_IMPORTED_MODULE_8__.getSecondLevelIdFromPathname)(trophyPathname); const trophyName = _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('#content span.title').getText(); this._logger.debug('Going to fetch guides list:', { guidesPathname, trophyName, trophyPathname, trophyId }); const guidesDoc = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_4__.fetchDocument)(guidesPathname); const availableGuides = (0,_util_J__WEBPACK_IMPORTED_MODULE_5__.all)('a[href^="/guide/"]', {}, guidesDoc); this._logger.debug('Number of guides found: ', availableGuides.length, '-', availableGuides.map(x => x.getAttribute('href'))); for (const guideAnchor of availableGuides) { const guidePathname = guideAnchor.getAttribute('href'); const guideTitle = guideAnchor.clone().find('span').getText(); const guideBackgroundStyle = guideAnchor .clone() .find('div.background') .getAttribute('style'); const guideAuthors = guideAnchor .clone() .find('span.author') .getText() .trim() .replace(/^By /, 'Written by '); const guideUserFavourites = guideAnchor .clone() .find('span.stat', { eq: 0 }) .getText() .trim() .replace('User Favourites', ''); const guideRatings = guideAnchor .clone() .find('span.stat', { eq: 1 }) .getText() .trim() .replace('Ratings', ''); const guideRatingsClass = guideAnchor .clone() .find('span.stat', { eq: 1 }) .find('span.rating-inline') .getClassName() .split(' ')[1]; const guideViews = guideAnchor .clone() .find('span.stat', { eq: 2 }) .getText() .trim() .replace('Views', ''); this._logger.debug('Processing guide:', { guideTitle, guidePathname, guideBackgroundStyle, guideAuthors, guideUserFavourites, guideRatings, guideRatingsClass, guideViews }); const guideDoc = await (0,_util_fetch__WEBPACK_IMPORTED_MODULE_4__.fetchDocument)(guidePathname); const authorInfo = _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('div.title-author', {}, guideDoc).getText(); const publishedDate = authorInfo.split('•')[1].trim().replace('Published ', ''); // NOTE: Some guides are never updated. const updatedDate = (_a = authorInfo.split('•')[2]) === null || _a === void 0 ? void 0 : _a.trim().replace('Updated ', ''); const trophyAnchor = (0,_util_J__WEBPACK_IMPORTED_MODULE_5__.all)('a.title[href^="/trophy/"]', {}, guideDoc) .find(scannedTrophy => { const scannedTrophyPathname = scannedTrophy.getAttribute('href'); const scannedTrophyId = (0,_util_url__WEBPACK_IMPORTED_MODULE_8__.getSecondLevelIdFromPathname)(scannedTrophyPathname); return scannedTrophyId === trophyId; }); if (trophyAnchor == null) { this._logger.debug('Did not find matching trophy in this guide.'); continue; } const matchedTrophyName = trophyAnchor.getText(); const trophyGuideBox = trophyAnchor .parent() .parent() .parent() .parent() .parent() .parent(); // mega oof! this._logger.debug('Displaying content from trophy guide:', { publishedDate, updatedDate, trophyGuideBoxExists: trophyGuideBox.exists(), matchedTrophyName }); const trophyGuideContent = trophyGuideBox.clone().find('div.section-original'); _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('#trophyTips') .append(trophyName === matchedTrophyName ? null : _util_J__WEBPACK_IMPORTED_MODULE_5__.J.c('div') .addClass('box', 'information', 'center') .setAttribute('style', 'padding: 10px; font-size: 15px; line-height: 15px; margin-bottom: 10px;') .setCss('backgroundColor', _util_constants__WEBPACK_IMPORTED_MODULE_3__.COLOR_LIGHT_ORANGE) .setCss('border', `2px solid ${_util_constants__WEBPACK_IMPORTED_MODULE_3__.COLOR_DARK_ORANGE}`) .append(_util_J__WEBPACK_IMPORTED_MODULE_5__.J.c('b').setText('WARNING: '), 'Trophy names do not match. Guide displayed below for trophy ', _util_J__WEBPACK_IMPORTED_MODULE_5__.J.c('i').setText(`"${matchedTrophyName}"`), ' might be incorrect.'), new _features_guide_GuideBanner__WEBPACK_IMPORTED_MODULE_0__.GuideBanner({ title: guideTitle, pathname: guidePathname + '#' + trophyGuideBox.getAttribute('id'), backgroundStyle: guideBackgroundStyle, authors: guideAuthors, favourites: guideUserFavourites, views: guideViews, ratings: guideRatings, ratingsClass: guideRatingsClass, publishedDate, updatedDate }), _util_J__WEBPACK_IMPORTED_MODULE_5__.J.c('div').setInnerHtml(trophyGuideContent.getOuterHTML())); (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_7__.activateSpoilers)(); (0,_util_video__WEBPACK_IMPORTED_MODULE_9__.applyLazyLoad)(true); return; } _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('#trophyTips') .append(_util_J__WEBPACK_IMPORTED_MODULE_5__.J.c('div') .addClass('box', 'information', 'center') .setAttribute('style', 'padding: 10px; font-size: 15px; line-height: 15px; margin-bottom: 10px;') .setCss('backgroundColor', _util_constants__WEBPACK_IMPORTED_MODULE_3__.COLOR_LIGHT_ORANGE) .setCss('border', `2px solid ${_util_constants__WEBPACK_IMPORTED_MODULE_3__.COLOR_DARK_ORANGE}`) .append('Trophy guide was not found.')); } _appendLoadGuideButton() { // If guide is already present... const guideIsEmpty = _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('#trophyTips').isEmpty(); if (!guideIsEmpty) { return false; } // ...or this is platinum trophy... const thisIsPlatinumTrophy = _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('img[title="Platinum"]').exists(); if (thisIsPlatinumTrophy) { return false; } // ...or there are no guides available. const guidesPathname = this._getGuidesPathname(); if (guidesPathname == null) { return false; } const addToCabinetButton = _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('a', { equalsText: 'Add to Cabinet' }); addToCabinetButton.setAttribute('style', 'margin-left: 0px !important'); let clicked = false; const button = _util_J__WEBPACK_IMPORTED_MODULE_5__.J.c('a') .setAttribute('href', '#') .setAttribute('style', 'margin-left: 10px;') .addClass('button', 'blue') .apply((el) => (0,_util_unsafe__WEBPACK_IMPORTED_MODULE_7__.tooltip)(el, _util_J__WEBPACK_IMPORTED_MODULE_5__.J.c('center') .append('Load guide', _util_J__WEBPACK_IMPORTED_MODULE_5__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_5__.J.c('span') .setAttribute('style', 'font-size: 11px;') .setText('PSNP+ will attempt to load appropriate trophy guide if there is one available')) .getOuterHTML())) .click(async (e, el) => { e.preventDefault(); if (clicked) { return; } clicked = true; el.clone() .find('i') .removeClass('fa-book') .addClass('fa-spinner', 'fa-spin', 'fa-fw'); try { await this._loadGuide(); } catch (e) { const typedE = e; alert('Failed to load guide! Error message: ' + typedE.message); } el.remove(); // NOTE: Need to manually hide tiptip, otherwise it stays visible _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('div#tiptip_holder').hide(); }) .append(_util_J__WEBPACK_IMPORTED_MODULE_5__.J.c('i').addClass('fa', 'fa-book').setAttribute('aria-hidden', 'true')); _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('table.box.zebra td', { eq: 1 }) .after(_util_J__WEBPACK_IMPORTED_MODULE_5__.J.c('td') .append(addToCabinetButton.exists() ? button : _util_J__WEBPACK_IMPORTED_MODULE_5__.J.c('span').addClass('separator', 'right').append(button))); return true; } _markTrophyAsUnobtainable() { const unobtainableTrophies = new _features_unobtainables_UnobtainableTrophiesStorage__WEBPACK_IMPORTED_MODULE_2__.UnobtainableTrophiesStorage().get(); const trophyPath = (0,_util_url__WEBPACK_IMPORTED_MODULE_8__.getUrlObject)().pathname; const trophyListId = parseInt((0,_util_url__WEBPACK_IMPORTED_MODULE_8__.getFirstLevelIdFromPathname)(trophyPath), 10); const trophyId = parseInt((0,_util_url__WEBPACK_IMPORTED_MODULE_8__.getSecondLevelIdFromPathname)(trophyPath), 10); const unobtainableTrophiesForList = unobtainableTrophies.data.list[trophyListId]; if (unobtainableTrophiesForList == null) { return; } if (unobtainableTrophiesForList.includes(trophyId) || unobtainableTrophiesForList[0] === 0) { _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('table.box.zebra tr').setCss('backgroundColor', _util_constants__WEBPACK_IMPORTED_MODULE_3__.COLOR_LIGHT_ORANGE); } } _renumberLatestAchievers() { const totalAchieversText = _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('nobr', { equalsText: 'Achievers' }).parent().prev().prev().getText().replace(/,/g, ''); let totalAchievers = parseInt(totalAchieversText, 10); const latestAchieversContainer = _util_J__WEBPACK_IMPORTED_MODULE_5__.J.q('h3', { equalsText: 'Latest Achievers' }).parent().parent().parent(); (0,_util_J__WEBPACK_IMPORTED_MODULE_5__.all)('td.rank', {}, latestAchieversContainer.get()).forEach(x => { x.setAttribute('title', totalAchievers.toLocaleString('en-US')); totalAchievers--; }); } run() { this._logger.debug('Running'); const appended = this._appendLoadGuideButton(); this._logger.debug('Added button to load guide', appended); if (!appended && this._settingsStorage.get('guideLazyLoadMedia')) { (0,_util_video__WEBPACK_IMPORTED_MODULE_9__.applyLazyLoad)(true); } this._markTrophyAsUnobtainable(); this._renumberLatestAchievers(); } } /***/ }), /* 85 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "GuideBanner": () => (/* binding */ GuideBanner) /* harmony export */ }); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3); class GuideBanner extends _util_J__WEBPACK_IMPORTED_MODULE_0__.JC { constructor(props) { super('div'); this._props = props; this._build(); } _build() { this .addClass('cf') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('guide-page-info', 'sm') .setAttribute('style', 'margin-bottom: 0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('a') .setAttribute('href', this._props.pathname) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('background') .setAttribute('style', this._props.backgroundStyle) .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('shade') .setAttribute('style', 'text-align: left;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('flex', 'v-align') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('grow') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('h3') .addClass('ellipsis') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').setText(this._props.title)), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('info') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span') .addClass('line-clamp', 'two') .append(this._props.authors, ' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' Published ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText(this._props.publishedDate)) .condition(this._props.updatedDate != null, (el) => { el.append(' ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('bullet').setText('•'), ' Updated ', _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('b').setText(this._props.updatedDate)); }))), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('no-shrink') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .addClass('flex') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('center') .setAttribute('style', 'padding: 0 10px 0 10px; border-right:1px solid rgba(255,255,255,.3);') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').addClass('rating-inline', this._props.ratingsClass), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').addClass('typo-bottom').setText(this._props.ratings + ' Ratings'))), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('center') .setAttribute('style', 'padding: 0 10px 0 10px; border-right:1px solid rgba(255,255,255,.3);') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').addClass('typo-top').setText(this._props.views), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').addClass('typo-bottom').setText('Views'))), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('div') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('center') .setAttribute('style', 'padding: 0 10px 0 10px;') .append(_util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').addClass('typo-top').setText(this._props.favourites), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('br'), _util_J__WEBPACK_IMPORTED_MODULE_0__.J.c('span').addClass('typo-bottom').setText('Favorites'))))))))))); } } /***/ }), /* 86 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "BaseImmediate": () => (/* binding */ BaseImmediate) /* harmony export */ }); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5); /* harmony import */ var _util_constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(25); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3); /* harmony import */ var _util_observe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(35); /* harmony import */ var _util_stylesheet__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(49); const TROPHY_ICON_MAP = { '/lib/img/icons/40-platinum.png': _util_constants__WEBPACK_IMPORTED_MODULE_1__.NEW_TROPHY_ICONS.x40.platinum, '/lib/img/icons/buttons/platinum.png': _util_constants__WEBPACK_IMPORTED_MODULE_1__.NEW_TROPHY_ICONS.x24.platinum, '/lib/img/icons/40-gold.png': _util_constants__WEBPACK_IMPORTED_MODULE_1__.NEW_TROPHY_ICONS.x40.gold, '/lib/img/icons/buttons/gold.png': _util_constants__WEBPACK_IMPORTED_MODULE_1__.NEW_TROPHY_ICONS.x24.gold, '/lib/img/icons/40-silver.png': _util_constants__WEBPACK_IMPORTED_MODULE_1__.NEW_TROPHY_ICONS.x40.silver, '/lib/img/icons/buttons/silver.png': _util_constants__WEBPACK_IMPORTED_MODULE_1__.NEW_TROPHY_ICONS.x24.silver, '/lib/img/icons/40-bronze.png': _util_constants__WEBPACK_IMPORTED_MODULE_1__.NEW_TROPHY_ICONS.x40.bronze, '/lib/img/icons/buttons/bronze.png': _util_constants__WEBPACK_IMPORTED_MODULE_1__.NEW_TROPHY_ICONS.x24.bronze, '/lib/img/icons/40-hidden.png': _util_constants__WEBPACK_IMPORTED_MODULE_1__.NEW_TROPHY_ICONS.x40.hidden, '/lib/img/icons/buttons/hidden.png': _util_constants__WEBPACK_IMPORTED_MODULE_1__.NEW_TROPHY_ICONS.x24.hidden }; class BaseImmediate { _replaceTrophyIcons() { function replaceTrophyIcon(imageElement) { const src = imageElement.getAttribute('src'); if (src in TROPHY_ICON_MAP) { imageElement.setAttribute('src', TROPHY_ICON_MAP[src]); } } function adjustNode(node) { if (node.childNodes.length > 0) { node.childNodes.forEach(node => adjustNode(node)); } if (node.nodeName === 'IMG') { const imageElement = new _util_J__WEBPACK_IMPORTED_MODULE_2__.J(node); replaceTrophyIcon(imageElement); } } // Action time... (0,_util_J__WEBPACK_IMPORTED_MODULE_2__.all)('img[src^="/lib/img/icons/"]').forEach(el => replaceTrophyIcon(el)); (0,_util_observe__WEBPACK_IMPORTED_MODULE_3__.htmlObserve)((mutationList) => { mutationList.forEach(mutation => mutation.addedNodes.forEach(node => adjustNode(node))); }); } run() { console.debug('BaseImmediate module is running'); // Global style (0,_util_stylesheet__WEBPACK_IMPORTED_MODULE_4__.injectStylesheet)(_util_stylesheet__WEBPACK_IMPORTED_MODULE_4__.STYLESHEET_GLOBAL); if (new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_0__.SettingsStorage().get('useNewTrophyIcons')) { this._replaceTrophyIcons(); } } } /***/ }), /* 87 */ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "GuideImmediate": () => (/* binding */ GuideImmediate) /* harmony export */ }); /* harmony import */ var _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5); /* harmony import */ var _util_J__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3); /* harmony import */ var _util_observe__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(35); class GuideImmediate { constructor(subSection) { this._subSection = subSection; } run() { console.debug('GuideImmediate module is running'); if (this._subSection != null) { // Edit guide, comments and other stuff... return; } if (!new _features_settings_SettingsStorage__WEBPACK_IMPORTED_MODULE_0__.SettingsStorage().get('guideLazyLoadMedia')) { return; } (0,_util_observe__WEBPACK_IMPORTED_MODULE_2__.htmlObserve)((mutationList) => { mutationList.forEach(mutation => mutation.addedNodes.forEach(node => { if (node.nodeName === 'IMG') { const imageElement = new _util_J__WEBPACK_IMPORTED_MODULE_1__.J(node); const src = imageElement.getAttribute('src'); imageElement.removeAttribute('src'); imageElement.addClass('lazy'); imageElement.setAttribute('data-src', src); } if (node.nodeName === 'DIV' && node.classList.contains('lazyYT')) { const videoDiv = new _util_J__WEBPACK_IMPORTED_MODULE_1__.J(node); const videoId = videoDiv.getAttribute('data-youtube-id'); videoDiv .after(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('div') .setAttribute('style', 'position: relative; padding-bottom: 56.25%; height: 0; margin: 0;') .append(_util_J__WEBPACK_IMPORTED_MODULE_1__.J.c('iframe') .addClass('lazy') .setAttribute('style', 'position: absolute; top: 0; left: 0; width: 100%; height: 100%;') .setAttribute('frameborder', '0') .setAttribute('allow', 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture') .setAttribute('allowfullscreen', 'allowfullscreen') .setAttribute('data-src', `https://www.youtube.com/embed/${videoId}`))); videoDiv.remove(); } })); }); } } /***/ }) /******/ ]); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = (exports, definition) => { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ })(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ (() => { /******/ // define __esModule on exports /******/ __webpack_require__.r = (exports) => { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ })(); /******/ /************************************************************************/ var __webpack_exports__ = {}; // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. (() => { __webpack_require__.r(__webpack_exports__); /* harmony import */ var _launcher__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony import */ var _util_user__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(19); function onLoad() { (async function start() { try { await (0,_launcher__WEBPACK_IMPORTED_MODULE_0__.launchAfterDomContentLoaded)(); } catch (e) { console.error('PSNP+ launch failed (onLoad)', e); } })(); } console.debug('PSNP+ is running, version', GM_info.script.version); if ((0,_util_user__WEBPACK_IMPORTED_MODULE_1__.isLoggedIn)()) { (0,_launcher__WEBPACK_IMPORTED_MODULE_0__.launchImmediately)(); if (document.readyState === 'complete') { onLoad(); } else { window.addEventListener('load', () => { onLoad(); }); } } else { console.debug('User not logged in. Stopping PSNP+.'); } })(); /******/ })() ;