From e4b6b784764f4f45f2e69d8c949880698b7d6e70 Mon Sep 17 00:00:00 2001 From: Typpi <20943337+Nick2bad4u@users.noreply.github.com> Date: Fri, 1 Nov 2024 18:57:47 -0400 Subject: [PATCH 01/28] Update magic-userjs.user.js added // @connect githubusercontent.com to fix errors when the url is redirected from github Signed-off-by: Typpi <20943337+Nick2bad4u@users.noreply.github.com> --- dist/magic-userjs.user.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dist/magic-userjs.user.js b/dist/magic-userjs.user.js index 604696e..36a60f2 100644 --- a/dist/magic-userjs.user.js +++ b/dist/magic-userjs.user.js @@ -40,6 +40,7 @@ // @connect greasyfork.org // @connect sleazyfork.org // @connect github.com +// @connect githubusercontent.com // @connect openuserjs.org // @grant GM_addElement // @grant GM_info @@ -5074,4 +5075,4 @@ const init = async () => { }; init(); -})(); \ No newline at end of file +})(); From b66378eb0f232a2ef7317552284493e2335288f4 Mon Sep 17 00:00:00 2001 From: Sam Stelle Date: Thu, 20 Feb 2025 19:07:28 -0800 Subject: [PATCH 02/28] Add dataset values for date fields in user script table to fix sorting issue for stupid American date format. --- src/UserJS/main.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/UserJS/main.js b/src/UserJS/main.js index ffb8ca4..d2a5228 100644 --- a/src/UserJS/main.js +++ b/src/UserJS/main.js @@ -1393,7 +1393,7 @@ class Container { this.tab.create(this.host); const tabbody = this.tabbody; - const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent; + const getCellValue = (tr, idx) => tr.children[idx].dataset.value || tr.children[idx].innerText || tr.children[idx].textContent; const comparer = (idx, asc) => (a, b) => ((v1, v2) => v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) @@ -2613,7 +2613,10 @@ function primaryFN() { textContent: ujs.daily_installs }); const fupdated = make('td', 'mujs-list', { - textContent: language.toDate(ujs.code_updated_at) + textContent: language.toDate(ujs.code_updated_at), + dataset: { + value: (new Date(ujs.code_updated_at)).toISOString() + } }); const fname = make('td', 'mujs-name'); const fmore = make('mujs-column', 'mujs-list hidden', { @@ -2637,7 +2640,10 @@ function primaryFN() { textContent: `${i18n$('version_number')}: ${ujs.version}` }); const fcreated = make('mu-js', 'mujs-list', { - textContent: `${i18n$('created_date')}: ${language.toDate(ujs.created_at)}` + textContent: `${i18n$('created_date')}: ${language.toDate(ujs.created_at)}`, + dataset: { + value: (new Date(ujs.created_at)).toISOString() + } }); const flicense = make('mu-js', 'mujs-list', { title: ujs.license ?? i18n$('no_license'), From 960239c899509537d895e24f3853c4b8bedc1de6 Mon Sep 17 00:00:00 2001 From: Magic Date: Tue, 25 Feb 2025 14:37:09 -0800 Subject: [PATCH 03/28] Updated eslint.config.js Signed-off-by: Magic --- eslint.config.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index 7c77b70..68f464d 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,5 +1,5 @@ -import js from '@eslint/js'; import globals from 'globals'; +import pluginJs from '@eslint/js'; import eslintConfigPrettier from 'eslint-config-prettier'; const userJSGlobals = { @@ -9,7 +9,7 @@ const userJSGlobals = { languageList: 'readonly', translations: 'readonly', userjs: 'writable', - ...globals.es2023, + ...globals.es2024, ...globals.browser, ...globals.greasemonkey }; @@ -19,7 +19,7 @@ const webextGlobals = { webext: 'readonly', brws: 'readonly', userjs: 'writable', - ...globals.es2023, + ...globals.es2024, ...globals.browser, ...globals.webextensions }; @@ -42,7 +42,7 @@ const rules = { }; export default [ - js.configs.recommended, + pluginJs.configs.recommended, eslintConfigPrettier, { files: ['src/js/*.js'], @@ -84,7 +84,7 @@ export default [ ecmaVersion: 'latest', sourceType: 'module', globals: { - ...globals.es2021, + ...globals.es2024, ...globals.node }, parserOptions From 942a8ea344c5774281e7a8851aa486354d81ff85 Mon Sep 17 00:00:00 2001 From: Magic Date: Tue, 25 Feb 2025 15:02:48 -0800 Subject: [PATCH 04/28] UserJS v7.4.0 Signed-off-by: Magic --- CHANGELOG.user.md | 29 + dist/magic-userjs.meta.js | 7 +- dist/magic-userjs.user.js | 1573 ++++++++++++++++++------------------- package.json | 45 +- pnpm-lock.yaml | 486 ++++++------ src/UserJS/header.js | 11 +- src/UserJS/main.js | 1557 ++++++++++++++++++------------------ src/sass/_main.scss | 1 + src/typings/UserJS.d.ts | 87 +- src/typings/types.d.ts | 90 ++- 10 files changed, 1987 insertions(+), 1899 deletions(-) diff --git a/CHANGELOG.user.md b/CHANGELOG.user.md index 61e1794..81b66f2 100644 --- a/CHANGELOG.user.md +++ b/CHANGELOG.user.md @@ -1,5 +1,34 @@ # Changelog +## v7.4.0 + +* Merged https://github.com/magicoflolis/Userscript-Plus/pull/59 +* Added `githubusercontent.com` to `@connect`. +* Added `autoSort` to config. +* Added sorting to the following: "Total installs", "Ratings", "Created date". + * Still in the early stages, but functional +* Reworked counter system. +* Tweaked cache system. + * Reduced how often the script will cache something. +* Cleaned up code. +* Fixed minor issues. + +**Known Issues:** + +* Enabling a engine requires the page to be reloaded, while disabling a engine does not. + * This is caused by the cache system. +* "Filter out other languages" may not filter _every_ userscript that is not in your language. +* SVG elements don't load on every webpage, _can be blocked by the page, external script, or extensions._ + +**TODO:** + +* Finish translations. +* Finish blacklist section. +* Finish config section. +* Merge https://github.com/magicoflolis/Userscript-Plus/pull/64 + +--- + ## v7.3.0 * Re-organized config list. diff --git a/dist/magic-userjs.meta.js b/dist/magic-userjs.meta.js index c74560c..6dd5d1d 100644 --- a/dist/magic-userjs.meta.js +++ b/dist/magic-userjs.meta.js @@ -1,5 +1,5 @@ // ==UserScript== -// @version 7.3.0 +// @version 7.4.0 // @name Magic Userscript+ : Show Site All UserJS // @name:ar Magic Userscript+: عرض جميع ملفات UserJS // @name:de Magic Userscript+ : Website anzeigen Alle UserJS @@ -40,20 +40,25 @@ // @connect greasyfork.org // @connect sleazyfork.org // @connect github.com +// @connect githubusercontent.com // @connect openuserjs.org +// @grant GM_addValueChangeListener // @grant GM_addElement // @grant GM_info // @grant GM_getValue // @grant GM_openInTab // @grant GM_setValue // @grant GM_registerMenuCommand +// @grant GM_removeValueChangeListener // @grant GM_xmlhttpRequest +// @grant GM.addValueChangeListener // @grant GM.addElement // @grant GM.info // @grant GM.getValue // @grant GM.openInTab // @grant GM.setValue // @grant GM.registerMenuCommand +// @grant GM.removeValueChangeListener // @grant GM.xmlHttpRequest // @match https://*/* // @noframes diff --git a/dist/magic-userjs.user.js b/dist/magic-userjs.user.js index e46b3fc..a624bdd 100644 --- a/dist/magic-userjs.user.js +++ b/dist/magic-userjs.user.js @@ -1,5 +1,5 @@ // ==UserScript== -// @version 7.3.0 +// @version 7.4.0 // @name Magic Userscript+ : Show Site All UserJS // @name:ar Magic Userscript+: عرض جميع ملفات UserJS // @name:de Magic Userscript+ : Website anzeigen Alle UserJS @@ -40,20 +40,25 @@ // @connect greasyfork.org // @connect sleazyfork.org // @connect github.com +// @connect githubusercontent.com // @connect openuserjs.org +// @grant GM_addValueChangeListener // @grant GM_addElement // @grant GM_info // @grant GM_getValue // @grant GM_openInTab // @grant GM_setValue // @grant GM_registerMenuCommand +// @grant GM_removeValueChangeListener // @grant GM_xmlhttpRequest +// @grant GM.addValueChangeListener // @grant GM.addElement // @grant GM.info // @grant GM.getValue // @grant GM.openInTab // @grant GM.setValue // @grant GM.registerMenuCommand +// @grant GM.removeValueChangeListener // @grant GM.xmlHttpRequest // @match https://*/* // @noframes @@ -89,6 +94,15 @@ if ( if (!(typeof userjs === 'object' && userjs.UserJS)) { return; } +const createPolicy = () => { + // Native implementation exists + if (window.trustedTypes && window.trustedTypes.createPolicy) { + window.trustedTypes.createPolicy('default', { + createHTML: (string) => string + }); + } +}; +createPolicy(); /** * Uncompressed locales + compiler * @@ -1688,29 +1702,6 @@ function safeSelf() { return userjs.safeSelf; } -const trustedTypes = { - policy: false, - init() { - if (this.policy) { - return this.policy; - } - this.policy = true; - try { - // Native implementation exists - if (window.trustedTypes && window.trustedTypes.createPolicy) { - window.trustedTypes.createPolicy('default', { - createHTML: (string) => string - }); - } - } catch (ex) { - ex.cause = 'trustedTypes.init()'; - err(ex); - } - return this.policy; - } -}; -trustedTypes.init(); - const BLANK_PAGE = 'about:blank'; // Lets highlight me :) const authorID = 166061; @@ -1718,6 +1709,7 @@ const authorID = 166061; * Some UserJS I personally enjoy - `https://greasyfork.org/scripts/{{id}}` */ const goodUserJS = [ + 33005, 394820, 438684, 4870, @@ -1749,11 +1741,9 @@ const goodUserJS = [ 'https://github.com/jesus2099/konami-command/raw/master/INSTALL-USER-SCRIPT.user.js', 'https://github.com/TagoDR/MangaOnlineViewer/raw/master/dist/Manga_OnlineViewer_Adult.user.js' ]; -/** - * Remove UserJS from banned accounts - */ +/** Remove UserJS from banned accounts */ const badUserJS = [478597]; -// Unsupport webpages for each engine +/** Unsupport host for search engines */ const engineUnsupported = { greasyfork: ['pornhub.com'], sleazyfork: ['pornhub.com'], @@ -1795,12 +1785,15 @@ const builtinList = { pathname: '/hentai/.+/read/page/.+' } }; +// #region DEFAULT_CONFIG /** * @type { import("../typings/types.d.ts").config } */ const DEFAULT_CONFIG = { autofetch: true, autoinject: true, + autoSort: 'daily_installs', + clearTabCache: true, cache: true, codePreview: false, autoexpand: false, @@ -1895,48 +1888,46 @@ const DEFAULT_CONFIG = { } } }; -//#region i18n +// #endregion +// #region i18n class i18nHandler { constructor() { - /** @type { string[] } */ - this.cache = []; - - const { navigator } = safeSelf(); - const { languages } = navigator; - for (const nlang of languages) { - const lg = nlang.split('-')[0]; - if (this.cache.indexOf(lg) === -1) { - this.cache.push(lg); - } + if (userjs.pool !== undefined) { + return userjs.pool; } - - const current = navigator.language.split('-')[0] ?? 'en'; - if (!this.cache.includes(current)) { - this.cache.push(current); + userjs.pool = new Map(); + for (const [k, v] of Object.entries(translations)) { + if (!userjs.pool.has(k)) userjs.pool.set(k, v); } } + /** + * @param {string | Date | number} str + */ toDate(str = '') { const { navigator } = safeSelf(); - return new Intl.DateTimeFormat(navigator.language).format(new Date(str)); + return new Intl.DateTimeFormat(navigator.language).format( + typeof str === 'string' ? new Date(str) : str + ); } + /** + * @param {number | bigint} number + */ toNumber(number) { const { navigator } = safeSelf(); return new Intl.NumberFormat(navigator.language).format(number); } - i18n$(...keys) { + /** + * @type { import("../typings/UserJS.d.ts").i18n$ } + */ + i18n$(key) { const { navigator } = safeSelf(); const current = navigator.language.split('-')[0] ?? 'en'; - const list = translations[cfg.language] ?? translations[current]; - const arr = []; - for (const key of keys) { - arr.push(list[key]); - } - return arr.length !== 1 ? arr : arr[0]; + return userjs.pool.get(current)?.[key] ?? 'Unknown'; } } const language = new i18nHandler(); const { i18n$ } = language; -//#endregion +// #endregion // #region Utilities const union = (...arr) => [...new Set(arr.flat())]; /** @@ -1965,20 +1956,6 @@ const qsA = (selectors, root) => { * @type { import("../typings/types.d.ts").objToStr } */ const objToStr = (obj) => Object.prototype.toString.call(obj); -/** - * @type { import("../typings/types.d.ts").strToURL } - */ -const strToURL = (str) => { - const WIN_LOCATION = window.location ?? BLANK_PAGE; - try { - str = str ?? WIN_LOCATION; - return objToStr(str).includes('URL') ? str : new URL(str); - } catch (ex) { - ex.cause = 'strToURL'; - err(ex); - } - return WIN_LOCATION; -}; /** * @type { import("../typings/types.d.ts").isRegExp } */ @@ -2064,6 +2041,7 @@ const ael = (el, type, listener, options = {}) => { elem.addEventListener(type, listener, options); } } catch (ex) { + ex.cause = 'ael'; err(ex); } }; @@ -2179,26 +2157,12 @@ const dom = { }, cl: { add(target, token) { - if (Array.isArray(token)) { - for (const elem of normalizeTarget(target)) { - elem.classList.add(...token); - } - } else { - for (const elem of normalizeTarget(target)) { - elem.classList.add(token); - } - } + token = Array.isArray(token) ? token : [token]; + return normalizeTarget(target).some((elem) => elem.classList.add(...token)); }, remove(target, token) { - if (Array.isArray(token)) { - for (const elem of normalizeTarget(target)) { - elem.classList.remove(...token); - } - } else { - for (const elem of normalizeTarget(target)) { - elem.classList.remove(token); - } - } + token = Array.isArray(token) ? token : [token]; + return normalizeTarget(target).some((elem) => elem.classList.remove(...token)); }, toggle(target, token, force) { let r; @@ -2208,12 +2172,7 @@ const dom = { return r; }, has(target, token) { - for (const elem of normalizeTarget(target)) { - if (elem.classList.contains(token)) { - return true; - } - } - return false; + return normalizeTarget(target).some((elem) => elem.classList.contains(token)); } } }; @@ -2330,6 +2289,7 @@ const iconSVG = { try { if (typeof iconSVG[type].html === 'string') { svgElem.innerHTML = iconSVG[type].html; + dom.attr(svgElem, 'id', `mujs_${type ?? 'Unknown'}`); } // eslint-disable-next-line no-unused-vars } catch (ex) { @@ -2348,6 +2308,7 @@ const iconSVG = { */ const StorageSystem = { prefix: 'MUJS', + events: new Set(), getItem(key) { return window.localStorage.getItem(key); }, @@ -2360,8 +2321,47 @@ const StorageSystem = { remove(key) { window.localStorage.removeItem(key); }, + addListener(name, callback) { + if (isGM) { + let GMType; + if (isFN(GM.addValueChangeListener)) { + GMType = GM.addValueChangeListener(name, callback); + } else if (isFN(GM_addValueChangeListener)) { + GMType = GM_addValueChangeListener(name, callback); + } + if (GMType) { + return this.events.add(GMType) && GMType; + } + } + return ( + this.events.add(callback) && + window.addEventListener('storage', (evt) => { + const { key, oldValue, newValue } = evt; + if (key === name) callback(key, oldValue, newValue, false); + }) + ); + }, + attach() { + window.addEventListener('beforeunload', () => { + for (const e of this.events) { + if (isGM && typeof e === 'number' && !Number.isNaN(e)) { + if (isFN(GM.removeValueChangeListener)) { + GM.removeValueChangeListener(e); + } else if (isFN(GM_addValueChangeListener)) { + GM_removeValueChangeListener(e); + } + } else { + window.removeEventListener('storage', e); + } + this.events.delete(e); + } + }); + }, async setValue(key, v) { - v = typeof v === 'string' ? v : JSON.stringify(v ?? {}); + if (!v) { + return; + } + v = typeof v === 'string' ? v : JSON.stringify(v); if (isGM) { if (isFN(GM.setValue)) { await GM.setValue(key, v); @@ -2430,9 +2430,6 @@ const Network = { method, ...data }; - if (params.hermes) { - delete params.hermes; - } if (isGM && !useFetch) { if (params.credentials) { Object.assign(params, { @@ -2483,8 +2480,8 @@ const Network = { } else if (responseType.match(/clone/)) { resolve(check('clone')); } else if (responseType.match(/document/)) { - const domParser = new DOMParser(); const respTxt = check('text'); + const domParser = new DOMParser(); if (respTxt instanceof Promise) { respTxt.then((txt) => { const doc = domParser.parseFromString(txt, 'text/html'); @@ -2580,33 +2577,45 @@ const Network = { return txt.replaceAll(/\W/g, ''); } }; -const sleazyRedirect = () => { - const locObj = window.top.location; - const { hostname } = locObj; - const gfSite = /greasyfork\.org/.test(hostname); - if (!gfSite && cfg.sleazyredirect) { - return; - } - const otherSite = gfSite ? 'sleazyfork' : 'greasyfork'; - if (!qs('span.sign-in-link')) { - return; - } - if (!/scripts\/\d+/.test(locObj.href)) { - return; - } - if ( - !qs('#script-info') && - (otherSite == 'greasyfork' || qs('div.width-constraint>section>p>a')) - ) { - const str = locObj.href.replace( - /\/\/([^.]+\.)?(greasyfork|sleazyfork)\.org/, - '//$1' + otherSite + '.org' - ); - info(`Redirecting to "${str}"`); - if (isFN(locObj.assign)) { - locObj.assign(str); - } else { - locObj.href = str; +const Counter = { + cnt: { + total: { + count: 0 + } + }, + set(engine) { + if (!this.cnt[engine.name]) { + const counter = make('count-frame', engine.enabled ? '' : 'hidden', { + dataset: { + counter: engine.name + }, + title: engine.query ? decodeURIComponent(engine.query) : engine.url, + textContent: '0' + }); + this.cnt[engine.name] = { + root: counter, + count: 0 + }; + return counter; + } + return this.cnt[engine.name].root; + }, + update(count, engine) { + this.cnt[engine.name].count += count; + this.cnt.total.count += count; + this.updateAll(); + }, + updateAll() { + for (const v of Object.values(this.cnt)) dom.text(v.root, v.count); + }, + reset() { + for (const [k, v] of Object.entries(this.cnt)) { + dom.text(v.root, 0); + v.count = 0; + const engine = cfg.engines.find((engine) => k === engine.name); + if (engine) { + dom.cl[engine.enabled ? 'remove' : 'add'](v.root, 'hidden'); + } } } }; @@ -2629,17 +2638,16 @@ class Container { unsaved; isBlacklisted; rebuild; - counters; opacityMin; opacityMax; constructor(url) { this.remove = this.remove.bind(this); this.refresh = this.refresh.bind(this); - this.updateCounter = this.updateCounter.bind(this); - this.updateCounters = this.updateCounters.bind(this); this.showError = this.showError.bind(this); + this.toArr = this.toArr.bind(this); + this.toElem = this.toElem.bind(this); - this.webpage = strToURL(url); + this.webpage = this.strToURL(url); this.host = this.getHost(this.webpage.host); this.domain = this.getDomain(this.webpage.host); this.ready = false; @@ -2647,7 +2655,7 @@ class Container { this.shadowRoot = undefined; this.supported = isFN(make('main-userjs').attachShadow); this.frame = this.supported - ? make('main-userjs', '', { + ? make('main-userjs', { dataset: { insertedBy: $info.script.name, role: 'primary-container' @@ -2677,9 +2685,9 @@ class Container { }); if (this.supported) { this.shadowRoot = this.frame.attachShadow({ - mode: 'open', - clonable: false, - delegatesfocus: false + mode: 'closed' + // clonable: false, + // delegatesfocus: false }); this.ready = true; } @@ -2689,9 +2697,6 @@ class Container { this.unsaved = false; this.isBlacklisted = false; this.rebuild = false; - this.counters = { - total: 0 - }; this.opacityMin = '0.15'; this.opacityMax = '1'; this.elementsReady = this.init(); @@ -2775,41 +2780,24 @@ class Container { initFn() { this.renderTheme(cfg.theme); - for (const engine of cfg.engines) { - if (engine.enabled) { - const counter = make('count-frame', '', { - dataset: { - counter: engine.name - }, - title: engine.query ? decodeURIComponent(engine.query) : engine.url, - textContent: '0' - }); - this.countframe.append(counter); - } - this.counters[engine.name] = 0; - } - - const cfgpage = this.cfgpage; - const table = this.table; - const exBtn = this.exBtn; - const supported = this.supported; - const frame = this.frame; - const refresh = this.refresh; - const cache = this.cache; - const cHost = this.host; - const urlBar = this.urlBar; + Counter.cnt.total.root = this.mainbtn; + for (const engine of cfg.engines) this.countframe.append(Counter.set(engine)); + const { cfgpage, table, exBtn, supported, frame, refresh, cache, urlBar, host } = this; class Tabs { /** * @param { HTMLElement } root */ constructor(root) { - this.Tab = new Map(); + /** + * @type { Set } + */ + this.pool = new Set(); this.blank = BLANK_PAGE; this.protocal = 'mujs:'; - this.protoReg = new RegExp(`${this.protocal}(.+)`); + this.protoReg = new RegExp(`${this.protocal}(.+)`, 'i'); this.el = { - add: make('mujs-addtab', '', { + add: make('mujs-addtab', { textContent: '+', dataset: { command: 'new-tab' @@ -2822,43 +2810,23 @@ class Container { this.el.root.append(this.el.head); this.custom = () => {}; } - hasTab(...params) { - for (const p of params) { - if (!this.Tab.has(p)) { - return false; - } - const content = normalizeTarget(this.Tab.get(p)).filter((t) => p === t.dataset.host); - if (isBlank(content)) { - return false; - } - } - return true; - } - storeTab(host) { - const h = host ?? this.blank; - if (!this.Tab.has(h)) { - this.Tab.set(h, new Set()); - } - return this.Tab.get(h); + /** + * @param {string} hostname + */ + getTab(hostname) { + return [...this.pool].find(({ dataset }) => hostname === dataset.host); } - cache(host, ...tabs) { - const h = host ?? this.blank; - const tabCache = this.storeTab(h); - for (const t of normalizeTarget(tabs)) { - if (tabCache.has(t)) { - continue; - } - tabCache.add(t); - } - this.Tab.set(h, tabCache); - return tabCache; + getActive() { + return [...this.pool].find((tab) => tab.classList.contains('active')); } - intFN(host) { - if (!host.startsWith(this.protocal)) { + /** + * @param {string} hostname + */ + intFN(hostname) { + if (!hostname.startsWith(this.protocal)) { return; } - const type = host.match(this.protoReg)[1]; - if (type === 'settings') { + if (hostname.match(this.protoReg)[1] === 'settings') { dom.cl.remove([cfgpage, exBtn], 'hidden'); dom.cl.add(table, 'hidden'); if (!supported) { @@ -2866,67 +2834,60 @@ class Container { } } } + /** + * @param {HTMLElement} tab + * @param {boolean} [build] + */ active(tab, build = true) { - for (const t of normalizeTarget(tab, false)) { - dom.cl.add([cfgpage, exBtn], 'hidden'); - dom.cl.remove(table, 'hidden'); - dom.cl.remove(qsA('mujs-tab', this.el.head), 'active'); - dom.cl.add(t, 'active'); - if (!build) { - continue; - } - const host = t.dataset.host ?? this.blank; - if (host === this.blank) { - refresh(); - } else if (host.startsWith(this.protocal)) { - this.intFN(host); - } else { - this.custom(host); - } + if (!this.pool.has(tab)) this.pool.add(tab); + dom.cl.add([cfgpage, exBtn], 'hidden'); + dom.cl.remove(table, 'hidden'); + dom.cl.remove([...this.pool], 'active'); + dom.cl.add(tab, 'active'); + if (!build) { + return; + } + const host = tab.dataset.host ?? this.blank; + if (host === this.blank) { + refresh(); + } else if (host.startsWith(this.protocal)) { + this.intFN(host); + } else { + this.custom(host); } } /** @param { HTMLElement } tab */ close(tab) { - for (const t of normalizeTarget(tab, false)) { - const host = t.dataset.host; - if (cache.has(host)) { - cache.delete(host); - } - if (dom.cl.has(t, 'active')) { - refresh(); + if (this.pool.has(tab)) this.pool.delete(tab); + const host = tab.dataset.host; + if (cfg.clearTabCache && cache.has(host)) cache.delete(host); + if (tab.classList.contains('active')) refresh(); + const sibling = tab.nextElementSibling ?? tab.previousElementSibling; + if (sibling) { + if (sibling.dataset.command !== 'new-tab') { + this.active(sibling); } - const sibling = t.previousElementSibling ?? t.nextElementSibling; - if (sibling) { - if (sibling.dataset.command !== 'new-tab') { - this.active(sibling); - } - } - if (this.Tab.has(host)) { - this.Tab.delete(host); - } - t.remove(); } + tab.remove(); } - create(host = undefined) { - if (typeof host === 'string') { - if (host.startsWith(this.protocal) && this.hasTab(host)) { - this.active(this.Tab.get(host)); - return; - } - const content = normalizeTarget(this.storeTab(host)).filter( - (t) => host === t.dataset.host - ); - if (!isEmpty(content)) { + /** + * @param {string} [hostname] + */ + create(hostname = undefined) { + if (typeof hostname === 'string') { + const createdTab = this.getTab(hostname); + if (this.protoReg.test(hostname) && createdTab) { + this.active(createdTab); return; } } - const tab = make('mujs-tab', '', { + const tab = make('mujs-tab', { dataset: { command: 'switch-tab' }, style: `order: ${this.el.head.childElementCount};` }); - const tabClose = make('mu-js', '', { + const tabClose = make('mu-js', { dataset: { command: 'close-tab' }, @@ -2937,29 +2898,28 @@ class Container { tab.append(tabHost, tabClose); this.el.head.append(tab); this.active(tab, false); - this.cache(host, tab); - if (isNull(host)) { + if (isNull(hostname)) { refresh(); urlBar.placeholder = i18n$('newTab'); tab.dataset.host = this.blank; tabHost.title = i18n$('newTab'); tabHost.textContent = i18n$('newTab'); - } else if (host.startsWith(this.protocal)) { - const type = host.match(this.protoReg)[1]; - tab.dataset.host = host || cHost; + } else if (hostname.startsWith(this.protocal)) { + const type = hostname.match(this.protoReg)[1]; + tab.dataset.host = hostname || host; tabHost.title = type || tab.dataset.host; tabHost.textContent = tabHost.title; - this.intFN(host); + this.intFN(hostname); } else { - tab.dataset.host = host || cHost; - tabHost.title = host || cHost; + tab.dataset.host = hostname || host; + tabHost.title = hostname || host; tabHost.textContent = tabHost.title; } return tab; } } this.tab = new Tabs(this.toolbar); - this.tab.create(this.host); + this.tab.create(host); const tabbody = this.tabbody; const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent; @@ -3101,9 +3061,9 @@ class Container { command: 'navigation' } }); - const makeTHead = (rows) => { + const makeTHead = (rows = []) => { const tr = make('tr'); - for (const r of normalizeTarget(rows)) { + for (const r of rows) { const tparent = make('th', r.class ?? '', r); tr.append(tparent); } @@ -3158,6 +3118,7 @@ class Container { this.unsaved = false; await StorageSystem.setValue('Config', cfg); info('Saved config:', cfg); + this.redirect(); return cfg; } /** @@ -3197,7 +3158,7 @@ class Container { return sty; } } - const sty = make('style', '', { + const sty = make('style', { textContent: css, dataset: { insertedBy: $info.script.name, @@ -3251,7 +3212,7 @@ class Container { return this.isBlacklisted; } getInfo(url) { - const webpage = strToURL(url || this.webpage); + const webpage = this.strToURL(url || this.webpage); const host = this.getHost(webpage.host); const domain = this.getDomain(webpage.host); return { @@ -3329,6 +3290,10 @@ class Container { } this.promptElem.append(el); } + /** + * @template {string | Error} E + * @param {...E} ex + */ showError(...ex) { err(...ex); const error = make('mu-js', 'error'); @@ -3345,34 +3310,74 @@ class Container { error.appendChild(createTextNode(str)); this.footer.append(error); } - updateCounter(count, engine) { - this.counters[engine.name] += count; - this.counters.total += count; - this.updateCounters(); + toArr() { + return Array.from(this.userjsCache.values()).filter(({ _mujs }) => { + return isElem(_mujs.root) && _mujs.info.engine.enabled; + }); } - updateCounters() { - for (const [k, v] of Object.entries(this.counters)) { - if (k === 'total') { - continue; - } - const c = qs(`count-frame[data-counter="${k}"]`, this.countframe); - if (c) { - dom.text(c, v); - } - } - dom.text(this.mainbtn, this.counters.total); + toElem() { + return this.toArr().map(({ _mujs }) => { + return _mujs.root; + }); } refresh() { this.urlBar.placeholder = i18n$('newTab'); - this.counters.total = 0; - for (const engine of cfg.engines) { - this.counters[engine.name] = 0; - } - this.updateCounters(); - dom.cl.remove(qsA('tr[data-engine]', this.tabbody), 'hidden'); + Counter.reset(); + dom.cl.remove(this.toElem(), 'hidden'); dom.cl.remove(qsA('mujs-section[data-name]', this.cfgpage), 'hidden'); dom.prop([this.tabbody, this.rateContainer, this.footer], 'innerHTML', ''); } + /** + * @template {string | URL} S + * @param {S} str + * @returns {URL} + */ + strToURL(str) { + const WIN_LOCATION = window.location ?? BLANK_PAGE; + try { + str = str ?? WIN_LOCATION; + return objToStr(str).includes('URL') ? str : new URL(str); + } catch (ex) { + ex.cause = 'strToURL'; + this.showError(ex); + } + return WIN_LOCATION; + } + /** + * Redirects sleazyfork userscripts from greasyfork.org to sleazyfork.org + * + * Taken from: https://greasyfork.org/scripts/23840 + */ + redirect() { + const locObj = window.top.location; + const { hostname } = locObj; + const gfSite = /greasyfork\.org/.test(hostname); + if (!gfSite && cfg.sleazyredirect) { + return; + } + const otherSite = gfSite ? 'sleazyfork' : 'greasyfork'; + if (!qs('span.sign-in-link')) { + return; + } + if (!/scripts\/\d+/.test(locObj.href)) { + return; + } + if ( + !qs('#script-info') && + (otherSite == 'greasyfork' || qs('div.width-constraint>section>p>a')) + ) { + const str = locObj.href.replace( + /\/\/([^.]+\.)?(greasyfork|sleazyfork)\.org/, + '//$1' + otherSite + '.org' + ); + info(`Redirecting to "${str}"`); + if (isFN(locObj.assign)) { + locObj.assign(str); + } else { + locObj.href = str; + } + } + } } const container = new Container(); // #endregion @@ -3389,8 +3394,6 @@ function primaryFN() { rateContainer, footer, tabbody, - toolbar, - tabhead, cfgpage, fsearch, btnfullscreen, @@ -3400,8 +3403,6 @@ function primaryFN() { btnissue, btngreasy, tab, - userjsCache, - updateCounter, showError } = container; const frameTimeout = container.timeouts.frame; @@ -3471,7 +3472,7 @@ function primaryFN() { } else if (prmpt !== prmptChoice) { installCode = dataset.userjs.replace(/\.user\.css$/, '.user.js'); } - const dlBtn = make('a', '', { + const dlBtn = make('a', { onclick(evt) { evt.preventDefault(); doInstallProcess(evt.target); @@ -3541,7 +3542,6 @@ function primaryFN() { dom.prop(rateContainer, 'innerHTML', ''); if (!dom.prop(target, 'disabled')) { const config = await container.save(); - sleazyRedirect(); if (container.rebuild) { container.cache.clear(); if (config.autofetch) { @@ -3621,7 +3621,7 @@ function primaryFN() { const apTo = (name, elem, root) => { const n = dataUserJS._mujs.code[name]; if (isEmpty(n)) { - const el = make('mujs-a', '', { + const el = make('mujs-a', { textContent: i18n$('listing_none') }); elem.append(el); @@ -3631,7 +3631,7 @@ function primaryFN() { dom.cl.remove(root, 'hidden'); for (const c of n) { if (typeof c === 'string' && c.startsWith('http')) { - const el = make('mujs-a', '', { + const el = make('mujs-a', { textContent: c, dataset: { command: 'open-tab', @@ -3642,7 +3642,7 @@ function primaryFN() { } else if (isObj(c)) { if (name === 'resource') { for (const [k, v] of Object.entries(c)) { - const el = make('mujs-a', '', { + const el = make('mujs-a', { textContent: k ?? 'ERROR' }); if (v.startsWith('http')) { @@ -3652,7 +3652,7 @@ function primaryFN() { elem.append(el); } } else { - const el = make('mujs-a', '', { + const el = make('mujs-a', { textContent: c.text }); if (c.domain) { @@ -3662,15 +3662,17 @@ function primaryFN() { elem.append(el); } } else { - const el = make('mujs-a', '', { + const el = make('mujs-a', { textContent: c }); elem.append(el); } } }; - const m = qsA('mujs-column[data-el="matches"]', target.parentElement.parentElement); - for (const e of normalizeTarget(m)) { + for (const e of qsA( + 'mujs-column[data-el="matches"]', + target.parentElement.parentElement + )) { apTo(e.dataset.type, qs('.mujs-grants', e), e); } } else if (/export-/.test(cmd)) { @@ -3705,7 +3707,6 @@ function primaryFN() { container.rebuild = true; rebuildCfg(); container.save().then((config) => { - sleazyRedirect(); container.cache.clear(); if (config.autofetch) { respHandles.build(); @@ -4038,42 +4039,23 @@ function primaryFN() { // return [...new Set(a)].filter((v) => arr.every((b) => b.includes(v))); // } } - const mergeTemplate = (obj = {}) => { - const template = { - id: 0, - bad_ratings: 0, - good_ratings: 0, - ok_ratings: 0, - daily_installs: 0, - total_installs: 0, - name: 'NOT FOUND', - description: 'NOT FOUND', - version: '0.0.0', - url: BLANK_PAGE, - code_url: BLANK_PAGE, - created_at: Date.now(), - code_updated_at: Date.now(), - locale: 'NOT FOUND', - deleted: false, - users: [ - { - id: 0, - name: 'NOT FOUND', - url: BLANK_PAGE - } - ] - }; - /** @type {ObjectConstructor["hasOwn"]} */ - const hasOwn = - Object.hasOwn || - function hasOwn(it, key) { - return Object.prototype.hasOwnProperty.call(it, key); - }; - for (const key in template) { - if (hasOwn(obj, key)) continue; - obj[key] = template[key]; - } - return obj; + const template = { + id: 0, + bad_ratings: 0, + good_ratings: 0, + ok_ratings: 0, + daily_installs: 0, + total_installs: 0, + name: 'NOT FOUND', + description: 'NOT FOUND', + version: '0.0.0', + url: BLANK_PAGE, + code_url: BLANK_PAGE, + created_at: Date.now(), + code_updated_at: Date.now(), + locale: 'NOT FOUND', + deleted: false, + users: [] }; const mkList = (txt = '', obj = {}) => { if (!obj.root || !obj.type) { @@ -4095,7 +4077,7 @@ function primaryFN() { const list = obj.list ?? []; if (isEmpty(list)) { - const elem = make('mujs-a', '', { + const elem = make('mujs-a', { textContent: i18n$('listing_none') }); applyList.append(elem); @@ -4104,7 +4086,7 @@ function primaryFN() { } for (const c of list) { if (typeof c === 'string' && c.startsWith('http')) { - const elem = make('mujs-a', '', { + const elem = make('mujs-a', { textContent: c, dataset: { command: 'open-tab', @@ -4115,7 +4097,7 @@ function primaryFN() { } else if (isObj(c)) { if (type === 'resource') { for (const [k, v] of Object.entries(c)) { - const elem = make('mujs-a', '', { + const elem = make('mujs-a', { textContent: k ?? 'ERROR' }); if (v.startsWith('http')) { @@ -4125,7 +4107,7 @@ function primaryFN() { applyList.append(elem); } } else { - const elem = make('mujs-a', '', { + const elem = make('mujs-a', { textContent: c.text }); if (c.domain) { @@ -4135,7 +4117,7 @@ function primaryFN() { applyList.append(elem); } } else { - const elem = make('mujs-a', '', { + const elem = make('mujs-a', { textContent: c }); applyList.append(elem); @@ -4165,7 +4147,6 @@ function primaryFN() { * @param { string } engine */ const createjs = (ujs, engine) => { - ujs = mergeTemplate(ujs); // Lets not add this UserJS to the list if (ujs.id === 421603) { return; @@ -4257,7 +4238,7 @@ function primaryFN() { userjs: ujs.code_url } }); - const scriptDownload = make('mu-jsbtn', '', { + const scriptDownload = make('mu-jsbtn', { innerHTML: `${iconSVG.load('install')} ${i18n$('saveFile')}`, dataset: { command: 'download-userjs', @@ -4279,7 +4260,7 @@ function primaryFN() { spellcheck: false, wrap: 'soft' }); - const loadCode = make('mu-jsbtn', '', { + const loadCode = make('mu-jsbtn', { innerHTML: `${iconSVG.load('search')} ${i18n$('preview_code')}`, dataset: { command: 'load-userjs', @@ -4299,7 +4280,7 @@ function primaryFN() { } } for (const u of ujs.users) { - const user = make('mujs-a', '', { + const user = make('mujs-a', { innerHTML: u.name, title: u.url, dataset: { @@ -4362,63 +4343,73 @@ function primaryFN() { codeArea.value = code_obj.get_code_block(); } - if (ujs._mujs.code?.translated) { - tr.classList.add('translated'); - } + if (ujs._mujs.code?.translated) tr.classList.add('translated'); - for (const e of [fname, uframe, fdaily, fupdated, eframe]) { - tr.append(e); - } - tabbody.append(tr); + for (const e of [fname, uframe, fdaily, fupdated, eframe]) tr.append(e); ujs._mujs.root = tr; return tr; }; // #endregion const loadFilters = () => { - const resp = []; - for (const v of Object.values(cfg.filters)) { - if (!v.enabled) { - continue; - } - resp.push(new RegExp(v.regExp, v.flag)); - } - return { - regExp: resp, - get(name) { - for (const v of Object.values(cfg.filters)) { - if (v.name === name) { - return new RegExp(v.regExp, v.flag) - }; + /** @type {Map} */ + const pool = new Map(); + const handles = { + pool, + enabled() { + return [...pool.values()].filter((o) => o.enabled); + }, + refresh() { + if (!Object.is(pool.size, 0)) pool.clear(); + for (const [key, value] of Object.entries(cfg.filters)) { + if (!pool.has(key)) + pool.set(key, { + ...value, + reg: new RegExp(value.regExp, value.flag), + keyReg: new RegExp(key.trim().toLocaleLowerCase(), 'gi'), + valueReg: new RegExp(value.name.trim().toLocaleLowerCase(), 'gi') + }); } - // return resp.find(r => r.name === name); + return this; + }, + get(str) { + return [...pool.values()].find((v) => v.keyReg.test(str) || v.valueReg.test(str)); }, + /** + * @param { import("../typings/types.d.ts").GSForkQuery } param0 + */ match({ name, users }) { - if (isBlank(resp)) { - return true; - } - const strArr = [{ name }, ...users]; - for (const r of resp) { - const v = strArr.find((o) => o.name.match(r)); - if (v) { - return false; - } + const p = handles.enabled(); + if (Object.is(p.length, 0)) return true; + for (const v of p) { + if ([{ name }, ...users].find((o) => o.name.match(v.reg))) return false; } return true; } }; + for (const [key, value] of Object.entries(cfg.filters)) { + if (!pool.has(key)) + pool.set(key, { + ...value, + reg: new RegExp(value.regExp, value.flag), + keyReg: new RegExp(key.trim().toLocaleLowerCase(), 'gi'), + valueReg: new RegExp(value.name.trim().toLocaleLowerCase(), 'gi') + }); + } + return handles.refresh(); }; // #region List class List { engines; - cache; intHost; - constructor(host = undefined) { + constructor(hostname = undefined) { this.build = this.build.bind(this); - if (isEmpty(host)) host = container.host; + this.toArr = this.toArr.bind(this); + this.groupBy = this.groupBy.bind(this); + this.sortRecords = this.sortRecords.bind(this); + if (isEmpty(hostname)) hostname = container.host; this.engines = cfg.engines; - this.cache = container.cache.get(host); - this.host = host; + this.host = hostname; } set host(hostname) { @@ -4431,27 +4422,24 @@ function primaryFN() { } container.cache.set(hostname, engineTemplate); } - if (container.checkBlacklist(hostname)) { + this.blacklisted = container.checkBlacklist(hostname); + if (this.blacklisted) { showError(`Blacklisted "${hostname}"`); timeoutFrame(); - this.blacklisted = true; - } else { - this.blacklisted = false; } - const isSupported = (name) => { - for (const [k, v] of Object.entries(engineUnsupported)) { - if (k !== name) { - continue; - } - if (v.includes(hostname)) { - return false; - } + this.engines = cfg.engines.filter((e) => { + if (!e.enabled) { + return false; + } + const v = engineUnsupported[e.name] ?? []; + if (v.includes(hostname)) { + showError(`Engine: "${e.name}" unsupported on "${hostname}"`); + timeoutFrame(); + return false; } return true; - }; - this.engines = cfg.engines.filter((e) => e.enabled && isSupported(e.name)); - this.cache = container.cache.get(hostname); + }); } get host() { @@ -4462,235 +4450,228 @@ function primaryFN() { build() { try { container.refresh(); - if (this.blacklisted) { - return; - } - if (isEmpty(this.engines)) { + const { blacklisted, engines, host, toArr } = this; + if (blacklisted || isEmpty(engines)) { container.opacityMin = '0'; mainframe.style.opacity = container.opacityMin; return; } - info(' Building list', { cache: this.cache, engines: this.engines }); - const customRecords = []; - const host = this.host; - const arr = []; + const fetchRecords = []; const bsFilter = loadFilters(); + const hostCache = toArr(); - for (const engine of this.engines) { - const cEngine = this.cache[`${engine.name}`]; - if (!isEmpty(cEngine)) { - for (const ujs of cEngine) { - if (isElem(ujs._mujs.root)) { - tabbody.append(ujs._mujs.root); + info('Building list', { hostCache, engines }); + + if (isBlank(hostCache)) { + for (const engine of engines) { + info(`Fetching from "${engine.name}" for "${host}"`); + const respError = (error) => { + if (!error.cause) error.cause = engine.name; + if (error.message.startsWith('429')) { + showError(`Engine: "${engine.name}" Too many requests...`); + return; } - } - updateCounter(cEngine.length, engine); - continue; - } - const respError = (error) => { - if (!error.cause) error.cause = engine.name; - if (error.message.startsWith('429')) { - showError(`Engine: "${engine.name}" Too many requests...`); - return; - } - showError(`Engine: "${engine.name}"`, error.message); - }; - const _mujs = (d) => { - const obj = { - ...d, - _mujs: { - root: {}, - info: { - engine, - host - }, - code: { - antifeatures: [], - grant: [], - match: [], - meta: {}, - request: async function (translate = false, code_url) { - if (this.data) { - return this; - } - this.data = ''; - /** @type { string } */ - const code = await Network.req(code_url ?? d.code_url, 'GET', 'text').catch( - showError - ); - if (typeof code !== 'string') { - return this; - } - Object.assign(this, { - data: code, - code_size: [Network.format(code.length)] - }); - const grantSet = new Set(); - const afSet = new Set(); - const code_obj = new ParseUserJS(code); - const meta = code_obj.parse_meta(); - const applies_to_names = code_obj.calculate_applies_to_names(); + showError(`Engine: "${engine.name}"`, error.message); + }; + const _mujs = (d) => { + const obj = { + ...template, + ...d, + _mujs: { + root: {}, + info: { + engine, + host + }, + code: { + antifeatures: [], + grant: [], + match: [], + meta: {}, + request: async function (translate = false, code_url) { + if (this.data) { + return this; + } + this.data = ''; + /** @type { string } */ + const code = await Network.req(code_url ?? d.code_url, 'GET', 'text').catch( + showError + ); + if (typeof code !== 'string') { + return this; + } + Object.assign(this, { + data: code, + code_size: [Network.format(code.length)] + }); + const grantSet = new Set(); + const afSet = new Set(); + const code_obj = new ParseUserJS(code); + const meta = code_obj.parse_meta(); + const applies_to_names = code_obj.calculate_applies_to_names(); - if (translate) { - for (const lng of language.cache) { - if (meta[`name:${lng}`]) { - Object.assign(obj, { - name: meta[`name:${lng}`] - }); - this.translated = true; - } - if (meta[`description:${lng}`]) { - Object.assign(obj, { - description: meta[`description:${lng}`] - }); - this.translated = true; + if (translate) { + for (const k of userjs.pool.keys()) { + if (meta[`name:${k}`]) { + Object.assign(obj, { + name: meta[`name:${k}`] + }); + this.translated = true; + } + if (meta[`description:${k}`]) { + Object.assign(obj, { + description: meta[`description:${k}`] + }); + this.translated = true; + } } } - } - for (const [key, value] of Object.entries(meta)) { - if (/grant/.test(key)) { - for (const v of normalizeTarget(value, false)) { - if (grantSet.has(v)) { - continue; + for (const [key, value] of Object.entries(meta)) { + if (/grant/.test(key)) { + for (const v of normalizeTarget(value, false)) { + if (grantSet.has(v)) { + continue; + } + grantSet.add(v); } - grantSet.add(v); - } - } else if (/antifeature/.test(key)) { - for (const v of normalizeTarget(value, false)) { - if (afSet.has(v)) { - continue; + } else if (/antifeature/.test(key)) { + for (const v of normalizeTarget(value, false)) { + if (afSet.has(v)) { + continue; + } + afSet.add(v); } - afSet.add(v); } } - } - if (typeof meta.require === 'string') { - const s = meta.require; - meta.require = [s]; - } - if (meta.resource) { - const obj = {}; - if (typeof meta.resource === 'string') { - const reg = /(.+)\s+(.+)/.exec(meta.resource); - if (reg) { - obj[reg[1].trim()] = reg[2]; - } - } else { - for (const r of meta.resource) { - const reg = /(.+)\s+(http.+)/.exec(r); + if (typeof meta.require === 'string') { + const s = meta.require; + meta.require = [s]; + } + if (meta.resource) { + const obj = {}; + if (typeof meta.resource === 'string') { + const reg = /(.+)\s+(.+)/.exec(meta.resource); if (reg) { obj[reg[1].trim()] = reg[2]; } + } else { + for (const r of meta.resource) { + const reg = /(.+)\s+(http.+)/.exec(r); + if (reg) { + obj[reg[1].trim()] = reg[2]; + } + } } + meta.resource = obj; } - meta.resource = obj; - } - Object.assign(this, { - meta, - match: applies_to_names, - grant: [...grantSet], - antifeatures: [...afSet] - }); + Object.assign(this, { + meta, + match: applies_to_names, + grant: [...grantSet], + antifeatures: [...afSet] + }); - return this; + return this; + } } } - } + }; + return obj; }; - return obj; - }; - const toQuery = (fallback) => { - if (engine.query) { - return decodeURIComponent(engine.query).replace(/\{host\}/g, host); - } - return fallback; - }; - /** - * @param { import("../typings/types.d.ts").GSFork } dataQ - */ - const forkFN = async (dataQ) => { - if (!dataQ) { - showError('Invalid data received from the server, check internet connection'); - return; - } /** - * @type { import("../typings/types.d.ts").GSForkQuery[] } + * Prior to UserScript v7.0.0 + * @template {string} F + * @param {F} fallback + * @returns {F} */ - const dq = Array.isArray(dataQ) - ? dataQ - : Array.isArray(dataQ.query) - ? dataQ.query - : []; - const dataA = dq - .filter(Boolean) - .filter((d) => !d.deleted) - .filter(bsFilter.match); - if (isBlank(dataA)) { - return; - } - const data = dataA.map(_mujs); - const otherLng = []; + const toQuery = (fallback) => { + if (engine.query) { + return decodeURIComponent(engine.query).replace(/\{host\}/g, host); + } + return fallback; + }; /** - * @param {import("../typings/types.d.ts").GSForkQuery} d - * @returns {boolean} + * @param { import("../typings/types.d.ts").GSFork } dataQ */ - const inUserLanguage = (d) => { - const dlocal = d.locale.split('-')[0] ?? d.locale; - if (language.cache.includes(dlocal)) { - return true; + const forkFN = async (dataQ) => { + if (!dataQ) { + showError('Invalid data received from the server, check internet connection'); + return; } - otherLng.push(d); - return false; - }; - const filterLang = data.filter((d) => { - if (cfg.filterlang && !inUserLanguage(d)) { - return false; + /** + * @type { import("../typings/types.d.ts").GSForkQuery[] } + */ + const dq = Array.isArray(dataQ) + ? dataQ + : Array.isArray(dataQ.query) + ? dataQ.query + : []; + const dataA = dq + .filter(Boolean) + .filter((d) => !d.deleted) + .filter(bsFilter.match); + if (isBlank(dataA)) { + return; } - return true; - }); - let finalList = filterLang; - const hds = []; - for (const ujs of otherLng) { - const c = await ujs._mujs.code.request(true); - if (c.translated) { - hds.push(ujs); + const data = dataA.map(_mujs); + const otherLng = []; + /** + * @param {import("../typings/types.d.ts").GSForkQuery} d + * @returns {boolean} + */ + const inUserLanguage = (d) => { + if (userjs.pool.has(d.locale.split('-')[0] ?? d.locale)) { + return true; + } + otherLng.push(d); + return false; + }; + const filterLang = data.filter((d) => { + if (cfg.filterlang && !inUserLanguage(d)) { + return false; + } + return true; + }); + let finalList = filterLang; + const hds = []; + for (const ujs of otherLng) { + const c = await ujs._mujs.code.request(true); + if (c.translated) { + hds.push(ujs); + } } - } - finalList = union(hds, filterLang); + finalList = union(hds, filterLang); - for (const ujs of finalList) { - if (cfg.codePreview && !ujs._mujs.code.data) { - await ujs._mujs.code.request(); - } - createjs(ujs, engine.name); - } - this.cache[engine.name].push(...finalList); - updateCounter(finalList.length, engine); - }; - /** - * @param {Document} htmlDocument - */ - const openuserjs = async (htmlDocument) => { - try { - if (!htmlDocument) { - showError('Invalid data received from the server, TODO fix this'); - return; + for (const ujs of finalList) { + if (cfg.codePreview && !ujs._mujs.code.data) { + await ujs._mujs.code.request(); + } + createjs(ujs, engine.name); } - const selected = htmlDocument.documentElement; - if (/openuserjs/gi.test(engine.name)) { - for (const i of qsA('.col-sm-8 .tr-link', selected)) { - while (isNull(qs('.script-version', i))) { - await new Promise((resolve) => requestAnimationFrame(resolve)); - } - const fixurl = dom - .prop(qs('.tr-link-a', i), 'href') - .replace( - new RegExp(document.location.origin, 'gi'), - 'https://openuserjs.org' - ); - const ujs = mergeTemplate( - _mujs({ + }; + /** + * @param {Document} htmlDocument + */ + const openuserjs = async (htmlDocument) => { + try { + if (!htmlDocument) { + showError('Invalid data received from the server, TODO fix this'); + return; + } + const selected = htmlDocument.documentElement; + if (/openuserjs/gi.test(engine.name)) { + for (const i of qsA('.col-sm-8 .tr-link', selected)) { + while (isNull(qs('.script-version', i))) { + await new Promise((resolve) => requestAnimationFrame(resolve)); + } + const fixurl = dom + .prop(qs('.tr-link-a', i), 'href') + .replace( + new RegExp(document.location.origin, 'gi'), + 'https://openuserjs.org' + ); + const ujs = _mujs({ name: dom.text(qs('.tr-link-a', i)), description: dom.text(qs('p', i)), version: dom.text(qs('.script-version', i)), @@ -4705,33 +4686,28 @@ function primaryFN() { url: dom.prop(qs('.inline-block a', i), 'href') } ] - }) - ); - if (bsFilter.match(ujs)) { - continue; - } - if (cfg.codePreview && !ujs._mujs.code.data) { - await ujs._mujs.code.request(); + }); + if (bsFilter.match(ujs)) { + continue; + } + if (cfg.codePreview && !ujs._mujs.code.data) { + await ujs._mujs.code.request(); + } + createjs(ujs, engine.name); } - createjs(ujs, engine.name); - customRecords.push(ujs); } + } catch (ex) { + showError(ex); } - this.cache[engine.name].push(...customRecords); - updateCounter(customRecords.length, engine); - } catch (ex) { - showError(ex); - } - }; - const gitFN = async (data) => { - try { - if (isBlank(data.items)) { - showError('Invalid data received from the server, TODO fix this'); - return; - } - for (const r of data.items) { - const ujs = mergeTemplate( - _mujs({ + }; + const gitFN = async (data) => { + try { + if (isBlank(data.items)) { + showError('Invalid data received from the server, TODO fix this'); + return; + } + for (const r of data.items) { + const ujs = _mujs({ name: r.name, description: isEmpty(r.repository.description) ? i18n$('no_license') @@ -4746,87 +4722,118 @@ function primaryFN() { url: r.repository.owner.html_url } ] - }) - ); - if (bsFilter.match(ujs)) { - continue; - } - if (cfg.codePreview && !ujs._mujs.code.data) { - await ujs._mujs.code.request(); + }); + if (bsFilter.match(ujs)) { + continue; + } + if (cfg.codePreview && !ujs._mujs.code.data) { + await ujs._mujs.code.request(); + } + createjs(ujs, engine.name); } - createjs(ujs, engine.name); - customRecords.push(ujs); + } catch (ex) { + showError(ex); } - this.cache[engine.name].push(...customRecords); - updateCounter(data.items.length, engine); - } catch (ex) { - showError(ex); - } - }; - let netFN; - if (/github/gi.test(engine.name)) { - if (isEmpty(engine.token)) { - showError(`"${engine.name}" requires a token to use`); - continue; - } - netFN = Network.req( - toQuery( - `${engine.url}"// ==UserScript=="+${host}+ "// ==/UserScript=="+in:file+language:js&per_page=30` - ), - 'GET', - 'json', - { - headers: { - Accept: 'application/vnd.github+json', - Authorization: `Bearer ${engine.token}`, - 'X-GitHub-Api-Version': '2022-11-28' - } + }; + let netFN; + if (/github/gi.test(engine.name)) { + if (isEmpty(engine.token)) { + showError(`"${engine.name}" requires a token to use`); + continue; } - ) - .then(gitFN) - .then(() => { - Network.req('https://api.github.com/rate_limit', 'GET', 'json', { + netFN = Network.req( + toQuery( + `${engine.url}"// ==UserScript=="+${host}+ "// ==/UserScript=="+in:file+language:js&per_page=30` + ), + 'GET', + 'json', + { headers: { Accept: 'application/vnd.github+json', Authorization: `Bearer ${engine.token}`, 'X-GitHub-Api-Version': '2022-11-28' } - }) - .then((data) => { - for (const [key, value] of Object.entries(data.resources.code_search)) { - const txt = make('mujs-row', 'rate-info', { - textContent: `${key.toUpperCase()}: ${value}` - }); - rateContainer.append(txt); + } + ) + .then(gitFN) + .then(() => { + Network.req('https://api.github.com/rate_limit', 'GET', 'json', { + headers: { + Accept: 'application/vnd.github+json', + Authorization: `Bearer ${engine.token}`, + 'X-GitHub-Api-Version': '2022-11-28' } }) - .catch(respError); - }); - } else if (/openuserjs/gi.test(engine.name)) { - netFN = Network.req(toQuery(`${engine.url}${host}`), 'GET', 'document').then( - openuserjs - ); - } else { - netFN = Network.req( - toQuery(`${engine.url}/scripts/by-site/${host}.json?language=all`) - ).then(forkFN); - } - if (netFN) { - arr.push(netFN.catch(respError)); + .then((data) => { + for (const [key, value] of Object.entries(data.resources.code_search)) { + const txt = make('mujs-row', 'rate-info', { + textContent: `${key.toUpperCase()}: ${value}` + }); + rateContainer.append(txt); + } + }) + .catch(respError); + }); + } else if (/openuserjs/gi.test(engine.name)) { + netFN = Network.req(toQuery(`${engine.url}${host}`), 'GET', 'document').then( + openuserjs + ); + } else { + netFN = Network.req( + toQuery(`${engine.url}/scripts/by-site/${host}.json?language=all`) + ).then(forkFN); + } + if (netFN) { + fetchRecords.push(netFN.catch(respError)); + } } + } else { + for (const ujs of hostCache) tabbody.append(ujs._mujs.root); } urlBar.placeholder = i18n$('search_placeholder'); urlBar.value = ''; - Promise.allSettled(arr).then(() => { - tabhead.rows[0].cells[2].dispatchEvent(new MouseEvent('click')); - tabhead.rows[0].cells[2].dispatchEvent(new MouseEvent('click')); - }); + if (isBlank(fetchRecords)) { + this.sortRecords(); + return; + } + Promise.allSettled(fetchRecords).then(this.sortRecords).catch(showError); } catch (ex) { showError(ex); } } + + sortRecords() { + const arr = this.toArr(); + for (const ujs of arr.flat().sort((a, b) => { + const sortType = cfg.autoSort ?? 'daily_installs'; + return b[sortType] - a[sortType]; + })) { + if (isElem(ujs._mujs.root)) tabbody.append(ujs._mujs.root); + } + for (const [name, value] of Object.entries(this.groupBy(arr))) + Counter.update(value.length, { name }); + } + + toArr() { + const h = this.intHost; + return container.toArr().filter(({ _mujs }) => _mujs.info.host === h); + } + + groupBy(arr) { + const callback = ({ _mujs }) => _mujs.info.engine.name; + if (isFN(Object.groupBy)) { + return Object.groupBy(arr, callback); + } + /** [Object.groupBy polyfill](https://gist.github.com/gtrabanco/7c97bd41aa74af974fa935bfb5044b6e) */ + return arr.reduce((acc = {}, ...args) => { + const key = callback(...args); + acc[key] ??= []; + acc[key].push(args[0]); + return acc; + }, {}); + } // #endregion } const MUList = new List(); @@ -4850,17 +4857,17 @@ function primaryFN() { const makesection = (name, tag) => { tag = tag ?? i18n$('no_license'); name = name ?? i18n$('no_license'); - const sec = make('mujs-section', '', { + const sec = make('mujs-section', { dataset: { name: tag } }); - const lb = make('label', '', { + const lb = make('label', { dataset: { command: tag } }); - const divDesc = make('mu-js', '', { + const divDesc = make('mu-js', { textContent: name }); ael(sec, 'click', (evt) => { @@ -4899,13 +4906,13 @@ function primaryFN() { const makerow = (desc, type = null, nm, attrs = {}) => { desc = desc ?? i18n$('no_license'); nm = nm ?? i18n$('no_license'); - const sec = make('mujs-section', '', { + const sec = make('mujs-section', { dataset: { name: nm } }); const lb = make('label'); - const divDesc = make('mu-js', '', { + const divDesc = make('mu-js', { textContent: desc }); lb.append(divDesc); @@ -4914,7 +4921,7 @@ function primaryFN() { if (isNull(type)) { return lb; } - const inp = make('input', '', { + const inp = make('input', { type, dataset: { name: nm @@ -4926,7 +4933,7 @@ function primaryFN() { } if (type === 'checkbox') { const inlab = make('mu-js', 'mujs-inlab'); - const la = make('label', '', { + const la = make('label', { onclick() { inp.dispatchEvent(new MouseEvent('click')); } @@ -4949,7 +4956,7 @@ function primaryFN() { if (engine.query) { const d = DEFAULT_CONFIG.engines.find((e) => e.name === engine.name); - const urlInp = make('input', '', { + const urlInp = make('input', { type: 'text', defaultValue: '', value: decodeURIComponent(engine.query) ?? '', @@ -4971,7 +4978,7 @@ function primaryFN() { sec.append(urlInp); } if (engine.name === 'github') { - const ghToken = make('input', '', { + const ghToken = make('input', { type: 'text', defaultValue: '', value: engine.token ?? '', @@ -5012,7 +5019,29 @@ function primaryFN() { [tag]: text } }); - const inp = make('input', '', { + if (type === 'select') { + const inp = make('select', { + dataset: { + [tag]: text + }, + ...attrs + }); + for (const selV of Object.keys(template)) { + if (selV === 'deleted' || selV === 'users') continue; + const o = make('option', { + value: selV, + textContent: selV + }); + inp.append(o); + } + inp.value = cfg[value]; + lb.append(inp); + if (sections[tag]) { + sections[tag].append(lb); + } + return lb; + } + const inp = make('input', { type, dataset: { [tag]: text @@ -5026,7 +5055,7 @@ function primaryFN() { if (type === 'checkbox') { const inlab = make('mu-js', 'mujs-inlab'); - const la = make('label', '', { + const la = make('label', { onclick() { inp.dispatchEvent(new MouseEvent('click')); } @@ -5116,7 +5145,9 @@ function primaryFN() { } } }); + mkSection('Clear on Tab close', 'clearTabCache', 'checkbox', 'load'); + mkSection('Default Sort', 'autoSort', 'select', 'list'); mkSection(i18n$('filter'), 'filterlang', 'checkbox', 'list'); mkSection(i18n$('preview_code'), 'codePreview', 'checkbox', 'list'); mkSection('Recommend author', 'recommend-author', 'checkbox', 'list'); @@ -5138,7 +5169,7 @@ function primaryFN() { theme: k } }); - const inp = make('input', '', { + const inp = make('input', { type: 'text', defaultValue: '', value: v ?? '', @@ -5212,7 +5243,7 @@ function primaryFN() { blacklist: key } }); - const inp = make('input', '', { + const inp = make('input', { type: 'text', defaultValue: '', value: v ?? '', @@ -5242,7 +5273,7 @@ function primaryFN() { } } }); - const selType = make('select', '', { + const selType = make('select', { disabled, dataset: { blacklist: key @@ -5250,14 +5281,14 @@ function primaryFN() { }); if (disabled) { inp.readOnly = true; - const o = make('option', '', { + const o = make('option', { value: type, textContent: type }); selType.append(o); } else { for (const selV of ['String', 'RegExp', 'Object']) { - const o = make('option', '', { + const o = make('option', { value: selV, textContent: selV }); @@ -5268,7 +5299,7 @@ function primaryFN() { lb.append(inp, selType); sections.blacklist.append(lb); }; - // const blacklist = make('textarea', '', { + // const blacklist = make('textarea', { // dataset: { // name: 'blacklist' // }, @@ -5297,19 +5328,19 @@ function primaryFN() { // } // }); // cfgMap.set('blacklist', blacklist); - // const addList = make('mujs-add', '', { + // const addList = make('mujs-add', { // textContent: '+', // dataset: { // command: 'new-list' // } // }); - // const n = make('input', '', { + // const n = make('input', { // type: 'text', // defaultValue: '', // value: '', // placeholder: 'Name', // }); - // const inpValue = make('input', '', { + // const inpValue = make('input', { // type: 'text', // defaultValue: '', // value: '', @@ -5375,15 +5406,16 @@ function primaryFN() { * @type { string } */ const val = evt.target.value; + const section = qsA('mujs-section[data-name]', cfgpage); if (isEmpty(val)) { - dom.cl.remove(qsA('tr[data-engine]', tabbody), 'hidden'); - dom.cl.remove(qsA('mujs-section[data-name]', cfgpage), 'hidden'); + dom.cl.remove(container.toElem(), 'hidden'); + dom.cl.remove(section, 'hidden'); return; } const finds = new Set(); if (!dom.cl.has(cfgpage, 'hidden')) { const reg = new RegExp(val, 'gi'); - for (const elem of qsA('mujs-section[data-name]', cfgpage)) { + for (const elem of section) { if (!isElem(elem)) { continue; } @@ -5394,10 +5426,13 @@ function primaryFN() { finds.add(elem); } } - dom.cl.add(qsA('mujs-section[data-name]', cfgpage), 'hidden'); + dom.cl.add(section, 'hidden'); dom.cl.remove([...finds], 'hidden'); return; } + const cacheValues = container.toArr().filter(({ _mujs }) => { + return !finds.has(_mujs.root); + }); /** * @param {RegExpMatchArray} regExp * @param {keyof import("../typings/types.d.ts").GSForkQuery} key @@ -5405,43 +5440,29 @@ function primaryFN() { const ezQuery = (regExp, key) => { const q_value = val.replace(regExp, ''); const reg = new RegExp(q_value, 'gi'); - for (const v of userjsCache.values()) { - const elem = v._mujs.root; - if (!isElem(elem)) { - continue; - } - if (finds.has(elem)) { - continue; - } + for (const v of cacheValues) { let k = v[key]; if (typeof k === 'number') { k = `${v[key]}`; } if (k && k.match(reg)) { - finds.add(elem); + finds.add(v._mujs.root); } } }; if (val.match(/^(code_url|url):/)) { ezQuery(/^(code_url|url):/, 'code_url'); } else if (val.match(/^(author|users?):/)) { - const q_value = val.replace(/^(author|users?):/, ''); - const reg = new RegExp(q_value, 'gi'); - for (const v of userjsCache.values()) { - const elem = v._mujs.root; - if (!isElem(elem)) { - continue; - } - if (finds.has(elem)) { - continue; - } - if (v.users) { + const parts = /^[\w_]+:(.+)/.exec(val); + if (parts) { + const reg = new RegExp(parts[1], 'gi'); + for (const v of cacheValues.filter((v) => !isEmpty(v.users))) { for (const user of v.users) { for (const value of Object.values(user)) { if (typeof value === 'string' && value.match(reg)) { - finds.add(elem); + finds.add(v._mujs.root); } else if (typeof value === 'number' && `${value}`.match(reg)) { - finds.add(elem); + finds.add(v._mujs.root); } } } @@ -5458,96 +5479,52 @@ function primaryFN() { } else if (val.match(/^description:/)) { ezQuery(/^description:/, 'description'); } else if (val.match(/^(search_engine|engine):/)) { - const q_value = val.replace(/^(search_engine|engine):/, ''); - const reg = new RegExp(q_value, 'gi'); - for (const v of userjsCache.values()) { - const elem = v._mujs.root; - if (!isElem(elem)) { - continue; - } - if (finds.has(elem)) { - continue; - } - if (v._mujs.info.engine) { - for (const value of Object.values(v._mujs.info.engine)) { - if (typeof value === 'string' && value.match(reg)) { - finds.add(elem); - } + const parts = /^[\w_]+:(\w+)/.exec(val); + if (parts) { + const reg = new RegExp(parts[1], 'gi'); + for (const { _mujs } of cacheValues) { + if (!_mujs.info.engine.name.match(reg)) { + continue; } + finds.add(_mujs.root); } } } else if (val.match(/^filter:/)) { const parts = /^\w+:(.+)/.exec(val); if (parts) { const bsFilter = loadFilters(); - const p = parts[1].trim().toLocaleLowerCase(); - for (const [key, value] of Object.entries(cfg.filters)) { - const k = key.trim().toLocaleLowerCase(); - const v = value.name.trim().toLocaleLowerCase(); - if (p.includes(k) || p.includes(v)) { - const reg = bsFilter.get(value.name); - if (reg) { - [...userjsCache.values()].filter(({ name, users, _mujs }) => { - const elem = _mujs.root; - if (!isElem(elem)) { - return false; - } - if (finds.has(elem)) { - return false; - } - const strArr = [{ name }, ...users]; - const v = strArr.find((o) => o.name.match(reg)); - if (v) { - return false; - } - finds.add(elem); - return true; - }); + const filterType = bsFilter.get(parts[1].trim().toLocaleLowerCase()); + if (filterType) { + const { reg } = filterType; + for (const { name, users, _mujs } of cacheValues) { + if ([{ name }, ...users].find((o) => o.name.match(reg))) { + continue; } + finds.add(_mujs.root); } } } } else if (val.match(/^recommend:/)) { - for (const v of userjsCache.values()) { - const elem = v._mujs.root; - if (!isElem(elem)) { - continue; - } - if (finds.has(elem)) { - continue; - } - if (v.users.find(u => u.id === authorID)) { - finds.add(elem); - } else if (goodUserJS.includes(v.url)) { - finds.add(elem); - } else if (goodUserJS.includes(v.id)) { - finds.add(elem); + for (const { url, id, users, _mujs } of cacheValues) { + if ( + users.find((u) => u.id === authorID) || + goodUserJS.includes(url) || + goodUserJS.includes(id) + ) { + finds.add(_mujs.root); } } } else { const reg = new RegExp(val, 'gi'); - for (const v of userjsCache.values()) { - const elem = v._mujs.root; - if (!isElem(elem)) { - continue; - } - if (finds.has(elem)) { - continue; - } - if (v.name && v.name.match(reg)) { - finds.add(elem); - } - if (v.description && v.description.match(reg)) { - finds.add(elem); - } + for (const v of cacheValues) { + if (v.name && v.name.match(reg)) finds.add(v._mujs.root); + if (v.description && v.description.match(reg)) finds.add(v._mujs.root); const code_data = v._mujs.code.data; if (code_data) { const code_obj = new ParseUserJS(code_data); const meta = code_obj.parse_meta(code_data); for (const key of Object.keys(meta)) { - if (/name|desc/i.test(key) && key.match(reg)) { - finds.add(elem); - } + if (/name|desc/i.test(key) && key.match(reg)) finds.add(v._mujs.root); } } } @@ -5558,16 +5535,19 @@ function primaryFN() { ael(urlBar, 'change', (evt) => { evt.preventDefault(); const val = evt.target.value; - if (urlBar.placeholder === i18n$('newTab') && qs('mujs-tab.active', toolbar)) { - const tabElem = qs('mujs-tab.active', toolbar); - const tabHost = qs('mujs-host', tabElem); - if (val.startsWith(tab.protocal)) { + const tabElem = tab.getActive(); + if (urlBar.placeholder === i18n$('newTab') && tabElem) { + const tabHost = tabElem.firstElementChild; + if (tab.protoReg.test(val)) { + const createdTab = tab.getTab(val); tab.close(tabElem); - if (tab.hasTab(val)) { - tab.active(tab.Tab.get(val)); + if (createdTab) { + tab.active(createdTab); } else { tab.create(val); } + evt.target.placeholder = i18n$('search_placeholder'); + evt.target.value = ''; return; } else if (val === '*') { tabElem.dataset.host = val; @@ -5587,7 +5567,6 @@ function primaryFN() { tabHost.textContent = value; MUList.host = value; respHandles.build(); - return; } }); scheduler.postTask(makecfg, { priority: 'background' }); @@ -5613,20 +5592,19 @@ function primaryFN() { * @param { (this: F, doc: Document) => * } onDomReady */ const loadDOM = (onDomReady) => { - if (!isFN(onDomReady)) { - return; - } - if (document.readyState === 'interactive' || document.readyState === 'complete') { - onDomReady(document); - return; + if (isFN(onDomReady)) { + if (document.readyState === 'interactive' || document.readyState === 'complete') { + onDomReady(document); + } else { + document.addEventListener('DOMContentLoaded', (evt) => onDomReady(evt.target), { + once: true + }); + } } - document.addEventListener('DOMContentLoaded', (evt) => onDomReady(evt.target), { - once: true - }); }; -const init = async () => { - const stored = await StorageSystem.getValue('Config', DEFAULT_CONFIG); +const init = async (prefix = 'Config') => { + const stored = await StorageSystem.getValue(prefix, DEFAULT_CONFIG); cfg = { ...DEFAULT_CONFIG, ...stored @@ -5644,8 +5622,7 @@ const init = async () => { cause: 'loadDOM' }); } - trustedTypes.init(); - sleazyRedirect(); + container.redirect(); if (cfg.autoinject) container.inject(primaryFN, doc); @@ -5662,4 +5639,4 @@ const init = async () => { }; init(); -})(); \ No newline at end of file +})(); diff --git a/package.json b/package.json index f4f73ec..2773e46 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "url": "https://github.com/magicoflolis/Userscript-Plus/issues" }, "userJS": { - "version": "7.3.0", + "version": "7.4.0", "name": "Magic Userscript+ : Show Site All UserJS", "description": "Finds available userscripts for the current webpage.", "bugs": "https://github.com/magicoflolis/Userscript-Plus/issues", @@ -61,22 +61,27 @@ "greasyfork.org", "sleazyfork.org", "github.com", + "githubusercontent.com", "openuserjs.org" ], "grant": [ + "GM_addValueChangeListener", "GM_addElement", "GM_info", "GM_getValue", "GM_openInTab", "GM_setValue", "GM_registerMenuCommand", + "GM_removeValueChangeListener", "GM_xmlhttpRequest", + "GM.addValueChangeListener", "GM.addElement", "GM.info", "GM.getValue", "GM.openInTab", "GM.setValue", "GM.registerMenuCommand", + "GM.removeValueChangeListener", "GM.xmlHttpRequest" ], "exclude": [], @@ -105,12 +110,14 @@ "web-run:firefox-android": "web-ext run --config=./tools/web-ext.js -t firefox-android --firefox-apk org.mozilla.firefox" }, "devDependencies": { + "@eslint/js": "^9.20.0", "@swc/cli": "^0.6.0", - "@swc/core": "^1.10.14", - "@types/chrome": "0.0.301", + "@swc/core": "^1.10.16", + "@types/chrome": "0.0.304", + "@types/eslint-config-prettier": "^6.11.3", "@types/firefox-webext-browser": "120.0.4", "@types/greasemonkey": "4.0.7", - "@types/node": "^22.13.1", + "@types/node": "^22.13.4", "@types/tampermonkey": "^5.0.4", "@types/trusted-types": "^2.0.7", "@types/webpack": "^5.28.5", @@ -121,21 +128,21 @@ "crx3": "^1.1.3", "css-loader": "^7.1.2", "dotenv": "^16.4.7", - "eslint": "^9.19.0", + "eslint": "^9.20.1", "eslint-config-prettier": "^10.0.1", - "globals": "^15.14.0", + "globals": "^15.15.0", "http-server": "^14.1.1", "mini-css-extract-plugin": "^2.9.2", "path-browserify": "^1.0.1", - "prettier": "^3.4.2", - "sass-embedded": "^1.83.4", - "sass-loader": "^16.0.4", + "prettier": "^3.5.1", + "sass-embedded": "^1.85.0", + "sass-loader": "^16.0.5", "swc-loader": "^0.2.6", "terser-webpack-plugin": "^5.3.11", "typescript": "^5.7.3", "watchpack": "^2.4.2", "web-ext": "^8.4.0", - "webpack": "^5.97.1", + "webpack": "^5.98.0", "webpack-cli": "^6.0.1", "webpack-merge": "^6.0.1" }, @@ -154,11 +161,21 @@ "violentmonkey" ], "webExt": { - "sourceDir": "./build/firefox/", - "artifactsDir": "./build" + "artifactsDir": "./build", + "build": { + "overwriteDest": true + }, + "sourceDir": "./build/firefox" }, "engines": { - "node": ">=20" + "node": ">=18", + "pnpm": ">=9" }, - "packageManager": "pnpm@9.12.1+sha512.e5a7e52a4183a02d5931057f7a0dbff9d5e9ce3161e33fa68ae392125b79282a8a8a470a51dfc8a0ed86221442eb2fb57019b0990ed24fab519bf0e1bc5ccfc4" + "packageManager": "pnpm@10.3.0+sha512.ee592eda8815a8a293c206bb0917c4bb0ff274c50def7cbc17be05ec641fc2d1b02490ce660061356bd0d126a4d7eb2ec8830e6959fb8a447571c631d5a2442d", + "pnpm": { + "onlyBuiltDependencies": [ + "@swc/core", + "spawn-sync" + ] + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b8ed7a9..546bb2b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,15 +8,21 @@ importers: .: devDependencies: + '@eslint/js': + specifier: ^9.20.0 + version: 9.20.0 '@swc/cli': specifier: ^0.6.0 - version: 0.6.0(@swc/core@1.10.14) + version: 0.6.0(@swc/core@1.10.16) '@swc/core': - specifier: ^1.10.14 - version: 1.10.14 + specifier: ^1.10.16 + version: 1.10.16 '@types/chrome': - specifier: 0.0.301 - version: 0.0.301 + specifier: 0.0.304 + version: 0.0.304 + '@types/eslint-config-prettier': + specifier: ^6.11.3 + version: 6.11.3 '@types/firefox-webext-browser': specifier: 120.0.4 version: 120.0.4 @@ -24,8 +30,8 @@ importers: specifier: 4.0.7 version: 4.0.7 '@types/node': - specifier: ^22.13.1 - version: 22.13.1 + specifier: ^22.13.4 + version: 22.13.4 '@types/tampermonkey': specifier: ^5.0.4 version: 5.0.4 @@ -34,7 +40,7 @@ importers: version: 2.0.7 '@types/webpack': specifier: ^5.28.5 - version: 5.28.5(@swc/core@1.10.14)(webpack-cli@6.0.1) + version: 5.28.5(@swc/core@1.10.16)(webpack-cli@6.0.1) '@violentmonkey/types': specifier: 0.2.0 version: 0.2.0 @@ -46,49 +52,49 @@ importers: version: 9.1.2 copy-webpack-plugin: specifier: ^12.0.2 - version: 12.0.2(webpack@5.97.1) + version: 12.0.2(webpack@5.98.0) crx3: specifier: ^1.1.3 version: 1.1.3 css-loader: specifier: ^7.1.2 - version: 7.1.2(webpack@5.97.1) + version: 7.1.2(webpack@5.98.0) dotenv: specifier: ^16.4.7 version: 16.4.7 eslint: - specifier: ^9.19.0 - version: 9.19.0 + specifier: ^9.20.1 + version: 9.20.1 eslint-config-prettier: specifier: ^10.0.1 - version: 10.0.1(eslint@9.19.0) + version: 10.0.1(eslint@9.20.1) globals: - specifier: ^15.14.0 - version: 15.14.0 + specifier: ^15.15.0 + version: 15.15.0 http-server: specifier: ^14.1.1 version: 14.1.1 mini-css-extract-plugin: specifier: ^2.9.2 - version: 2.9.2(webpack@5.97.1) + version: 2.9.2(webpack@5.98.0) path-browserify: specifier: ^1.0.1 version: 1.0.1 prettier: - specifier: ^3.4.2 - version: 3.4.2 + specifier: ^3.5.1 + version: 3.5.1 sass-embedded: - specifier: ^1.83.4 - version: 1.83.4 + specifier: ^1.85.0 + version: 1.85.0 sass-loader: - specifier: ^16.0.4 - version: 16.0.4(sass-embedded@1.83.4)(webpack@5.97.1) + specifier: ^16.0.5 + version: 16.0.5(sass-embedded@1.85.0)(webpack@5.98.0) swc-loader: specifier: ^0.2.6 - version: 0.2.6(@swc/core@1.10.14)(webpack@5.97.1) + version: 0.2.6(@swc/core@1.10.16)(webpack@5.98.0) terser-webpack-plugin: specifier: ^5.3.11 - version: 5.3.11(@swc/core@1.10.14)(webpack@5.97.1) + version: 5.3.11(@swc/core@1.10.16)(webpack@5.98.0) typescript: specifier: ^5.7.3 version: 5.7.3 @@ -99,11 +105,11 @@ importers: specifier: ^8.4.0 version: 8.4.0 webpack: - specifier: ^5.97.1 - version: 5.97.1(@swc/core@1.10.14)(webpack-cli@6.0.1) + specifier: ^5.98.0 + version: 5.98.0(@swc/core@1.10.16)(webpack-cli@6.0.1) webpack-cli: specifier: ^6.0.1 - version: 6.0.1(webpack@5.97.1) + version: 6.0.1(webpack@5.98.0) webpack-merge: specifier: ^6.0.1 version: 6.0.1 @@ -168,6 +174,10 @@ packages: resolution: {integrity: sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.11.0': + resolution: {integrity: sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@2.1.4': resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -180,8 +190,8 @@ packages: resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/js@9.19.0': - resolution: {integrity: sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==} + '@eslint/js@9.20.0': + resolution: {integrity: sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.5': @@ -299,68 +309,68 @@ packages: chokidar: optional: true - '@swc/core-darwin-arm64@1.10.14': - resolution: {integrity: sha512-Dh4VyrhDDb05tdRmqJ/MucOPMTnrB4pRJol18HVyLlqu1HOT5EzonUniNTCdQbUXjgdv5UVJSTE1lYTzrp+myA==} + '@swc/core-darwin-arm64@1.10.16': + resolution: {integrity: sha512-iikIxwqCQ4Bvz79vJ4ELh26efPf1u5D9TFdmXSJUBs7C3mmMHvk5zyWD9A9cTowXiW6WHs2gE58U1R9HOTTIcg==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.10.14': - resolution: {integrity: sha512-KpzotL/I0O12RE3tF8NmQErINv0cQe/0mnN/Q50ESFzB5kU6bLgp2HMnnwDTm/XEZZRJCNe0oc9WJ5rKbAJFRQ==} + '@swc/core-darwin-x64@1.10.16': + resolution: {integrity: sha512-R2Eb9aktWd62vPfW9H/c/OaQ0e94iURibBo4uzUUcgxNNmB4+wb6piKbHxGdr/5bEsT+vJ1lwZFSRzfb45E7DA==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.10.14': - resolution: {integrity: sha512-20yRXZjMJVz1wp1TcscKiGTVXistG+saIaxOmxSNQia1Qun3hSWLL+u6+5kXbfYGr7R2N6kqSwtZbIfJI25r9Q==} + '@swc/core-linux-arm-gnueabihf@1.10.16': + resolution: {integrity: sha512-mkqN3HBAMnuiSGZ/k2utScuH8rAPshvNj0T1LjBWon+X9DkMNHSA+aMLdWsy0yZKF1zjOPc4L3Uq2l2wzhUlzA==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.10.14': - resolution: {integrity: sha512-Gy7cGrNkiMfPxQyLGxdgXPwyWzNzbHuWycJFcoKBihxZKZIW8hkPBttkGivuLC+0qOgsV2/U+S7tlvAju7FtmQ==} + '@swc/core-linux-arm64-gnu@1.10.16': + resolution: {integrity: sha512-PH/+q/L5nVZJ91CU07CL6Q9Whs6iR6nneMZMAgtVF9Ix8ST0cWVItdUhs6D38kFklCFhaOrpHhS01HlMJ72vWw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.10.14': - resolution: {integrity: sha512-+oYVqJvFw62InZ8PIy1rBACJPC2WTe4vbVb9kM1jJj2D7dKLm9acnnYIVIDsM5Wo7Uab8RvPHXVbs19IBurzuw==} + '@swc/core-linux-arm64-musl@1.10.16': + resolution: {integrity: sha512-1169+C9XbydKKc6Ec1XZxTGKtHjZHDIFn0r+Nqp/QSVwkORrOY1Vz2Hdu7tn/lWMg36ZkGePS+LnnyV67s/7yg==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.10.14': - resolution: {integrity: sha512-OmEbVEKQFLQVHwo4EJl9osmlulURy46k232Opfpn/1ji0t2KcNCci3POsnfMuoZjLkGJv8vGNJdPQxX+CP+wSA==} + '@swc/core-linux-x64-gnu@1.10.16': + resolution: {integrity: sha512-n2rV0XwkjoHn4MDJmpYp5RBrnyi94/6GsJVpbn6f+/eqSrZn3mh3dT7pdZc9zCN1Qp9eDHo+uI6e/wgvbL22uA==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.10.14': - resolution: {integrity: sha512-OZW+Icm8DMPqHbhdxplkuG8qrNnPk5i7xJOZWYi1y5bTjgGFI4nEzrsmmeHKMdQTaWwsFrm3uK1rlyQ48MmXmg==} + '@swc/core-linux-x64-musl@1.10.16': + resolution: {integrity: sha512-EevCpwreBrkPrJjQVIbiM81lK42ukNNSlBmrSRxxbx2V9VGmOd5qxX0cJBn0TRRSLIPi62BuMS76F9iYjqsjgg==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.10.14': - resolution: {integrity: sha512-sTvc+xrDQXy3HXZFtTEClY35Efvuc3D+busYm0+rb1+Thau4HLRY9WP+sOKeGwH9/16rzfzYEqD7Ds8A9ykrHw==} + '@swc/core-win32-arm64-msvc@1.10.16': + resolution: {integrity: sha512-BvE7RWAnKJeELVQWLok6env5I4GUVBTZSvaSN/VPgxnTjF+4PsTeQptYx0xCYhp5QCv68wWYsBnZKuPDS+SBsw==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.10.14': - resolution: {integrity: sha512-j2iQ4y9GWTKtES5eMU0sDsFdYni7IxME7ejFej25Tv3Fq4B+U9tgtYWlJwh1858nIWDXelHiKcSh/UICAyVMdQ==} + '@swc/core-win32-ia32-msvc@1.10.16': + resolution: {integrity: sha512-7Jf/7AeCgbLR/JsQgMJuacHIq4Jeie3knf6+mXxn8aCvRypsOTIEu0eh7j24SolOboxK1ijqJ86GyN1VA2Rebg==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.10.14': - resolution: {integrity: sha512-TYtWkUSMkjs0jGPeWdtWbex4B+DlQZmN/ySVLiPI+EltYCLEXsFMkVFq6aWn48dqFHggFK0UYfvDrJUR2c3Qxg==} + '@swc/core-win32-x64-msvc@1.10.16': + resolution: {integrity: sha512-p0blVm0R8bjaTtmW+FoPmLxLSQdRNbqhuWcR/8g80OzMSkka9mk5/J3kn/5JRVWh+MaR9LHRHZc1Q1L8zan13g==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.10.14': - resolution: {integrity: sha512-WSrnE6JRnH20ZYjOOgSS4aOaPv9gxlkI2KRkN24kagbZnPZMnN8bZZyzw1rrLvwgpuRGv17Uz+hflosbR+SP6w==} + '@swc/core@1.10.16': + resolution: {integrity: sha512-nOINg/OUcZazCW7B55QV2/UB8QAqz9FYe4+z229+4RYboBTZ102K7ebOEjY5sKn59JgAkhjZTz+5BKmXpDFopw==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '*' @@ -381,8 +391,11 @@ packages: '@tokenizer/token@0.3.0': resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - '@types/chrome@0.0.301': - resolution: {integrity: sha512-BljW7InXXOfDYr4nG79y5lnaklrZ0gmeTwCUkuCXK2+69dHnZIrg13KhXJE/HrcFUmy8NG/EK+RTGScsh/Hbiw==} + '@types/chrome@0.0.304': + resolution: {integrity: sha512-ms9CLILU+FEMK7gcmgz/Mtn2E81YQWiMIzCFF8ktp98EVNIIfoqaDTD4+ailOCq1sGjbnEmfJxQ1FAsQtk5M3A==} + + '@types/eslint-config-prettier@6.11.3': + resolution: {integrity: sha512-3wXCiM8croUnhg9LdtZUJQwNcQYGWxxdOWDjPe1ykCqJFPVpzAKfs/2dgSoCtAvdPeaponcWPI7mPcGGp9dkKQ==} '@types/eslint-scope@3.7.7': resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} @@ -420,8 +433,8 @@ packages: '@types/minimatch@3.0.5': resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} - '@types/node@22.13.1': - resolution: {integrity: sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==} + '@types/node@22.13.4': + resolution: {integrity: sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==} '@types/tampermonkey@5.0.4': resolution: {integrity: sha512-HEJ0O5CkDZSwIgd9Zip4xM8o7gZC8zBmJuH1YEXNINIC+aCWEXD10pnpo3NQG5IWHx+Xr4fMSGq1jqeKXH2lpA==} @@ -617,11 +630,6 @@ packages: ajv: optional: true - ajv-keywords@3.5.2: - resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} - peerDependencies: - ajv: ^6.9.1 - ajv-keywords@5.1.0: resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} peerDependencies: @@ -1130,8 +1138,8 @@ packages: deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true - eslint@9.19.0: - resolution: {integrity: sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==} + eslint@9.20.1: + resolution: {integrity: sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -1369,8 +1377,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@15.14.0: - resolution: {integrity: sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==} + globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} globby@14.0.1: @@ -2053,8 +2061,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@3.4.2: - resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} + prettier@3.5.1: + resolution: {integrity: sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==} engines: {node: '>=14'} hasBin: true @@ -2211,133 +2219,133 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sass-embedded-android-arm64@1.83.4: - resolution: {integrity: sha512-tgX4FzmbVqnQmD67ZxQDvI+qFNABrboOQgwsG05E5bA/US42zGajW9AxpECJYiMXVOHmg+d81ICbjb0fsVHskw==} + sass-embedded-android-arm64@1.85.0: + resolution: {integrity: sha512-4itDzRwezwrW8+YzMLIwHtMeH+qrBNdBsRn9lTVI15K+cNLC8z5JWJi6UCZ8TNNZr9LDBfsh5jUdjSub0yF7jg==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [android] - sass-embedded-android-arm@1.83.4: - resolution: {integrity: sha512-9Z4pJAOgEkXa3VDY/o+U6l5XvV0mZTJcSl0l/mSPHihjAHSpLYnOW6+KOWeM8dxqrsqTYcd6COzhanI/a++5Gw==} + sass-embedded-android-arm@1.85.0: + resolution: {integrity: sha512-pPBT7Ad6G8Mlao8ypVNXW2ya7I/Bhcny+RYZ/EmrunEXfhzCNp4PWV2VAweitPO9RnPIJwvUTkLc8Fu6K3nVmw==} engines: {node: '>=14.0.0'} cpu: [arm] os: [android] - sass-embedded-android-ia32@1.83.4: - resolution: {integrity: sha512-RsFOziFqPcfZXdFRULC4Ayzy9aK6R6FwQ411broCjlOBX+b0gurjRadkue3cfUEUR5mmy0KeCbp7zVKPLTK+5Q==} + sass-embedded-android-ia32@1.85.0: + resolution: {integrity: sha512-bwqKq95hzbGbMTeXCMQhH7yEdc2xJVwIXj7rGdD3McvyFWbED6362XRFFPI5YyjfD2wRJd9yWLh/hn+6VyjcYA==} engines: {node: '>=14.0.0'} cpu: [ia32] os: [android] - sass-embedded-android-riscv64@1.83.4: - resolution: {integrity: sha512-EHwh0nmQarBBrMRU928eTZkFGx19k/XW2YwbPR4gBVdWLkbTgCA5aGe8hTE6/1zStyx++3nDGvTZ78+b/VvvLg==} + sass-embedded-android-riscv64@1.85.0: + resolution: {integrity: sha512-Fgkgay+5EePJXZFHR5Vlkutnsmox2V6nX4U3mfGbSN1xjLRm8F5ST72V2s5Z0mnIFpGvEu/v7hfptgViqMvaxg==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [android] - sass-embedded-android-x64@1.83.4: - resolution: {integrity: sha512-0PgQNuPWYy1jEOEPDVsV89KfqOsMLIp9CSbjBY7jRcwRhyVAcigqrUG6bDeNtojHUYKA1kU+Eh/85WxOHUOgBw==} + sass-embedded-android-x64@1.85.0: + resolution: {integrity: sha512-/bG3JgTn3eoIDHCiJNVkLeJgUesat4ghxqYmKMZUJx++4e6iKCDj8XwQTJAgm+QDrsPKXHBacHEANJ9LEAuTqg==} engines: {node: '>=14.0.0'} cpu: [x64] os: [android] - sass-embedded-darwin-arm64@1.83.4: - resolution: {integrity: sha512-rp2ywymWc3nymnSnAFG5R/8hvxWCsuhK3wOnD10IDlmNB7o4rzKby1c+2ZfpQGowlYGWsWWTgz8FW2qzmZsQRw==} + sass-embedded-darwin-arm64@1.85.0: + resolution: {integrity: sha512-plp8TyMz97YFBCB3ndftEvoW29vyfsSBJILM5U84cGzr06SvLh/Npjj8psfUeRw+upEk1zkFtw5u61sRCdgwIw==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [darwin] - sass-embedded-darwin-x64@1.83.4: - resolution: {integrity: sha512-kLkN2lXz9PCgGfDS8Ev5YVcl/V2173L6379en/CaFuJJi7WiyPgBymW7hOmfCt4uO4R1y7CP2Uc08DRtZsBlAA==} + sass-embedded-darwin-x64@1.85.0: + resolution: {integrity: sha512-LP8Zv8DG57Gn6PmSwWzC0gEZUsGdg36Ps3m0i1fVTOelql7N3HZIrlPYRjJvidL8ZlB3ISxNANebTREUHn/wkQ==} engines: {node: '>=14.0.0'} cpu: [x64] os: [darwin] - sass-embedded-linux-arm64@1.83.4: - resolution: {integrity: sha512-E0zjsZX2HgESwyqw31EHtI39DKa7RgK7nvIhIRco1d0QEw227WnoR9pjH3M/ZQy4gQj3GKilOFHM5Krs/omeIA==} + sass-embedded-linux-arm64@1.85.0: + resolution: {integrity: sha512-JRIRKVOY5Y8M1zlUOv9AQGju4P6lj8i5vLJZsVYVN/uY8Cd2dDJZPC8EOhjntp+IpF8AOGIHqCeCkHBceIyIjA==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [linux] - sass-embedded-linux-arm@1.83.4: - resolution: {integrity: sha512-nL90ryxX2lNmFucr9jYUyHHx21AoAgdCL1O5Ltx2rKg2xTdytAGHYo2MT5S0LIeKLa/yKP/hjuSvrbICYNDvtA==} + sass-embedded-linux-arm@1.85.0: + resolution: {integrity: sha512-18xOAEfazJt1MMVS2TRHV94n81VyMnywOoJ7/S7I79qno/zx26OoqqP4XvH107xu8+mZ9Gg54LrUH6ZcgHk08g==} engines: {node: '>=14.0.0'} cpu: [arm] os: [linux] - sass-embedded-linux-ia32@1.83.4: - resolution: {integrity: sha512-ew5HpchSzgAYbQoriRh8QhlWn5Kw2nQ2jHoV9YLwGKe3fwwOWA0KDedssvDv7FWnY/FCqXyymhLd6Bxae4Xquw==} + sass-embedded-linux-ia32@1.85.0: + resolution: {integrity: sha512-4JH+h+gLt9So22nNPQtsKojEsLzjld9ol3zWcOtMGclv+HojZGbCuhJUrLUcK72F8adXYsULmWhJPKROLIwYMA==} engines: {node: '>=14.0.0'} cpu: [ia32] os: [linux] - sass-embedded-linux-musl-arm64@1.83.4: - resolution: {integrity: sha512-IzMgalf6MZOxgp4AVCgsaWAFDP/IVWOrgVXxkyhw29fyAEoSWBJH4k87wyPhEtxSuzVHLxKNbc8k3UzdWmlBFg==} + sass-embedded-linux-musl-arm64@1.85.0: + resolution: {integrity: sha512-aoQjUjK28bvdw9XKTjQeayn8oWQ2QqvoTD11myklGd3IHH7Jj0nwXUstI4NxDueCKt3wghuZoIQkjOheReQxlg==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [linux] - sass-embedded-linux-musl-arm@1.83.4: - resolution: {integrity: sha512-0RrJRwMrmm+gG0VOB5b5Cjs7Sd+lhqpQJa6EJNEaZHljJokEfpE5GejZsGMRMIQLxEvVphZnnxl6sonCGFE/QQ==} + sass-embedded-linux-musl-arm@1.85.0: + resolution: {integrity: sha512-Z1j4ageDVFihqNUBnm89fxY46pY0zD/Clp1D3ZdI7S+D280+AEpbm5vMoH8LLhBQfQLf2w7H++SZGpQwrisudQ==} engines: {node: '>=14.0.0'} cpu: [arm] os: [linux] - sass-embedded-linux-musl-ia32@1.83.4: - resolution: {integrity: sha512-LLb4lYbcxPzX4UaJymYXC+WwokxUlfTJEFUv5VF0OTuSsHAGNRs/rslPtzVBTvMeG9TtlOQDhku1F7G6iaDotA==} + sass-embedded-linux-musl-ia32@1.85.0: + resolution: {integrity: sha512-/cJCSXOfXmQFH8deE+3U9x+BSz8i0d1Tt9gKV/Gat1Xm43Oumw8pmZgno+cDuGjYQInr9ryW5121pTMlj/PBXQ==} engines: {node: '>=14.0.0'} cpu: [ia32] os: [linux] - sass-embedded-linux-musl-riscv64@1.83.4: - resolution: {integrity: sha512-zoKlPzD5Z13HKin1UGR74QkEy+kZEk2AkGX5RelRG494mi+IWwRuWCppXIovor9+BQb9eDWPYPoMVahwN5F7VA==} + sass-embedded-linux-musl-riscv64@1.85.0: + resolution: {integrity: sha512-l+FJxMXkmg42RZq5RFKXg4InX0IA7yEiPHe4kVSdrczP7z3NLxk+W9wVkPnoRKYIMe1qZPPQ25y0TgI4HNWouA==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [linux] - sass-embedded-linux-musl-x64@1.83.4: - resolution: {integrity: sha512-hB8+/PYhfEf2zTIcidO5Bpof9trK6WJjZ4T8g2MrxQh8REVtdPcgIkoxczRynqybf9+fbqbUwzXtiUao2GV+vQ==} + sass-embedded-linux-musl-x64@1.85.0: + resolution: {integrity: sha512-M9ffjcYfFcRvkFA6V3DpOS955AyvmpvPAhL/xNK45d/ma1n1ehTWpd24tVeKiNK5CZkNjjMEfyw2fHa6MpqmEA==} engines: {node: '>=14.0.0'} cpu: [x64] os: [linux] - sass-embedded-linux-riscv64@1.83.4: - resolution: {integrity: sha512-83fL4n+oeDJ0Y4KjASmZ9jHS1Vl9ESVQYHMhJE0i4xDi/P3BNarm2rsKljq/QtrwGpbqwn8ujzOu7DsNCMDSHA==} + sass-embedded-linux-riscv64@1.85.0: + resolution: {integrity: sha512-yqPXQWfM+qiIPkfn++48GOlbmSvUZIyL9nwFstBk0k4x40UhbhilfknqeTUpxoHfQzylTGVhrm5JE7MjM+LNZA==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [linux] - sass-embedded-linux-x64@1.83.4: - resolution: {integrity: sha512-NlnGdvCmTD5PK+LKXlK3sAuxOgbRIEoZfnHvxd157imCm/s2SYF/R28D0DAAjEViyI8DovIWghgbcqwuertXsA==} + sass-embedded-linux-x64@1.85.0: + resolution: {integrity: sha512-NTDeQFZcuVR7COoaRy8pZD6/+QznwBR8kVFsj7NpmvX9aJ7TX/q+OQZHX7Bfb3tsfKXhf1YZozegPuYxRnMKAQ==} engines: {node: '>=14.0.0'} cpu: [x64] os: [linux] - sass-embedded-win32-arm64@1.83.4: - resolution: {integrity: sha512-J2BFKrEaeSrVazU2qTjyQdAk+MvbzJeTuCET0uAJEXSKtvQ3AzxvzndS7LqkDPbF32eXAHLw8GVpwcBwKbB3Uw==} + sass-embedded-win32-arm64@1.85.0: + resolution: {integrity: sha512-gO0VAuxC4AdV+uZYJESRWVVHQWCGzNs0C3OKCAdH4r1vGRugooMi7J/5wbwUdXDA1MV9ICfhlKsph2n3GiPdqA==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [win32] - sass-embedded-win32-ia32@1.83.4: - resolution: {integrity: sha512-uPAe9T/5sANFhJS5dcfAOhOJy8/l2TRYG4r+UO3Wp4yhqbN7bggPvY9c7zMYS0OC8tU/bCvfYUDFHYMCl91FgA==} + sass-embedded-win32-ia32@1.85.0: + resolution: {integrity: sha512-PCyn6xeFIBUgBceNypuf73/5DWF2VWPlPqPuBprPsTvpZOMUJeBtP+Lf4mnu3dNy1z76mYVnpaCnQmzZ0zHZaA==} engines: {node: '>=14.0.0'} cpu: [ia32] os: [win32] - sass-embedded-win32-x64@1.83.4: - resolution: {integrity: sha512-C9fkDY0jKITdJFij4UbfPFswxoXN9O/Dr79v17fJnstVwtUojzVJWKHUXvF0Zg2LIR7TCc4ju3adejKFxj7ueA==} + sass-embedded-win32-x64@1.85.0: + resolution: {integrity: sha512-AknE2jLp6OBwrR5hQ8pDsG94KhJCeSheFJ2xgbnk8RUjZX909JiNbgh2sNt9LG+RXf4xZa55dDL537gZoCx/iw==} engines: {node: '>=14.0.0'} cpu: [x64] os: [win32] - sass-embedded@1.83.4: - resolution: {integrity: sha512-Hf2burRA/y5PGxsg6jB9UpoK/xZ6g/pgrkOcdl6j+rRg1Zj8XhGKZ1MTysZGtTPUUmiiErqzkP5+Kzp95yv9GQ==} + sass-embedded@1.85.0: + resolution: {integrity: sha512-x3Vv54g0jv1aPSW8OTA/0GzQCs/HMQOjIkLtZJ3Xsn/I4vnyjKbVTQmFTax9bQjldqLEEkdbvy6ES/cOOnYNwA==} engines: {node: '>=16.0.0'} hasBin: true - sass-loader@16.0.4: - resolution: {integrity: sha512-LavLbgbBGUt3wCiYzhuLLu65+fWXaXLmq7YxivLhEqmiupCFZ5sKUAipK3do6V80YSU0jvSxNhEdT13IXNr3rg==} + sass-loader@16.0.5: + resolution: {integrity: sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==} engines: {node: '>= 18.12.0'} peerDependencies: '@rspack/core': 0.x || 1.x @@ -2360,10 +2368,6 @@ packages: sax@1.2.4: resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} - schema-utils@3.3.0: - resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} - engines: {node: '>= 10.13.0'} - schema-utils@4.2.0: resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==} engines: {node: '>= 12.13.0'} @@ -2751,8 +2755,8 @@ packages: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} - webpack@5.97.1: - resolution: {integrity: sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==} + webpack@5.98.0: + resolution: {integrity: sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -2904,9 +2908,9 @@ snapshots: eslint: 8.57.1 eslint-visitor-keys: 3.4.3 - '@eslint-community/eslint-utils@4.4.0(eslint@9.19.0)': + '@eslint-community/eslint-utils@4.4.0(eslint@9.20.1)': dependencies: - eslint: 9.19.0 + eslint: 9.20.1 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -2923,6 +2927,10 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 + '@eslint/core@0.11.0': + dependencies: + '@types/json-schema': 7.0.15 + '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 @@ -2953,7 +2961,7 @@ snapshots: '@eslint/js@8.57.1': {} - '@eslint/js@9.19.0': {} + '@eslint/js@9.20.0': {} '@eslint/object-schema@2.1.5': {} @@ -3043,9 +3051,9 @@ snapshots: '@sindresorhus/merge-streams@2.3.0': {} - '@swc/cli@0.6.0(@swc/core@1.10.14)': + '@swc/cli@0.6.0(@swc/core@1.10.16)': dependencies: - '@swc/core': 1.10.14 + '@swc/core': 1.10.16 '@swc/counter': 0.1.3 '@xhmikosr/bin-wrapper': 13.0.5 commander: 8.3.0 @@ -3056,51 +3064,51 @@ snapshots: slash: 3.0.0 source-map: 0.7.4 - '@swc/core-darwin-arm64@1.10.14': + '@swc/core-darwin-arm64@1.10.16': optional: true - '@swc/core-darwin-x64@1.10.14': + '@swc/core-darwin-x64@1.10.16': optional: true - '@swc/core-linux-arm-gnueabihf@1.10.14': + '@swc/core-linux-arm-gnueabihf@1.10.16': optional: true - '@swc/core-linux-arm64-gnu@1.10.14': + '@swc/core-linux-arm64-gnu@1.10.16': optional: true - '@swc/core-linux-arm64-musl@1.10.14': + '@swc/core-linux-arm64-musl@1.10.16': optional: true - '@swc/core-linux-x64-gnu@1.10.14': + '@swc/core-linux-x64-gnu@1.10.16': optional: true - '@swc/core-linux-x64-musl@1.10.14': + '@swc/core-linux-x64-musl@1.10.16': optional: true - '@swc/core-win32-arm64-msvc@1.10.14': + '@swc/core-win32-arm64-msvc@1.10.16': optional: true - '@swc/core-win32-ia32-msvc@1.10.14': + '@swc/core-win32-ia32-msvc@1.10.16': optional: true - '@swc/core-win32-x64-msvc@1.10.14': + '@swc/core-win32-x64-msvc@1.10.16': optional: true - '@swc/core@1.10.14': + '@swc/core@1.10.16': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.17 optionalDependencies: - '@swc/core-darwin-arm64': 1.10.14 - '@swc/core-darwin-x64': 1.10.14 - '@swc/core-linux-arm-gnueabihf': 1.10.14 - '@swc/core-linux-arm64-gnu': 1.10.14 - '@swc/core-linux-arm64-musl': 1.10.14 - '@swc/core-linux-x64-gnu': 1.10.14 - '@swc/core-linux-x64-musl': 1.10.14 - '@swc/core-win32-arm64-msvc': 1.10.14 - '@swc/core-win32-ia32-msvc': 1.10.14 - '@swc/core-win32-x64-msvc': 1.10.14 + '@swc/core-darwin-arm64': 1.10.16 + '@swc/core-darwin-x64': 1.10.16 + '@swc/core-linux-arm-gnueabihf': 1.10.16 + '@swc/core-linux-arm64-gnu': 1.10.16 + '@swc/core-linux-arm64-musl': 1.10.16 + '@swc/core-linux-x64-gnu': 1.10.16 + '@swc/core-linux-x64-musl': 1.10.16 + '@swc/core-win32-arm64-msvc': 1.10.16 + '@swc/core-win32-ia32-msvc': 1.10.16 + '@swc/core-win32-x64-msvc': 1.10.16 '@swc/counter@0.1.3': {} @@ -3114,11 +3122,13 @@ snapshots: '@tokenizer/token@0.3.0': {} - '@types/chrome@0.0.301': + '@types/chrome@0.0.304': dependencies: '@types/filesystem': 0.0.32 '@types/har-format': 1.2.10 + '@types/eslint-config-prettier@6.11.3': {} + '@types/eslint-scope@3.7.7': dependencies: '@types/eslint': 9.6.1 @@ -3151,7 +3161,7 @@ snapshots: '@types/minimatch@3.0.5': {} - '@types/node@22.13.1': + '@types/node@22.13.4': dependencies: undici-types: 6.20.0 @@ -3159,11 +3169,11 @@ snapshots: '@types/trusted-types@2.0.7': {} - '@types/webpack@5.28.5(@swc/core@1.10.14)(webpack-cli@6.0.1)': + '@types/webpack@5.28.5(@swc/core@1.10.16)(webpack-cli@6.0.1)': dependencies: - '@types/node': 22.13.1 + '@types/node': 22.13.4 tapable: 2.2.1 - webpack: 5.97.1(@swc/core@1.10.14)(webpack-cli@6.0.1) + webpack: 5.98.0(@swc/core@1.10.16)(webpack-cli@6.0.1) transitivePeerDependencies: - '@swc/core' - esbuild @@ -3172,7 +3182,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.13.1 + '@types/node': 22.13.4 '@ungap/structured-clone@1.2.0': {} @@ -3254,20 +3264,20 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1)(webpack@5.97.1)': + '@webpack-cli/configtest@3.0.1(webpack-cli@6.0.1)(webpack@5.98.0)': dependencies: - webpack: 5.97.1(@swc/core@1.10.14)(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack@5.97.1) + webpack: 5.98.0(@swc/core@1.10.16)(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack@5.98.0) - '@webpack-cli/info@3.0.1(webpack-cli@6.0.1)(webpack@5.97.1)': + '@webpack-cli/info@3.0.1(webpack-cli@6.0.1)(webpack@5.98.0)': dependencies: - webpack: 5.97.1(@swc/core@1.10.14)(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack@5.97.1) + webpack: 5.98.0(@swc/core@1.10.16)(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack@5.98.0) - '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1)(webpack@5.97.1)': + '@webpack-cli/serve@3.0.1(webpack-cli@6.0.1)(webpack@5.98.0)': dependencies: - webpack: 5.97.1(@swc/core@1.10.14)(webpack-cli@6.0.1) - webpack-cli: 6.0.1(webpack@5.97.1) + webpack: 5.98.0(@swc/core@1.10.16)(webpack-cli@6.0.1) + webpack-cli: 6.0.1(webpack@5.98.0) '@xhmikosr/archive-type@7.0.0': dependencies: @@ -3414,10 +3424,6 @@ snapshots: optionalDependencies: ajv: 8.17.1 - ajv-keywords@3.5.2(ajv@6.12.6): - dependencies: - ajv: 6.12.6 - ajv-keywords@5.1.0(ajv@8.12.0): dependencies: ajv: 8.12.0 @@ -3630,7 +3636,7 @@ snapshots: chrome-launcher@1.1.2: dependencies: - '@types/node': 22.13.1 + '@types/node': 22.13.4 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 2.0.1 @@ -3727,7 +3733,7 @@ snapshots: dependencies: safe-buffer: 5.2.1 - copy-webpack-plugin@12.0.2(webpack@5.97.1): + copy-webpack-plugin@12.0.2(webpack@5.98.0): dependencies: fast-glob: 3.3.2 glob-parent: 6.0.2 @@ -3735,7 +3741,7 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.2.0 serialize-javascript: 6.0.2 - webpack: 5.97.1(@swc/core@1.10.14)(webpack-cli@6.0.1) + webpack: 5.98.0(@swc/core@1.10.16)(webpack-cli@6.0.1) core-util-is@1.0.3: {} @@ -3759,7 +3765,7 @@ snapshots: pbf: 3.2.1 yazl: 2.5.1 - css-loader@7.1.2(webpack@5.97.1): + css-loader@7.1.2(webpack@5.98.0): dependencies: icss-utils: 5.1.0(postcss@8.4.35) postcss: 8.4.35 @@ -3770,7 +3776,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.5.4 optionalDependencies: - webpack: 5.97.1(@swc/core@1.10.14)(webpack-cli@6.0.1) + webpack: 5.98.0(@swc/core@1.10.16)(webpack-cli@6.0.1) css-select@5.1.0: dependencies: @@ -3891,9 +3897,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.0.1(eslint@9.19.0): + eslint-config-prettier@10.0.1(eslint@9.20.1): dependencies: - eslint: 9.19.0 + eslint: 9.20.1 eslint-plugin-no-unsanitized@4.1.2(eslint@8.57.1): dependencies: @@ -3961,14 +3967,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint@9.19.0: + eslint@9.20.1: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.19.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.20.1) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.19.1 - '@eslint/core': 0.10.0 + '@eslint/core': 0.11.0 '@eslint/eslintrc': 3.2.0 - '@eslint/js': 9.19.0 + '@eslint/js': 9.20.0 '@eslint/plugin-kit': 0.2.5 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 @@ -4231,7 +4237,7 @@ snapshots: globals@14.0.0: {} - globals@15.14.0: {} + globals@15.15.0: {} globby@14.0.1: dependencies: @@ -4456,7 +4462,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.13.1 + '@types/node': 22.13.4 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -4580,11 +4586,11 @@ snapshots: mimic-response@4.0.0: {} - mini-css-extract-plugin@2.9.2(webpack@5.97.1): + mini-css-extract-plugin@2.9.2(webpack@5.98.0): dependencies: schema-utils: 4.2.0 tapable: 2.2.1 - webpack: 5.97.1(@swc/core@1.10.14)(webpack-cli@6.0.1) + webpack: 5.98.0(@swc/core@1.10.16)(webpack-cli@6.0.1) minimatch@3.1.2: dependencies: @@ -4868,7 +4874,7 @@ snapshots: prelude-ls@1.2.1: {} - prettier@3.4.2: {} + prettier@3.5.1: {} process-nextick-args@2.0.1: {} @@ -5008,67 +5014,67 @@ snapshots: safer-buffer@2.1.2: {} - sass-embedded-android-arm64@1.83.4: + sass-embedded-android-arm64@1.85.0: optional: true - sass-embedded-android-arm@1.83.4: + sass-embedded-android-arm@1.85.0: optional: true - sass-embedded-android-ia32@1.83.4: + sass-embedded-android-ia32@1.85.0: optional: true - sass-embedded-android-riscv64@1.83.4: + sass-embedded-android-riscv64@1.85.0: optional: true - sass-embedded-android-x64@1.83.4: + sass-embedded-android-x64@1.85.0: optional: true - sass-embedded-darwin-arm64@1.83.4: + sass-embedded-darwin-arm64@1.85.0: optional: true - sass-embedded-darwin-x64@1.83.4: + sass-embedded-darwin-x64@1.85.0: optional: true - sass-embedded-linux-arm64@1.83.4: + sass-embedded-linux-arm64@1.85.0: optional: true - sass-embedded-linux-arm@1.83.4: + sass-embedded-linux-arm@1.85.0: optional: true - sass-embedded-linux-ia32@1.83.4: + sass-embedded-linux-ia32@1.85.0: optional: true - sass-embedded-linux-musl-arm64@1.83.4: + sass-embedded-linux-musl-arm64@1.85.0: optional: true - sass-embedded-linux-musl-arm@1.83.4: + sass-embedded-linux-musl-arm@1.85.0: optional: true - sass-embedded-linux-musl-ia32@1.83.4: + sass-embedded-linux-musl-ia32@1.85.0: optional: true - sass-embedded-linux-musl-riscv64@1.83.4: + sass-embedded-linux-musl-riscv64@1.85.0: optional: true - sass-embedded-linux-musl-x64@1.83.4: + sass-embedded-linux-musl-x64@1.85.0: optional: true - sass-embedded-linux-riscv64@1.83.4: + sass-embedded-linux-riscv64@1.85.0: optional: true - sass-embedded-linux-x64@1.83.4: + sass-embedded-linux-x64@1.85.0: optional: true - sass-embedded-win32-arm64@1.83.4: + sass-embedded-win32-arm64@1.85.0: optional: true - sass-embedded-win32-ia32@1.83.4: + sass-embedded-win32-ia32@1.85.0: optional: true - sass-embedded-win32-x64@1.83.4: + sass-embedded-win32-x64@1.85.0: optional: true - sass-embedded@1.83.4: + sass-embedded@1.85.0: dependencies: '@bufbuild/protobuf': 2.2.0 buffer-builder: 0.2.0 @@ -5079,42 +5085,36 @@ snapshots: sync-child-process: 1.0.2 varint: 6.0.0 optionalDependencies: - sass-embedded-android-arm: 1.83.4 - sass-embedded-android-arm64: 1.83.4 - sass-embedded-android-ia32: 1.83.4 - sass-embedded-android-riscv64: 1.83.4 - sass-embedded-android-x64: 1.83.4 - sass-embedded-darwin-arm64: 1.83.4 - sass-embedded-darwin-x64: 1.83.4 - sass-embedded-linux-arm: 1.83.4 - sass-embedded-linux-arm64: 1.83.4 - sass-embedded-linux-ia32: 1.83.4 - sass-embedded-linux-musl-arm: 1.83.4 - sass-embedded-linux-musl-arm64: 1.83.4 - sass-embedded-linux-musl-ia32: 1.83.4 - sass-embedded-linux-musl-riscv64: 1.83.4 - sass-embedded-linux-musl-x64: 1.83.4 - sass-embedded-linux-riscv64: 1.83.4 - sass-embedded-linux-x64: 1.83.4 - sass-embedded-win32-arm64: 1.83.4 - sass-embedded-win32-ia32: 1.83.4 - sass-embedded-win32-x64: 1.83.4 - - sass-loader@16.0.4(sass-embedded@1.83.4)(webpack@5.97.1): + sass-embedded-android-arm: 1.85.0 + sass-embedded-android-arm64: 1.85.0 + sass-embedded-android-ia32: 1.85.0 + sass-embedded-android-riscv64: 1.85.0 + sass-embedded-android-x64: 1.85.0 + sass-embedded-darwin-arm64: 1.85.0 + sass-embedded-darwin-x64: 1.85.0 + sass-embedded-linux-arm: 1.85.0 + sass-embedded-linux-arm64: 1.85.0 + sass-embedded-linux-ia32: 1.85.0 + sass-embedded-linux-musl-arm: 1.85.0 + sass-embedded-linux-musl-arm64: 1.85.0 + sass-embedded-linux-musl-ia32: 1.85.0 + sass-embedded-linux-musl-riscv64: 1.85.0 + sass-embedded-linux-musl-x64: 1.85.0 + sass-embedded-linux-riscv64: 1.85.0 + sass-embedded-linux-x64: 1.85.0 + sass-embedded-win32-arm64: 1.85.0 + sass-embedded-win32-ia32: 1.85.0 + sass-embedded-win32-x64: 1.85.0 + + sass-loader@16.0.5(sass-embedded@1.85.0)(webpack@5.98.0): dependencies: neo-async: 2.6.2 optionalDependencies: - sass-embedded: 1.83.4 - webpack: 5.97.1(@swc/core@1.10.14)(webpack-cli@6.0.1) + sass-embedded: 1.85.0 + webpack: 5.98.0(@swc/core@1.10.16)(webpack-cli@6.0.1) sax@1.2.4: {} - schema-utils@3.3.0: - dependencies: - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - ajv-keywords: 3.5.2(ajv@6.12.6) - schema-utils@4.2.0: dependencies: '@types/json-schema': 7.0.11 @@ -5298,11 +5298,11 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - swc-loader@0.2.6(@swc/core@1.10.14)(webpack@5.97.1): + swc-loader@0.2.6(@swc/core@1.10.16)(webpack@5.98.0): dependencies: - '@swc/core': 1.10.14 + '@swc/core': 1.10.16 '@swc/counter': 0.1.3 - webpack: 5.97.1(@swc/core@1.10.14)(webpack-cli@6.0.1) + webpack: 5.98.0(@swc/core@1.10.16)(webpack-cli@6.0.1) sync-child-process@1.0.2: dependencies: @@ -5318,16 +5318,16 @@ snapshots: fast-fifo: 1.3.2 streamx: 2.21.1 - terser-webpack-plugin@5.3.11(@swc/core@1.10.14)(webpack@5.97.1): + terser-webpack-plugin@5.3.11(@swc/core@1.10.16)(webpack@5.98.0): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 4.3.0 serialize-javascript: 6.0.2 terser: 5.37.0 - webpack: 5.97.1(@swc/core@1.10.14)(webpack-cli@6.0.1) + webpack: 5.98.0(@swc/core@1.10.16)(webpack-cli@6.0.1) optionalDependencies: - '@swc/core': 1.10.14 + '@swc/core': 1.10.16 terser@5.37.0: dependencies: @@ -5483,12 +5483,12 @@ snapshots: - supports-color - utf-8-validate - webpack-cli@6.0.1(webpack@5.97.1): + webpack-cli@6.0.1(webpack@5.98.0): dependencies: '@discoveryjs/json-ext': 0.6.3 - '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1)(webpack@5.97.1) - '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1)(webpack@5.97.1) - '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1)(webpack@5.97.1) + '@webpack-cli/configtest': 3.0.1(webpack-cli@6.0.1)(webpack@5.98.0) + '@webpack-cli/info': 3.0.1(webpack-cli@6.0.1)(webpack@5.98.0) + '@webpack-cli/serve': 3.0.1(webpack-cli@6.0.1)(webpack@5.98.0) colorette: 2.0.19 commander: 12.1.0 cross-spawn: 7.0.3 @@ -5497,7 +5497,7 @@ snapshots: import-local: 3.1.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.97.1(@swc/core@1.10.14)(webpack-cli@6.0.1) + webpack: 5.98.0(@swc/core@1.10.16)(webpack-cli@6.0.1) webpack-merge: 6.0.1 webpack-merge@6.0.1: @@ -5508,7 +5508,7 @@ snapshots: webpack-sources@3.2.3: {} - webpack@5.97.1(@swc/core@1.10.14)(webpack-cli@6.0.1): + webpack@5.98.0(@swc/core@1.10.16)(webpack-cli@6.0.1): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.6 @@ -5528,13 +5528,13 @@ snapshots: loader-runner: 4.3.0 mime-types: 2.1.35 neo-async: 2.6.2 - schema-utils: 3.3.0 + schema-utils: 4.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.11(@swc/core@1.10.14)(webpack@5.97.1) + terser-webpack-plugin: 5.3.11(@swc/core@1.10.16)(webpack@5.98.0) watchpack: 2.4.2 webpack-sources: 3.2.3 optionalDependencies: - webpack-cli: 6.0.1(webpack@5.97.1) + webpack-cli: 6.0.1(webpack@5.98.0) transitivePeerDependencies: - '@swc/core' - esbuild diff --git a/src/UserJS/header.js b/src/UserJS/header.js index 1df7454..9b48860 100644 --- a/src/UserJS/header.js +++ b/src/UserJS/header.js @@ -29,6 +29,15 @@ if ( if (!(typeof userjs === 'object' && userjs.UserJS)) { return; } +const createPolicy = () => { + // Native implementation exists + if (window.trustedTypes && window.trustedTypes.createPolicy) { + window.trustedTypes.createPolicy('default', { + createHTML: (string) => string + }); + } +}; +createPolicy(); /** * Uncompressed locales + compiler * @@ -45,4 +54,4 @@ const translations = [[languageList]]; const main_css = `[[mainCSS]]`; /******************************************************************************/ [[code]] -})(); \ No newline at end of file +})(); diff --git a/src/UserJS/main.js b/src/UserJS/main.js index ffb8ca4..01bd3e7 100644 --- a/src/UserJS/main.js +++ b/src/UserJS/main.js @@ -119,29 +119,6 @@ function safeSelf() { return userjs.safeSelf; } -const trustedTypes = { - policy: false, - init() { - if (this.policy) { - return this.policy; - } - this.policy = true; - try { - // Native implementation exists - if (window.trustedTypes && window.trustedTypes.createPolicy) { - window.trustedTypes.createPolicy('default', { - createHTML: (string) => string - }); - } - } catch (ex) { - ex.cause = 'trustedTypes.init()'; - err(ex); - } - return this.policy; - } -}; -trustedTypes.init(); - const BLANK_PAGE = 'about:blank'; // Lets highlight me :) const authorID = 166061; @@ -149,6 +126,7 @@ const authorID = 166061; * Some UserJS I personally enjoy - `https://greasyfork.org/scripts/{{id}}` */ const goodUserJS = [ + 33005, 394820, 438684, 4870, @@ -180,11 +158,9 @@ const goodUserJS = [ 'https://github.com/jesus2099/konami-command/raw/master/INSTALL-USER-SCRIPT.user.js', 'https://github.com/TagoDR/MangaOnlineViewer/raw/master/dist/Manga_OnlineViewer_Adult.user.js' ]; -/** - * Remove UserJS from banned accounts - */ +/** Remove UserJS from banned accounts */ const badUserJS = [478597]; -// Unsupport webpages for each engine +/** Unsupport host for search engines */ const engineUnsupported = { greasyfork: ['pornhub.com'], sleazyfork: ['pornhub.com'], @@ -226,12 +202,15 @@ const builtinList = { pathname: '/hentai/.+/read/page/.+' } }; +// #region DEFAULT_CONFIG /** * @type { import("../typings/types.d.ts").config } */ const DEFAULT_CONFIG = { autofetch: true, autoinject: true, + autoSort: 'daily_installs', + clearTabCache: true, cache: true, codePreview: false, autoexpand: false, @@ -326,48 +305,46 @@ const DEFAULT_CONFIG = { } } }; -//#region i18n +// #endregion +// #region i18n class i18nHandler { constructor() { - /** @type { string[] } */ - this.cache = []; - - const { navigator } = safeSelf(); - const { languages } = navigator; - for (const nlang of languages) { - const lg = nlang.split('-')[0]; - if (this.cache.indexOf(lg) === -1) { - this.cache.push(lg); - } + if (userjs.pool !== undefined) { + return userjs.pool; } - - const current = navigator.language.split('-')[0] ?? 'en'; - if (!this.cache.includes(current)) { - this.cache.push(current); + userjs.pool = new Map(); + for (const [k, v] of Object.entries(translations)) { + if (!userjs.pool.has(k)) userjs.pool.set(k, v); } } + /** + * @param {string | Date | number} str + */ toDate(str = '') { const { navigator } = safeSelf(); - return new Intl.DateTimeFormat(navigator.language).format(new Date(str)); + return new Intl.DateTimeFormat(navigator.language).format( + typeof str === 'string' ? new Date(str) : str + ); } + /** + * @param {number | bigint} number + */ toNumber(number) { const { navigator } = safeSelf(); return new Intl.NumberFormat(navigator.language).format(number); } - i18n$(...keys) { + /** + * @type { import("../typings/UserJS.d.ts").i18n$ } + */ + i18n$(key) { const { navigator } = safeSelf(); const current = navigator.language.split('-')[0] ?? 'en'; - const list = translations[cfg.language] ?? translations[current]; - const arr = []; - for (const key of keys) { - arr.push(list[key]); - } - return arr.length !== 1 ? arr : arr[0]; + return userjs.pool.get(current)?.[key] ?? 'Unknown'; } } const language = new i18nHandler(); const { i18n$ } = language; -//#endregion +// #endregion // #region Utilities const union = (...arr) => [...new Set(arr.flat())]; /** @@ -396,20 +373,6 @@ const qsA = (selectors, root) => { * @type { import("../typings/types.d.ts").objToStr } */ const objToStr = (obj) => Object.prototype.toString.call(obj); -/** - * @type { import("../typings/types.d.ts").strToURL } - */ -const strToURL = (str) => { - const WIN_LOCATION = window.location ?? BLANK_PAGE; - try { - str = str ?? WIN_LOCATION; - return objToStr(str).includes('URL') ? str : new URL(str); - } catch (ex) { - ex.cause = 'strToURL'; - err(ex); - } - return WIN_LOCATION; -}; /** * @type { import("../typings/types.d.ts").isRegExp } */ @@ -495,6 +458,7 @@ const ael = (el, type, listener, options = {}) => { elem.addEventListener(type, listener, options); } } catch (ex) { + ex.cause = 'ael'; err(ex); } }; @@ -610,26 +574,12 @@ const dom = { }, cl: { add(target, token) { - if (Array.isArray(token)) { - for (const elem of normalizeTarget(target)) { - elem.classList.add(...token); - } - } else { - for (const elem of normalizeTarget(target)) { - elem.classList.add(token); - } - } + token = Array.isArray(token) ? token : [token]; + return normalizeTarget(target).some((elem) => elem.classList.add(...token)); }, remove(target, token) { - if (Array.isArray(token)) { - for (const elem of normalizeTarget(target)) { - elem.classList.remove(...token); - } - } else { - for (const elem of normalizeTarget(target)) { - elem.classList.remove(token); - } - } + token = Array.isArray(token) ? token : [token]; + return normalizeTarget(target).some((elem) => elem.classList.remove(...token)); }, toggle(target, token, force) { let r; @@ -639,12 +589,7 @@ const dom = { return r; }, has(target, token) { - for (const elem of normalizeTarget(target)) { - if (elem.classList.contains(token)) { - return true; - } - } - return false; + return normalizeTarget(target).some((elem) => elem.classList.contains(token)); } } }; @@ -761,6 +706,7 @@ const iconSVG = { try { if (typeof iconSVG[type].html === 'string') { svgElem.innerHTML = iconSVG[type].html; + dom.attr(svgElem, 'id', `mujs_${type ?? 'Unknown'}`); } // eslint-disable-next-line no-unused-vars } catch (ex) { @@ -779,6 +725,7 @@ const iconSVG = { */ const StorageSystem = { prefix: 'MUJS', + events: new Set(), getItem(key) { return window.localStorage.getItem(key); }, @@ -791,8 +738,47 @@ const StorageSystem = { remove(key) { window.localStorage.removeItem(key); }, + addListener(name, callback) { + if (isGM) { + let GMType; + if (isFN(GM.addValueChangeListener)) { + GMType = GM.addValueChangeListener(name, callback); + } else if (isFN(GM_addValueChangeListener)) { + GMType = GM_addValueChangeListener(name, callback); + } + if (GMType) { + return this.events.add(GMType) && GMType; + } + } + return ( + this.events.add(callback) && + window.addEventListener('storage', (evt) => { + const { key, oldValue, newValue } = evt; + if (key === name) callback(key, oldValue, newValue, false); + }) + ); + }, + attach() { + window.addEventListener('beforeunload', () => { + for (const e of this.events) { + if (isGM && typeof e === 'number' && !Number.isNaN(e)) { + if (isFN(GM.removeValueChangeListener)) { + GM.removeValueChangeListener(e); + } else if (isFN(GM_addValueChangeListener)) { + GM_removeValueChangeListener(e); + } + } else { + window.removeEventListener('storage', e); + } + this.events.delete(e); + } + }); + }, async setValue(key, v) { - v = typeof v === 'string' ? v : JSON.stringify(v ?? {}); + if (!v) { + return; + } + v = typeof v === 'string' ? v : JSON.stringify(v); if (isGM) { if (isFN(GM.setValue)) { await GM.setValue(key, v); @@ -861,9 +847,6 @@ const Network = { method, ...data }; - if (params.hermes) { - delete params.hermes; - } if (isGM && !useFetch) { if (params.credentials) { Object.assign(params, { @@ -914,8 +897,8 @@ const Network = { } else if (responseType.match(/clone/)) { resolve(check('clone')); } else if (responseType.match(/document/)) { - const domParser = new DOMParser(); const respTxt = check('text'); + const domParser = new DOMParser(); if (respTxt instanceof Promise) { respTxt.then((txt) => { const doc = domParser.parseFromString(txt, 'text/html'); @@ -1011,33 +994,45 @@ const Network = { return txt.replaceAll(/\W/g, ''); } }; -const sleazyRedirect = () => { - const locObj = window.top.location; - const { hostname } = locObj; - const gfSite = /greasyfork\.org/.test(hostname); - if (!gfSite && cfg.sleazyredirect) { - return; - } - const otherSite = gfSite ? 'sleazyfork' : 'greasyfork'; - if (!qs('span.sign-in-link')) { - return; - } - if (!/scripts\/\d+/.test(locObj.href)) { - return; - } - if ( - !qs('#script-info') && - (otherSite == 'greasyfork' || qs('div.width-constraint>section>p>a')) - ) { - const str = locObj.href.replace( - /\/\/([^.]+\.)?(greasyfork|sleazyfork)\.org/, - '//$1' + otherSite + '.org' - ); - info(`Redirecting to "${str}"`); - if (isFN(locObj.assign)) { - locObj.assign(str); - } else { - locObj.href = str; +const Counter = { + cnt: { + total: { + count: 0 + } + }, + set(engine) { + if (!this.cnt[engine.name]) { + const counter = make('count-frame', engine.enabled ? '' : 'hidden', { + dataset: { + counter: engine.name + }, + title: engine.query ? decodeURIComponent(engine.query) : engine.url, + textContent: '0' + }); + this.cnt[engine.name] = { + root: counter, + count: 0 + }; + return counter; + } + return this.cnt[engine.name].root; + }, + update(count, engine) { + this.cnt[engine.name].count += count; + this.cnt.total.count += count; + this.updateAll(); + }, + updateAll() { + for (const v of Object.values(this.cnt)) dom.text(v.root, v.count); + }, + reset() { + for (const [k, v] of Object.entries(this.cnt)) { + dom.text(v.root, 0); + v.count = 0; + const engine = cfg.engines.find((engine) => k === engine.name); + if (engine) { + dom.cl[engine.enabled ? 'remove' : 'add'](v.root, 'hidden'); + } } } }; @@ -1060,17 +1055,16 @@ class Container { unsaved; isBlacklisted; rebuild; - counters; opacityMin; opacityMax; constructor(url) { this.remove = this.remove.bind(this); this.refresh = this.refresh.bind(this); - this.updateCounter = this.updateCounter.bind(this); - this.updateCounters = this.updateCounters.bind(this); this.showError = this.showError.bind(this); + this.toArr = this.toArr.bind(this); + this.toElem = this.toElem.bind(this); - this.webpage = strToURL(url); + this.webpage = this.strToURL(url); this.host = this.getHost(this.webpage.host); this.domain = this.getDomain(this.webpage.host); this.ready = false; @@ -1078,7 +1072,7 @@ class Container { this.shadowRoot = undefined; this.supported = isFN(make('main-userjs').attachShadow); this.frame = this.supported - ? make('main-userjs', '', { + ? make('main-userjs', { dataset: { insertedBy: $info.script.name, role: 'primary-container' @@ -1108,9 +1102,9 @@ class Container { }); if (this.supported) { this.shadowRoot = this.frame.attachShadow({ - mode: 'open', - clonable: false, - delegatesfocus: false + mode: 'closed' + // clonable: false, + // delegatesfocus: false }); this.ready = true; } @@ -1120,9 +1114,6 @@ class Container { this.unsaved = false; this.isBlacklisted = false; this.rebuild = false; - this.counters = { - total: 0 - }; this.opacityMin = '0.15'; this.opacityMax = '1'; this.elementsReady = this.init(); @@ -1206,41 +1197,24 @@ class Container { initFn() { this.renderTheme(cfg.theme); - for (const engine of cfg.engines) { - if (engine.enabled) { - const counter = make('count-frame', '', { - dataset: { - counter: engine.name - }, - title: engine.query ? decodeURIComponent(engine.query) : engine.url, - textContent: '0' - }); - this.countframe.append(counter); - } - this.counters[engine.name] = 0; - } - - const cfgpage = this.cfgpage; - const table = this.table; - const exBtn = this.exBtn; - const supported = this.supported; - const frame = this.frame; - const refresh = this.refresh; - const cache = this.cache; - const cHost = this.host; - const urlBar = this.urlBar; + Counter.cnt.total.root = this.mainbtn; + for (const engine of cfg.engines) this.countframe.append(Counter.set(engine)); + const { cfgpage, table, exBtn, supported, frame, refresh, cache, urlBar, host } = this; class Tabs { /** * @param { HTMLElement } root */ constructor(root) { - this.Tab = new Map(); + /** + * @type { Set } + */ + this.pool = new Set(); this.blank = BLANK_PAGE; this.protocal = 'mujs:'; - this.protoReg = new RegExp(`${this.protocal}(.+)`); + this.protoReg = new RegExp(`${this.protocal}(.+)`, 'i'); this.el = { - add: make('mujs-addtab', '', { + add: make('mujs-addtab', { textContent: '+', dataset: { command: 'new-tab' @@ -1253,43 +1227,23 @@ class Container { this.el.root.append(this.el.head); this.custom = () => {}; } - hasTab(...params) { - for (const p of params) { - if (!this.Tab.has(p)) { - return false; - } - const content = normalizeTarget(this.Tab.get(p)).filter((t) => p === t.dataset.host); - if (isBlank(content)) { - return false; - } - } - return true; - } - storeTab(host) { - const h = host ?? this.blank; - if (!this.Tab.has(h)) { - this.Tab.set(h, new Set()); - } - return this.Tab.get(h); + /** + * @param {string} hostname + */ + getTab(hostname) { + return [...this.pool].find(({ dataset }) => hostname === dataset.host); } - cache(host, ...tabs) { - const h = host ?? this.blank; - const tabCache = this.storeTab(h); - for (const t of normalizeTarget(tabs)) { - if (tabCache.has(t)) { - continue; - } - tabCache.add(t); - } - this.Tab.set(h, tabCache); - return tabCache; + getActive() { + return [...this.pool].find((tab) => tab.classList.contains('active')); } - intFN(host) { - if (!host.startsWith(this.protocal)) { + /** + * @param {string} hostname + */ + intFN(hostname) { + if (!hostname.startsWith(this.protocal)) { return; } - const type = host.match(this.protoReg)[1]; - if (type === 'settings') { + if (hostname.match(this.protoReg)[1] === 'settings') { dom.cl.remove([cfgpage, exBtn], 'hidden'); dom.cl.add(table, 'hidden'); if (!supported) { @@ -1297,67 +1251,60 @@ class Container { } } } + /** + * @param {HTMLElement} tab + * @param {boolean} [build] + */ active(tab, build = true) { - for (const t of normalizeTarget(tab, false)) { - dom.cl.add([cfgpage, exBtn], 'hidden'); - dom.cl.remove(table, 'hidden'); - dom.cl.remove(qsA('mujs-tab', this.el.head), 'active'); - dom.cl.add(t, 'active'); - if (!build) { - continue; - } - const host = t.dataset.host ?? this.blank; - if (host === this.blank) { - refresh(); - } else if (host.startsWith(this.protocal)) { - this.intFN(host); - } else { - this.custom(host); - } + if (!this.pool.has(tab)) this.pool.add(tab); + dom.cl.add([cfgpage, exBtn], 'hidden'); + dom.cl.remove(table, 'hidden'); + dom.cl.remove([...this.pool], 'active'); + dom.cl.add(tab, 'active'); + if (!build) { + return; + } + const host = tab.dataset.host ?? this.blank; + if (host === this.blank) { + refresh(); + } else if (host.startsWith(this.protocal)) { + this.intFN(host); + } else { + this.custom(host); } } /** @param { HTMLElement } tab */ close(tab) { - for (const t of normalizeTarget(tab, false)) { - const host = t.dataset.host; - if (cache.has(host)) { - cache.delete(host); - } - if (dom.cl.has(t, 'active')) { - refresh(); - } - const sibling = t.previousElementSibling ?? t.nextElementSibling; - if (sibling) { - if (sibling.dataset.command !== 'new-tab') { - this.active(sibling); - } - } - if (this.Tab.has(host)) { - this.Tab.delete(host); + if (this.pool.has(tab)) this.pool.delete(tab); + const host = tab.dataset.host; + if (cfg.clearTabCache && cache.has(host)) cache.delete(host); + if (tab.classList.contains('active')) refresh(); + const sibling = tab.nextElementSibling ?? tab.previousElementSibling; + if (sibling) { + if (sibling.dataset.command !== 'new-tab') { + this.active(sibling); } - t.remove(); } + tab.remove(); } - create(host = undefined) { - if (typeof host === 'string') { - if (host.startsWith(this.protocal) && this.hasTab(host)) { - this.active(this.Tab.get(host)); - return; - } - const content = normalizeTarget(this.storeTab(host)).filter( - (t) => host === t.dataset.host - ); - if (!isEmpty(content)) { + /** + * @param {string} [hostname] + */ + create(hostname = undefined) { + if (typeof hostname === 'string') { + const createdTab = this.getTab(hostname); + if (this.protoReg.test(hostname) && createdTab) { + this.active(createdTab); return; } } - const tab = make('mujs-tab', '', { + const tab = make('mujs-tab', { dataset: { command: 'switch-tab' }, style: `order: ${this.el.head.childElementCount};` }); - const tabClose = make('mu-js', '', { + const tabClose = make('mu-js', { dataset: { command: 'close-tab' }, @@ -1368,29 +1315,28 @@ class Container { tab.append(tabHost, tabClose); this.el.head.append(tab); this.active(tab, false); - this.cache(host, tab); - if (isNull(host)) { + if (isNull(hostname)) { refresh(); urlBar.placeholder = i18n$('newTab'); tab.dataset.host = this.blank; tabHost.title = i18n$('newTab'); tabHost.textContent = i18n$('newTab'); - } else if (host.startsWith(this.protocal)) { - const type = host.match(this.protoReg)[1]; - tab.dataset.host = host || cHost; + } else if (hostname.startsWith(this.protocal)) { + const type = hostname.match(this.protoReg)[1]; + tab.dataset.host = hostname || host; tabHost.title = type || tab.dataset.host; tabHost.textContent = tabHost.title; - this.intFN(host); + this.intFN(hostname); } else { - tab.dataset.host = host || cHost; - tabHost.title = host || cHost; + tab.dataset.host = hostname || host; + tabHost.title = hostname || host; tabHost.textContent = tabHost.title; } return tab; } } this.tab = new Tabs(this.toolbar); - this.tab.create(this.host); + this.tab.create(host); const tabbody = this.tabbody; const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent; @@ -1532,9 +1478,9 @@ class Container { command: 'navigation' } }); - const makeTHead = (rows) => { + const makeTHead = (rows = []) => { const tr = make('tr'); - for (const r of normalizeTarget(rows)) { + for (const r of rows) { const tparent = make('th', r.class ?? '', r); tr.append(tparent); } @@ -1589,6 +1535,7 @@ class Container { this.unsaved = false; await StorageSystem.setValue('Config', cfg); info('Saved config:', cfg); + this.redirect(); return cfg; } /** @@ -1628,7 +1575,7 @@ class Container { return sty; } } - const sty = make('style', '', { + const sty = make('style', { textContent: css, dataset: { insertedBy: $info.script.name, @@ -1682,7 +1629,7 @@ class Container { return this.isBlacklisted; } getInfo(url) { - const webpage = strToURL(url || this.webpage); + const webpage = this.strToURL(url || this.webpage); const host = this.getHost(webpage.host); const domain = this.getDomain(webpage.host); return { @@ -1760,6 +1707,10 @@ class Container { } this.promptElem.append(el); } + /** + * @template {string | Error} E + * @param {...E} ex + */ showError(...ex) { err(...ex); const error = make('mu-js', 'error'); @@ -1776,34 +1727,74 @@ class Container { error.appendChild(createTextNode(str)); this.footer.append(error); } - updateCounter(count, engine) { - this.counters[engine.name] += count; - this.counters.total += count; - this.updateCounters(); + toArr() { + return Array.from(this.userjsCache.values()).filter(({ _mujs }) => { + return isElem(_mujs.root) && _mujs.info.engine.enabled; + }); } - updateCounters() { - for (const [k, v] of Object.entries(this.counters)) { - if (k === 'total') { - continue; - } - const c = qs(`count-frame[data-counter="${k}"]`, this.countframe); - if (c) { - dom.text(c, v); - } - } - dom.text(this.mainbtn, this.counters.total); + toElem() { + return this.toArr().map(({ _mujs }) => { + return _mujs.root; + }); } refresh() { this.urlBar.placeholder = i18n$('newTab'); - this.counters.total = 0; - for (const engine of cfg.engines) { - this.counters[engine.name] = 0; - } - this.updateCounters(); - dom.cl.remove(qsA('tr[data-engine]', this.tabbody), 'hidden'); + Counter.reset(); + dom.cl.remove(this.toElem(), 'hidden'); dom.cl.remove(qsA('mujs-section[data-name]', this.cfgpage), 'hidden'); dom.prop([this.tabbody, this.rateContainer, this.footer], 'innerHTML', ''); } + /** + * @template {string | URL} S + * @param {S} str + * @returns {URL} + */ + strToURL(str) { + const WIN_LOCATION = window.location ?? BLANK_PAGE; + try { + str = str ?? WIN_LOCATION; + return objToStr(str).includes('URL') ? str : new URL(str); + } catch (ex) { + ex.cause = 'strToURL'; + this.showError(ex); + } + return WIN_LOCATION; + } + /** + * Redirects sleazyfork userscripts from greasyfork.org to sleazyfork.org + * + * Taken from: https://greasyfork.org/scripts/23840 + */ + redirect() { + const locObj = window.top.location; + const { hostname } = locObj; + const gfSite = /greasyfork\.org/.test(hostname); + if (!gfSite && cfg.sleazyredirect) { + return; + } + const otherSite = gfSite ? 'sleazyfork' : 'greasyfork'; + if (!qs('span.sign-in-link')) { + return; + } + if (!/scripts\/\d+/.test(locObj.href)) { + return; + } + if ( + !qs('#script-info') && + (otherSite == 'greasyfork' || qs('div.width-constraint>section>p>a')) + ) { + const str = locObj.href.replace( + /\/\/([^.]+\.)?(greasyfork|sleazyfork)\.org/, + '//$1' + otherSite + '.org' + ); + info(`Redirecting to "${str}"`); + if (isFN(locObj.assign)) { + locObj.assign(str); + } else { + locObj.href = str; + } + } + } } const container = new Container(); // #endregion @@ -1820,8 +1811,6 @@ function primaryFN() { rateContainer, footer, tabbody, - toolbar, - tabhead, cfgpage, fsearch, btnfullscreen, @@ -1831,8 +1820,6 @@ function primaryFN() { btnissue, btngreasy, tab, - userjsCache, - updateCounter, showError } = container; const frameTimeout = container.timeouts.frame; @@ -1902,7 +1889,7 @@ function primaryFN() { } else if (prmpt !== prmptChoice) { installCode = dataset.userjs.replace(/\.user\.css$/, '.user.js'); } - const dlBtn = make('a', '', { + const dlBtn = make('a', { onclick(evt) { evt.preventDefault(); doInstallProcess(evt.target); @@ -1972,7 +1959,6 @@ function primaryFN() { dom.prop(rateContainer, 'innerHTML', ''); if (!dom.prop(target, 'disabled')) { const config = await container.save(); - sleazyRedirect(); if (container.rebuild) { container.cache.clear(); if (config.autofetch) { @@ -2052,7 +2038,7 @@ function primaryFN() { const apTo = (name, elem, root) => { const n = dataUserJS._mujs.code[name]; if (isEmpty(n)) { - const el = make('mujs-a', '', { + const el = make('mujs-a', { textContent: i18n$('listing_none') }); elem.append(el); @@ -2062,7 +2048,7 @@ function primaryFN() { dom.cl.remove(root, 'hidden'); for (const c of n) { if (typeof c === 'string' && c.startsWith('http')) { - const el = make('mujs-a', '', { + const el = make('mujs-a', { textContent: c, dataset: { command: 'open-tab', @@ -2073,7 +2059,7 @@ function primaryFN() { } else if (isObj(c)) { if (name === 'resource') { for (const [k, v] of Object.entries(c)) { - const el = make('mujs-a', '', { + const el = make('mujs-a', { textContent: k ?? 'ERROR' }); if (v.startsWith('http')) { @@ -2083,7 +2069,7 @@ function primaryFN() { elem.append(el); } } else { - const el = make('mujs-a', '', { + const el = make('mujs-a', { textContent: c.text }); if (c.domain) { @@ -2093,15 +2079,17 @@ function primaryFN() { elem.append(el); } } else { - const el = make('mujs-a', '', { + const el = make('mujs-a', { textContent: c }); elem.append(el); } } }; - const m = qsA('mujs-column[data-el="matches"]', target.parentElement.parentElement); - for (const e of normalizeTarget(m)) { + for (const e of qsA( + 'mujs-column[data-el="matches"]', + target.parentElement.parentElement + )) { apTo(e.dataset.type, qs('.mujs-grants', e), e); } } else if (/export-/.test(cmd)) { @@ -2136,7 +2124,6 @@ function primaryFN() { container.rebuild = true; rebuildCfg(); container.save().then((config) => { - sleazyRedirect(); container.cache.clear(); if (config.autofetch) { respHandles.build(); @@ -2469,42 +2456,23 @@ function primaryFN() { // return [...new Set(a)].filter((v) => arr.every((b) => b.includes(v))); // } } - const mergeTemplate = (obj = {}) => { - const template = { - id: 0, - bad_ratings: 0, - good_ratings: 0, - ok_ratings: 0, - daily_installs: 0, - total_installs: 0, - name: 'NOT FOUND', - description: 'NOT FOUND', - version: '0.0.0', - url: BLANK_PAGE, - code_url: BLANK_PAGE, - created_at: Date.now(), - code_updated_at: Date.now(), - locale: 'NOT FOUND', - deleted: false, - users: [ - { - id: 0, - name: 'NOT FOUND', - url: BLANK_PAGE - } - ] - }; - /** @type {ObjectConstructor["hasOwn"]} */ - const hasOwn = - Object.hasOwn || - function hasOwn(it, key) { - return Object.prototype.hasOwnProperty.call(it, key); - }; - for (const key in template) { - if (hasOwn(obj, key)) continue; - obj[key] = template[key]; - } - return obj; + const template = { + id: 0, + bad_ratings: 0, + good_ratings: 0, + ok_ratings: 0, + daily_installs: 0, + total_installs: 0, + name: 'NOT FOUND', + description: 'NOT FOUND', + version: '0.0.0', + url: BLANK_PAGE, + code_url: BLANK_PAGE, + created_at: Date.now(), + code_updated_at: Date.now(), + locale: 'NOT FOUND', + deleted: false, + users: [] }; const mkList = (txt = '', obj = {}) => { if (!obj.root || !obj.type) { @@ -2526,7 +2494,7 @@ function primaryFN() { const list = obj.list ?? []; if (isEmpty(list)) { - const elem = make('mujs-a', '', { + const elem = make('mujs-a', { textContent: i18n$('listing_none') }); applyList.append(elem); @@ -2535,7 +2503,7 @@ function primaryFN() { } for (const c of list) { if (typeof c === 'string' && c.startsWith('http')) { - const elem = make('mujs-a', '', { + const elem = make('mujs-a', { textContent: c, dataset: { command: 'open-tab', @@ -2546,7 +2514,7 @@ function primaryFN() { } else if (isObj(c)) { if (type === 'resource') { for (const [k, v] of Object.entries(c)) { - const elem = make('mujs-a', '', { + const elem = make('mujs-a', { textContent: k ?? 'ERROR' }); if (v.startsWith('http')) { @@ -2556,7 +2524,7 @@ function primaryFN() { applyList.append(elem); } } else { - const elem = make('mujs-a', '', { + const elem = make('mujs-a', { textContent: c.text }); if (c.domain) { @@ -2566,7 +2534,7 @@ function primaryFN() { applyList.append(elem); } } else { - const elem = make('mujs-a', '', { + const elem = make('mujs-a', { textContent: c }); applyList.append(elem); @@ -2596,7 +2564,6 @@ function primaryFN() { * @param { string } engine */ const createjs = (ujs, engine) => { - ujs = mergeTemplate(ujs); // Lets not add this UserJS to the list if (ujs.id === 421603) { return; @@ -2688,7 +2655,7 @@ function primaryFN() { userjs: ujs.code_url } }); - const scriptDownload = make('mu-jsbtn', '', { + const scriptDownload = make('mu-jsbtn', { innerHTML: `${iconSVG.load('install')} ${i18n$('saveFile')}`, dataset: { command: 'download-userjs', @@ -2710,7 +2677,7 @@ function primaryFN() { spellcheck: false, wrap: 'soft' }); - const loadCode = make('mu-jsbtn', '', { + const loadCode = make('mu-jsbtn', { innerHTML: `${iconSVG.load('search')} ${i18n$('preview_code')}`, dataset: { command: 'load-userjs', @@ -2730,7 +2697,7 @@ function primaryFN() { } } for (const u of ujs.users) { - const user = make('mujs-a', '', { + const user = make('mujs-a', { innerHTML: u.name, title: u.url, dataset: { @@ -2793,63 +2760,73 @@ function primaryFN() { codeArea.value = code_obj.get_code_block(); } - if (ujs._mujs.code?.translated) { - tr.classList.add('translated'); - } + if (ujs._mujs.code?.translated) tr.classList.add('translated'); - for (const e of [fname, uframe, fdaily, fupdated, eframe]) { - tr.append(e); - } - tabbody.append(tr); + for (const e of [fname, uframe, fdaily, fupdated, eframe]) tr.append(e); ujs._mujs.root = tr; return tr; }; // #endregion const loadFilters = () => { - const resp = []; - for (const v of Object.values(cfg.filters)) { - if (!v.enabled) { - continue; - } - resp.push(new RegExp(v.regExp, v.flag)); - } - return { - regExp: resp, - get(name) { - for (const v of Object.values(cfg.filters)) { - if (v.name === name) { - return new RegExp(v.regExp, v.flag) - }; + /** @type {Map} */ + const pool = new Map(); + const handles = { + pool, + enabled() { + return [...pool.values()].filter((o) => o.enabled); + }, + refresh() { + if (!Object.is(pool.size, 0)) pool.clear(); + for (const [key, value] of Object.entries(cfg.filters)) { + if (!pool.has(key)) + pool.set(key, { + ...value, + reg: new RegExp(value.regExp, value.flag), + keyReg: new RegExp(key.trim().toLocaleLowerCase(), 'gi'), + valueReg: new RegExp(value.name.trim().toLocaleLowerCase(), 'gi') + }); } - // return resp.find(r => r.name === name); + return this; }, + get(str) { + return [...pool.values()].find((v) => v.keyReg.test(str) || v.valueReg.test(str)); + }, + /** + * @param { import("../typings/types.d.ts").GSForkQuery } param0 + */ match({ name, users }) { - if (isBlank(resp)) { - return true; - } - const strArr = [{ name }, ...users]; - for (const r of resp) { - const v = strArr.find((o) => o.name.match(r)); - if (v) { - return false; - } + const p = handles.enabled(); + if (Object.is(p.length, 0)) return true; + for (const v of p) { + if ([{ name }, ...users].find((o) => o.name.match(v.reg))) return false; } return true; } }; + for (const [key, value] of Object.entries(cfg.filters)) { + if (!pool.has(key)) + pool.set(key, { + ...value, + reg: new RegExp(value.regExp, value.flag), + keyReg: new RegExp(key.trim().toLocaleLowerCase(), 'gi'), + valueReg: new RegExp(value.name.trim().toLocaleLowerCase(), 'gi') + }); + } + return handles.refresh(); }; // #region List class List { engines; - cache; intHost; - constructor(host = undefined) { + constructor(hostname = undefined) { this.build = this.build.bind(this); - if (isEmpty(host)) host = container.host; + this.toArr = this.toArr.bind(this); + this.groupBy = this.groupBy.bind(this); + this.sortRecords = this.sortRecords.bind(this); + if (isEmpty(hostname)) hostname = container.host; this.engines = cfg.engines; - this.cache = container.cache.get(host); - this.host = host; + this.host = hostname; } set host(hostname) { @@ -2862,27 +2839,24 @@ function primaryFN() { } container.cache.set(hostname, engineTemplate); } - if (container.checkBlacklist(hostname)) { + this.blacklisted = container.checkBlacklist(hostname); + if (this.blacklisted) { showError(`Blacklisted "${hostname}"`); timeoutFrame(); - this.blacklisted = true; - } else { - this.blacklisted = false; } - const isSupported = (name) => { - for (const [k, v] of Object.entries(engineUnsupported)) { - if (k !== name) { - continue; - } - if (v.includes(hostname)) { - return false; - } + this.engines = cfg.engines.filter((e) => { + if (!e.enabled) { + return false; + } + const v = engineUnsupported[e.name] ?? []; + if (v.includes(hostname)) { + showError(`Engine: "${e.name}" unsupported on "${hostname}"`); + timeoutFrame(); + return false; } return true; - }; - this.engines = cfg.engines.filter((e) => e.enabled && isSupported(e.name)); - this.cache = container.cache.get(hostname); + }); } get host() { @@ -2893,235 +2867,228 @@ function primaryFN() { build() { try { container.refresh(); - if (this.blacklisted) { - return; - } - if (isEmpty(this.engines)) { + const { blacklisted, engines, host, toArr } = this; + if (blacklisted || isEmpty(engines)) { container.opacityMin = '0'; mainframe.style.opacity = container.opacityMin; return; } - info(' Building list', { cache: this.cache, engines: this.engines }); - const customRecords = []; - const host = this.host; - const arr = []; + const fetchRecords = []; const bsFilter = loadFilters(); + const hostCache = toArr(); - for (const engine of this.engines) { - const cEngine = this.cache[`${engine.name}`]; - if (!isEmpty(cEngine)) { - for (const ujs of cEngine) { - if (isElem(ujs._mujs.root)) { - tabbody.append(ujs._mujs.root); + info('Building list', { hostCache, engines }); + + if (isBlank(hostCache)) { + for (const engine of engines) { + info(`Fetching from "${engine.name}" for "${host}"`); + const respError = (error) => { + if (!error.cause) error.cause = engine.name; + if (error.message.startsWith('429')) { + showError(`Engine: "${engine.name}" Too many requests...`); + return; } - } - updateCounter(cEngine.length, engine); - continue; - } - const respError = (error) => { - if (!error.cause) error.cause = engine.name; - if (error.message.startsWith('429')) { - showError(`Engine: "${engine.name}" Too many requests...`); - return; - } - showError(`Engine: "${engine.name}"`, error.message); - }; - const _mujs = (d) => { - const obj = { - ...d, - _mujs: { - root: {}, - info: { - engine, - host - }, - code: { - antifeatures: [], - grant: [], - match: [], - meta: {}, - request: async function (translate = false, code_url) { - if (this.data) { - return this; - } - this.data = ''; - /** @type { string } */ - const code = await Network.req(code_url ?? d.code_url, 'GET', 'text').catch( - showError - ); - if (typeof code !== 'string') { - return this; - } - Object.assign(this, { - data: code, - code_size: [Network.format(code.length)] - }); - const grantSet = new Set(); - const afSet = new Set(); - const code_obj = new ParseUserJS(code); - const meta = code_obj.parse_meta(); - const applies_to_names = code_obj.calculate_applies_to_names(); - - if (translate) { - for (const lng of language.cache) { - if (meta[`name:${lng}`]) { - Object.assign(obj, { - name: meta[`name:${lng}`] - }); - this.translated = true; - } - if (meta[`description:${lng}`]) { - Object.assign(obj, { - description: meta[`description:${lng}`] - }); - this.translated = true; + showError(`Engine: "${engine.name}"`, error.message); + }; + const _mujs = (d) => { + const obj = { + ...template, + ...d, + _mujs: { + root: {}, + info: { + engine, + host + }, + code: { + antifeatures: [], + grant: [], + match: [], + meta: {}, + request: async function (translate = false, code_url) { + if (this.data) { + return this; + } + this.data = ''; + /** @type { string } */ + const code = await Network.req(code_url ?? d.code_url, 'GET', 'text').catch( + showError + ); + if (typeof code !== 'string') { + return this; + } + Object.assign(this, { + data: code, + code_size: [Network.format(code.length)] + }); + const grantSet = new Set(); + const afSet = new Set(); + const code_obj = new ParseUserJS(code); + const meta = code_obj.parse_meta(); + const applies_to_names = code_obj.calculate_applies_to_names(); + + if (translate) { + for (const k of userjs.pool.keys()) { + if (meta[`name:${k}`]) { + Object.assign(obj, { + name: meta[`name:${k}`] + }); + this.translated = true; + } + if (meta[`description:${k}`]) { + Object.assign(obj, { + description: meta[`description:${k}`] + }); + this.translated = true; + } } } - } - for (const [key, value] of Object.entries(meta)) { - if (/grant/.test(key)) { - for (const v of normalizeTarget(value, false)) { - if (grantSet.has(v)) { - continue; + for (const [key, value] of Object.entries(meta)) { + if (/grant/.test(key)) { + for (const v of normalizeTarget(value, false)) { + if (grantSet.has(v)) { + continue; + } + grantSet.add(v); } - grantSet.add(v); - } - } else if (/antifeature/.test(key)) { - for (const v of normalizeTarget(value, false)) { - if (afSet.has(v)) { - continue; + } else if (/antifeature/.test(key)) { + for (const v of normalizeTarget(value, false)) { + if (afSet.has(v)) { + continue; + } + afSet.add(v); } - afSet.add(v); } } - } - if (typeof meta.require === 'string') { - const s = meta.require; - meta.require = [s]; - } - if (meta.resource) { - const obj = {}; - if (typeof meta.resource === 'string') { - const reg = /(.+)\s+(.+)/.exec(meta.resource); - if (reg) { - obj[reg[1].trim()] = reg[2]; - } - } else { - for (const r of meta.resource) { - const reg = /(.+)\s+(http.+)/.exec(r); + if (typeof meta.require === 'string') { + const s = meta.require; + meta.require = [s]; + } + if (meta.resource) { + const obj = {}; + if (typeof meta.resource === 'string') { + const reg = /(.+)\s+(.+)/.exec(meta.resource); if (reg) { obj[reg[1].trim()] = reg[2]; } + } else { + for (const r of meta.resource) { + const reg = /(.+)\s+(http.+)/.exec(r); + if (reg) { + obj[reg[1].trim()] = reg[2]; + } + } } + meta.resource = obj; } - meta.resource = obj; - } - Object.assign(this, { - meta, - match: applies_to_names, - grant: [...grantSet], - antifeatures: [...afSet] - }); + Object.assign(this, { + meta, + match: applies_to_names, + grant: [...grantSet], + antifeatures: [...afSet] + }); - return this; + return this; + } } } - } + }; + return obj; }; - return obj; - }; - const toQuery = (fallback) => { - if (engine.query) { - return decodeURIComponent(engine.query).replace(/\{host\}/g, host); - } - return fallback; - }; - /** - * @param { import("../typings/types.d.ts").GSFork } dataQ - */ - const forkFN = async (dataQ) => { - if (!dataQ) { - showError('Invalid data received from the server, check internet connection'); - return; - } /** - * @type { import("../typings/types.d.ts").GSForkQuery[] } + * Prior to UserScript v7.0.0 + * @template {string} F + * @param {F} fallback + * @returns {F} */ - const dq = Array.isArray(dataQ) - ? dataQ - : Array.isArray(dataQ.query) - ? dataQ.query - : []; - const dataA = dq - .filter(Boolean) - .filter((d) => !d.deleted) - .filter(bsFilter.match); - if (isBlank(dataA)) { - return; - } - const data = dataA.map(_mujs); - const otherLng = []; + const toQuery = (fallback) => { + if (engine.query) { + return decodeURIComponent(engine.query).replace(/\{host\}/g, host); + } + return fallback; + }; /** - * @param {import("../typings/types.d.ts").GSForkQuery} d - * @returns {boolean} + * @param { import("../typings/types.d.ts").GSFork } dataQ */ - const inUserLanguage = (d) => { - const dlocal = d.locale.split('-')[0] ?? d.locale; - if (language.cache.includes(dlocal)) { - return true; + const forkFN = async (dataQ) => { + if (!dataQ) { + showError('Invalid data received from the server, check internet connection'); + return; } - otherLng.push(d); - return false; - }; - const filterLang = data.filter((d) => { - if (cfg.filterlang && !inUserLanguage(d)) { - return false; + /** + * @type { import("../typings/types.d.ts").GSForkQuery[] } + */ + const dq = Array.isArray(dataQ) + ? dataQ + : Array.isArray(dataQ.query) + ? dataQ.query + : []; + const dataA = dq + .filter(Boolean) + .filter((d) => !d.deleted) + .filter(bsFilter.match); + if (isBlank(dataA)) { + return; } - return true; - }); - let finalList = filterLang; - const hds = []; - for (const ujs of otherLng) { - const c = await ujs._mujs.code.request(true); - if (c.translated) { - hds.push(ujs); + const data = dataA.map(_mujs); + const otherLng = []; + /** + * @param {import("../typings/types.d.ts").GSForkQuery} d + * @returns {boolean} + */ + const inUserLanguage = (d) => { + if (userjs.pool.has(d.locale.split('-')[0] ?? d.locale)) { + return true; + } + otherLng.push(d); + return false; + }; + const filterLang = data.filter((d) => { + if (cfg.filterlang && !inUserLanguage(d)) { + return false; + } + return true; + }); + let finalList = filterLang; + const hds = []; + for (const ujs of otherLng) { + const c = await ujs._mujs.code.request(true); + if (c.translated) { + hds.push(ujs); + } } - } - finalList = union(hds, filterLang); + finalList = union(hds, filterLang); - for (const ujs of finalList) { - if (cfg.codePreview && !ujs._mujs.code.data) { - await ujs._mujs.code.request(); - } - createjs(ujs, engine.name); - } - this.cache[engine.name].push(...finalList); - updateCounter(finalList.length, engine); - }; - /** - * @param {Document} htmlDocument - */ - const openuserjs = async (htmlDocument) => { - try { - if (!htmlDocument) { - showError('Invalid data received from the server, TODO fix this'); - return; + for (const ujs of finalList) { + if (cfg.codePreview && !ujs._mujs.code.data) { + await ujs._mujs.code.request(); + } + createjs(ujs, engine.name); } - const selected = htmlDocument.documentElement; - if (/openuserjs/gi.test(engine.name)) { - for (const i of qsA('.col-sm-8 .tr-link', selected)) { - while (isNull(qs('.script-version', i))) { - await new Promise((resolve) => requestAnimationFrame(resolve)); - } - const fixurl = dom - .prop(qs('.tr-link-a', i), 'href') - .replace( - new RegExp(document.location.origin, 'gi'), - 'https://openuserjs.org' - ); - const ujs = mergeTemplate( - _mujs({ + }; + /** + * @param {Document} htmlDocument + */ + const openuserjs = async (htmlDocument) => { + try { + if (!htmlDocument) { + showError('Invalid data received from the server, TODO fix this'); + return; + } + const selected = htmlDocument.documentElement; + if (/openuserjs/gi.test(engine.name)) { + for (const i of qsA('.col-sm-8 .tr-link', selected)) { + while (isNull(qs('.script-version', i))) { + await new Promise((resolve) => requestAnimationFrame(resolve)); + } + const fixurl = dom + .prop(qs('.tr-link-a', i), 'href') + .replace( + new RegExp(document.location.origin, 'gi'), + 'https://openuserjs.org' + ); + const ujs = _mujs({ name: dom.text(qs('.tr-link-a', i)), description: dom.text(qs('p', i)), version: dom.text(qs('.script-version', i)), @@ -3136,33 +3103,28 @@ function primaryFN() { url: dom.prop(qs('.inline-block a', i), 'href') } ] - }) - ); - if (bsFilter.match(ujs)) { - continue; - } - if (cfg.codePreview && !ujs._mujs.code.data) { - await ujs._mujs.code.request(); + }); + if (bsFilter.match(ujs)) { + continue; + } + if (cfg.codePreview && !ujs._mujs.code.data) { + await ujs._mujs.code.request(); + } + createjs(ujs, engine.name); } - createjs(ujs, engine.name); - customRecords.push(ujs); } + } catch (ex) { + showError(ex); } - this.cache[engine.name].push(...customRecords); - updateCounter(customRecords.length, engine); - } catch (ex) { - showError(ex); - } - }; - const gitFN = async (data) => { - try { - if (isBlank(data.items)) { - showError('Invalid data received from the server, TODO fix this'); - return; - } - for (const r of data.items) { - const ujs = mergeTemplate( - _mujs({ + }; + const gitFN = async (data) => { + try { + if (isBlank(data.items)) { + showError('Invalid data received from the server, TODO fix this'); + return; + } + for (const r of data.items) { + const ujs = _mujs({ name: r.name, description: isEmpty(r.repository.description) ? i18n$('no_license') @@ -3177,87 +3139,118 @@ function primaryFN() { url: r.repository.owner.html_url } ] - }) - ); - if (bsFilter.match(ujs)) { - continue; - } - if (cfg.codePreview && !ujs._mujs.code.data) { - await ujs._mujs.code.request(); + }); + if (bsFilter.match(ujs)) { + continue; + } + if (cfg.codePreview && !ujs._mujs.code.data) { + await ujs._mujs.code.request(); + } + createjs(ujs, engine.name); } - createjs(ujs, engine.name); - customRecords.push(ujs); + } catch (ex) { + showError(ex); } - this.cache[engine.name].push(...customRecords); - updateCounter(data.items.length, engine); - } catch (ex) { - showError(ex); - } - }; - let netFN; - if (/github/gi.test(engine.name)) { - if (isEmpty(engine.token)) { - showError(`"${engine.name}" requires a token to use`); - continue; - } - netFN = Network.req( - toQuery( - `${engine.url}"// ==UserScript=="+${host}+ "// ==/UserScript=="+in:file+language:js&per_page=30` - ), - 'GET', - 'json', - { - headers: { - Accept: 'application/vnd.github+json', - Authorization: `Bearer ${engine.token}`, - 'X-GitHub-Api-Version': '2022-11-28' - } + }; + let netFN; + if (/github/gi.test(engine.name)) { + if (isEmpty(engine.token)) { + showError(`"${engine.name}" requires a token to use`); + continue; } - ) - .then(gitFN) - .then(() => { - Network.req('https://api.github.com/rate_limit', 'GET', 'json', { + netFN = Network.req( + toQuery( + `${engine.url}"// ==UserScript=="+${host}+ "// ==/UserScript=="+in:file+language:js&per_page=30` + ), + 'GET', + 'json', + { headers: { Accept: 'application/vnd.github+json', Authorization: `Bearer ${engine.token}`, 'X-GitHub-Api-Version': '2022-11-28' } - }) - .then((data) => { - for (const [key, value] of Object.entries(data.resources.code_search)) { - const txt = make('mujs-row', 'rate-info', { - textContent: `${key.toUpperCase()}: ${value}` - }); - rateContainer.append(txt); + } + ) + .then(gitFN) + .then(() => { + Network.req('https://api.github.com/rate_limit', 'GET', 'json', { + headers: { + Accept: 'application/vnd.github+json', + Authorization: `Bearer ${engine.token}`, + 'X-GitHub-Api-Version': '2022-11-28' } }) - .catch(respError); - }); - } else if (/openuserjs/gi.test(engine.name)) { - netFN = Network.req(toQuery(`${engine.url}${host}`), 'GET', 'document').then( - openuserjs - ); - } else { - netFN = Network.req( - toQuery(`${engine.url}/scripts/by-site/${host}.json?language=all`) - ).then(forkFN); - } - if (netFN) { - arr.push(netFN.catch(respError)); + .then((data) => { + for (const [key, value] of Object.entries(data.resources.code_search)) { + const txt = make('mujs-row', 'rate-info', { + textContent: `${key.toUpperCase()}: ${value}` + }); + rateContainer.append(txt); + } + }) + .catch(respError); + }); + } else if (/openuserjs/gi.test(engine.name)) { + netFN = Network.req(toQuery(`${engine.url}${host}`), 'GET', 'document').then( + openuserjs + ); + } else { + netFN = Network.req( + toQuery(`${engine.url}/scripts/by-site/${host}.json?language=all`) + ).then(forkFN); + } + if (netFN) { + fetchRecords.push(netFN.catch(respError)); + } } + } else { + for (const ujs of hostCache) tabbody.append(ujs._mujs.root); } urlBar.placeholder = i18n$('search_placeholder'); urlBar.value = ''; - Promise.allSettled(arr).then(() => { - tabhead.rows[0].cells[2].dispatchEvent(new MouseEvent('click')); - tabhead.rows[0].cells[2].dispatchEvent(new MouseEvent('click')); - }); + if (isBlank(fetchRecords)) { + this.sortRecords(); + return; + } + Promise.allSettled(fetchRecords).then(this.sortRecords).catch(showError); } catch (ex) { showError(ex); } } + + sortRecords() { + const arr = this.toArr(); + for (const ujs of arr.flat().sort((a, b) => { + const sortType = cfg.autoSort ?? 'daily_installs'; + return b[sortType] - a[sortType]; + })) { + if (isElem(ujs._mujs.root)) tabbody.append(ujs._mujs.root); + } + for (const [name, value] of Object.entries(this.groupBy(arr))) + Counter.update(value.length, { name }); + } + + toArr() { + const h = this.intHost; + return container.toArr().filter(({ _mujs }) => _mujs.info.host === h); + } + + groupBy(arr) { + const callback = ({ _mujs }) => _mujs.info.engine.name; + if (isFN(Object.groupBy)) { + return Object.groupBy(arr, callback); + } + /** [Object.groupBy polyfill](https://gist.github.com/gtrabanco/7c97bd41aa74af974fa935bfb5044b6e) */ + return arr.reduce((acc = {}, ...args) => { + const key = callback(...args); + acc[key] ??= []; + acc[key].push(args[0]); + return acc; + }, {}); + } // #endregion } const MUList = new List(); @@ -3281,17 +3274,17 @@ function primaryFN() { const makesection = (name, tag) => { tag = tag ?? i18n$('no_license'); name = name ?? i18n$('no_license'); - const sec = make('mujs-section', '', { + const sec = make('mujs-section', { dataset: { name: tag } }); - const lb = make('label', '', { + const lb = make('label', { dataset: { command: tag } }); - const divDesc = make('mu-js', '', { + const divDesc = make('mu-js', { textContent: name }); ael(sec, 'click', (evt) => { @@ -3330,13 +3323,13 @@ function primaryFN() { const makerow = (desc, type = null, nm, attrs = {}) => { desc = desc ?? i18n$('no_license'); nm = nm ?? i18n$('no_license'); - const sec = make('mujs-section', '', { + const sec = make('mujs-section', { dataset: { name: nm } }); const lb = make('label'); - const divDesc = make('mu-js', '', { + const divDesc = make('mu-js', { textContent: desc }); lb.append(divDesc); @@ -3345,7 +3338,7 @@ function primaryFN() { if (isNull(type)) { return lb; } - const inp = make('input', '', { + const inp = make('input', { type, dataset: { name: nm @@ -3357,7 +3350,7 @@ function primaryFN() { } if (type === 'checkbox') { const inlab = make('mu-js', 'mujs-inlab'); - const la = make('label', '', { + const la = make('label', { onclick() { inp.dispatchEvent(new MouseEvent('click')); } @@ -3380,7 +3373,7 @@ function primaryFN() { if (engine.query) { const d = DEFAULT_CONFIG.engines.find((e) => e.name === engine.name); - const urlInp = make('input', '', { + const urlInp = make('input', { type: 'text', defaultValue: '', value: decodeURIComponent(engine.query) ?? '', @@ -3402,7 +3395,7 @@ function primaryFN() { sec.append(urlInp); } if (engine.name === 'github') { - const ghToken = make('input', '', { + const ghToken = make('input', { type: 'text', defaultValue: '', value: engine.token ?? '', @@ -3443,7 +3436,29 @@ function primaryFN() { [tag]: text } }); - const inp = make('input', '', { + if (type === 'select') { + const inp = make('select', { + dataset: { + [tag]: text + }, + ...attrs + }); + for (const selV of Object.keys(template)) { + if (selV === 'deleted' || selV === 'users') continue; + const o = make('option', { + value: selV, + textContent: selV + }); + inp.append(o); + } + inp.value = cfg[value]; + lb.append(inp); + if (sections[tag]) { + sections[tag].append(lb); + } + return lb; + } + const inp = make('input', { type, dataset: { [tag]: text @@ -3457,7 +3472,7 @@ function primaryFN() { if (type === 'checkbox') { const inlab = make('mu-js', 'mujs-inlab'); - const la = make('label', '', { + const la = make('label', { onclick() { inp.dispatchEvent(new MouseEvent('click')); } @@ -3547,7 +3562,9 @@ function primaryFN() { } } }); + mkSection('Clear on Tab close', 'clearTabCache', 'checkbox', 'load'); + mkSection('Default Sort', 'autoSort', 'select', 'list'); mkSection(i18n$('filter'), 'filterlang', 'checkbox', 'list'); mkSection(i18n$('preview_code'), 'codePreview', 'checkbox', 'list'); mkSection('Recommend author', 'recommend-author', 'checkbox', 'list'); @@ -3569,7 +3586,7 @@ function primaryFN() { theme: k } }); - const inp = make('input', '', { + const inp = make('input', { type: 'text', defaultValue: '', value: v ?? '', @@ -3643,7 +3660,7 @@ function primaryFN() { blacklist: key } }); - const inp = make('input', '', { + const inp = make('input', { type: 'text', defaultValue: '', value: v ?? '', @@ -3673,7 +3690,7 @@ function primaryFN() { } } }); - const selType = make('select', '', { + const selType = make('select', { disabled, dataset: { blacklist: key @@ -3681,14 +3698,14 @@ function primaryFN() { }); if (disabled) { inp.readOnly = true; - const o = make('option', '', { + const o = make('option', { value: type, textContent: type }); selType.append(o); } else { for (const selV of ['String', 'RegExp', 'Object']) { - const o = make('option', '', { + const o = make('option', { value: selV, textContent: selV }); @@ -3699,7 +3716,7 @@ function primaryFN() { lb.append(inp, selType); sections.blacklist.append(lb); }; - // const blacklist = make('textarea', '', { + // const blacklist = make('textarea', { // dataset: { // name: 'blacklist' // }, @@ -3728,19 +3745,19 @@ function primaryFN() { // } // }); // cfgMap.set('blacklist', blacklist); - // const addList = make('mujs-add', '', { + // const addList = make('mujs-add', { // textContent: '+', // dataset: { // command: 'new-list' // } // }); - // const n = make('input', '', { + // const n = make('input', { // type: 'text', // defaultValue: '', // value: '', // placeholder: 'Name', // }); - // const inpValue = make('input', '', { + // const inpValue = make('input', { // type: 'text', // defaultValue: '', // value: '', @@ -3806,15 +3823,16 @@ function primaryFN() { * @type { string } */ const val = evt.target.value; + const section = qsA('mujs-section[data-name]', cfgpage); if (isEmpty(val)) { - dom.cl.remove(qsA('tr[data-engine]', tabbody), 'hidden'); - dom.cl.remove(qsA('mujs-section[data-name]', cfgpage), 'hidden'); + dom.cl.remove(container.toElem(), 'hidden'); + dom.cl.remove(section, 'hidden'); return; } const finds = new Set(); if (!dom.cl.has(cfgpage, 'hidden')) { const reg = new RegExp(val, 'gi'); - for (const elem of qsA('mujs-section[data-name]', cfgpage)) { + for (const elem of section) { if (!isElem(elem)) { continue; } @@ -3825,10 +3843,13 @@ function primaryFN() { finds.add(elem); } } - dom.cl.add(qsA('mujs-section[data-name]', cfgpage), 'hidden'); + dom.cl.add(section, 'hidden'); dom.cl.remove([...finds], 'hidden'); return; } + const cacheValues = container.toArr().filter(({ _mujs }) => { + return !finds.has(_mujs.root); + }); /** * @param {RegExpMatchArray} regExp * @param {keyof import("../typings/types.d.ts").GSForkQuery} key @@ -3836,43 +3857,29 @@ function primaryFN() { const ezQuery = (regExp, key) => { const q_value = val.replace(regExp, ''); const reg = new RegExp(q_value, 'gi'); - for (const v of userjsCache.values()) { - const elem = v._mujs.root; - if (!isElem(elem)) { - continue; - } - if (finds.has(elem)) { - continue; - } + for (const v of cacheValues) { let k = v[key]; if (typeof k === 'number') { k = `${v[key]}`; } if (k && k.match(reg)) { - finds.add(elem); + finds.add(v._mujs.root); } } }; if (val.match(/^(code_url|url):/)) { ezQuery(/^(code_url|url):/, 'code_url'); } else if (val.match(/^(author|users?):/)) { - const q_value = val.replace(/^(author|users?):/, ''); - const reg = new RegExp(q_value, 'gi'); - for (const v of userjsCache.values()) { - const elem = v._mujs.root; - if (!isElem(elem)) { - continue; - } - if (finds.has(elem)) { - continue; - } - if (v.users) { + const parts = /^[\w_]+:(.+)/.exec(val); + if (parts) { + const reg = new RegExp(parts[1], 'gi'); + for (const v of cacheValues.filter((v) => !isEmpty(v.users))) { for (const user of v.users) { for (const value of Object.values(user)) { if (typeof value === 'string' && value.match(reg)) { - finds.add(elem); + finds.add(v._mujs.root); } else if (typeof value === 'number' && `${value}`.match(reg)) { - finds.add(elem); + finds.add(v._mujs.root); } } } @@ -3889,96 +3896,52 @@ function primaryFN() { } else if (val.match(/^description:/)) { ezQuery(/^description:/, 'description'); } else if (val.match(/^(search_engine|engine):/)) { - const q_value = val.replace(/^(search_engine|engine):/, ''); - const reg = new RegExp(q_value, 'gi'); - for (const v of userjsCache.values()) { - const elem = v._mujs.root; - if (!isElem(elem)) { - continue; - } - if (finds.has(elem)) { - continue; - } - if (v._mujs.info.engine) { - for (const value of Object.values(v._mujs.info.engine)) { - if (typeof value === 'string' && value.match(reg)) { - finds.add(elem); - } + const parts = /^[\w_]+:(\w+)/.exec(val); + if (parts) { + const reg = new RegExp(parts[1], 'gi'); + for (const { _mujs } of cacheValues) { + if (!_mujs.info.engine.name.match(reg)) { + continue; } + finds.add(_mujs.root); } } } else if (val.match(/^filter:/)) { const parts = /^\w+:(.+)/.exec(val); if (parts) { const bsFilter = loadFilters(); - const p = parts[1].trim().toLocaleLowerCase(); - for (const [key, value] of Object.entries(cfg.filters)) { - const k = key.trim().toLocaleLowerCase(); - const v = value.name.trim().toLocaleLowerCase(); - if (p.includes(k) || p.includes(v)) { - const reg = bsFilter.get(value.name); - if (reg) { - [...userjsCache.values()].filter(({ name, users, _mujs }) => { - const elem = _mujs.root; - if (!isElem(elem)) { - return false; - } - if (finds.has(elem)) { - return false; - } - const strArr = [{ name }, ...users]; - const v = strArr.find((o) => o.name.match(reg)); - if (v) { - return false; - } - finds.add(elem); - return true; - }); + const filterType = bsFilter.get(parts[1].trim().toLocaleLowerCase()); + if (filterType) { + const { reg } = filterType; + for (const { name, users, _mujs } of cacheValues) { + if ([{ name }, ...users].find((o) => o.name.match(reg))) { + continue; } + finds.add(_mujs.root); } } } } else if (val.match(/^recommend:/)) { - for (const v of userjsCache.values()) { - const elem = v._mujs.root; - if (!isElem(elem)) { - continue; - } - if (finds.has(elem)) { - continue; - } - if (v.users.find(u => u.id === authorID)) { - finds.add(elem); - } else if (goodUserJS.includes(v.url)) { - finds.add(elem); - } else if (goodUserJS.includes(v.id)) { - finds.add(elem); + for (const { url, id, users, _mujs } of cacheValues) { + if ( + users.find((u) => u.id === authorID) || + goodUserJS.includes(url) || + goodUserJS.includes(id) + ) { + finds.add(_mujs.root); } } } else { const reg = new RegExp(val, 'gi'); - for (const v of userjsCache.values()) { - const elem = v._mujs.root; - if (!isElem(elem)) { - continue; - } - if (finds.has(elem)) { - continue; - } - if (v.name && v.name.match(reg)) { - finds.add(elem); - } - if (v.description && v.description.match(reg)) { - finds.add(elem); - } + for (const v of cacheValues) { + if (v.name && v.name.match(reg)) finds.add(v._mujs.root); + if (v.description && v.description.match(reg)) finds.add(v._mujs.root); const code_data = v._mujs.code.data; if (code_data) { const code_obj = new ParseUserJS(code_data); const meta = code_obj.parse_meta(code_data); for (const key of Object.keys(meta)) { - if (/name|desc/i.test(key) && key.match(reg)) { - finds.add(elem); - } + if (/name|desc/i.test(key) && key.match(reg)) finds.add(v._mujs.root); } } } @@ -3989,16 +3952,19 @@ function primaryFN() { ael(urlBar, 'change', (evt) => { evt.preventDefault(); const val = evt.target.value; - if (urlBar.placeholder === i18n$('newTab') && qs('mujs-tab.active', toolbar)) { - const tabElem = qs('mujs-tab.active', toolbar); - const tabHost = qs('mujs-host', tabElem); - if (val.startsWith(tab.protocal)) { + const tabElem = tab.getActive(); + if (urlBar.placeholder === i18n$('newTab') && tabElem) { + const tabHost = tabElem.firstElementChild; + if (tab.protoReg.test(val)) { + const createdTab = tab.getTab(val); tab.close(tabElem); - if (tab.hasTab(val)) { - tab.active(tab.Tab.get(val)); + if (createdTab) { + tab.active(createdTab); } else { tab.create(val); } + evt.target.placeholder = i18n$('search_placeholder'); + evt.target.value = ''; return; } else if (val === '*') { tabElem.dataset.host = val; @@ -4018,7 +3984,6 @@ function primaryFN() { tabHost.textContent = value; MUList.host = value; respHandles.build(); - return; } }); scheduler.postTask(makecfg, { priority: 'background' }); @@ -4044,20 +4009,19 @@ function primaryFN() { * @param { (this: F, doc: Document) => * } onDomReady */ const loadDOM = (onDomReady) => { - if (!isFN(onDomReady)) { - return; - } - if (document.readyState === 'interactive' || document.readyState === 'complete') { - onDomReady(document); - return; + if (isFN(onDomReady)) { + if (document.readyState === 'interactive' || document.readyState === 'complete') { + onDomReady(document); + } else { + document.addEventListener('DOMContentLoaded', (evt) => onDomReady(evt.target), { + once: true + }); + } } - document.addEventListener('DOMContentLoaded', (evt) => onDomReady(evt.target), { - once: true - }); }; -const init = async () => { - const stored = await StorageSystem.getValue('Config', DEFAULT_CONFIG); +const init = async (prefix = 'Config') => { + const stored = await StorageSystem.getValue(prefix, DEFAULT_CONFIG); cfg = { ...DEFAULT_CONFIG, ...stored @@ -4075,8 +4039,7 @@ const init = async () => { cause: 'loadDOM' }); } - trustedTypes.init(); - sleazyRedirect(); + container.redirect(); if (cfg.autoinject) container.inject(primaryFN, doc); diff --git a/src/sass/_main.scss b/src/sass/_main.scss index 7834a03..b4d429d 100644 --- a/src/sass/_main.scss +++ b/src/sass/_main.scss @@ -889,6 +889,7 @@ mujs-body { &[data-blacklist] { display: grid; grid-auto-flow: column; + &:not(.new-list) { grid-template-columns: repeat(2, 1fr); } diff --git a/src/typings/UserJS.d.ts b/src/typings/UserJS.d.ts index 1584f08..db953c1 100644 --- a/src/typings/UserJS.d.ts +++ b/src/typings/UserJS.d.ts @@ -19,6 +19,75 @@ export interface safeHandles { scheduler: typeof scheduler; } +export interface Translations { + createdby: string; + name: string; + daily_installs: string; + close: string; + filterA: string; + max: string; + min: string; + search: string; + search_placeholder: string; + install: string; + issue: string; + version_number: string; + updated: string; + total_installs: string; + ratings: string; + good: string; + ok: string; + bad: string; + created_date: string; + redirect: string; + filter: string; + dtime: string; + save: string; + reset: string; + preview_code: string; + saveFile: string; + newTab: string; + applies_to: string; + license: string; + no_license: string; + antifeatures: string; + userjs_fullscreen: string; + listing_none: string; + export_config: string; + export_theme: string; + import_config: string; + import_theme: string; + code_size: string; + prmpt_css: string; + userjs_inject: string; + userjs_close: string; + userjs_sync: string; + userjs_autoinject: string; + auto_fetch: string; +} + +export interface LanguageTranslations { + ar: Translations; + de: Translations; + en: Translations; + en_GB: Translations; + es: Translations; + fr: Translations; + ja: Translations; + nl: Translations; + pl: Translations; + ru: Translations; + zh: Translations; + zh_CN: Translations; + zh_TW: Translations; +} + +// export declare const translations: LanguageTranslations; + +export declare function i18n$( + key: string +): Translations[K] | 'Unknown'; + /** * Some sites will alter or remove document functions * To get around this we bind them to the `userjs` object @@ -56,6 +125,7 @@ export declare function getGMInfo(): typeof GM_info; export interface StorageSystem { prefix: string; + events: Set; /** * Alias of `window.localStorage.getItem` */ @@ -73,6 +143,10 @@ export interface StorageSystem { */ remove(key: K): void; + addListener(name: string, callback: VMScriptGMValueChangeCallback): number | void; + + attach(): void; + /** * Set value - Saves key to either GM managed storage or `window.localStorage` * @@ -134,18 +208,17 @@ export interface Container { shadowRoot?: ShadowRoot | HTMLElement; supported: boolean; frame: HTMLElement | HTMLIFrameElement; - cache: Map; + cache: Map< + string, + { + [engine: string]: GSForkQuery[]; + } + >; userjsCache: Map; root: HTMLElement; unsaved: boolean; isBlacklisted: boolean; rebuild: boolean; - counters: { - total: number; - [engine: string]: number; - }; opacityMin: string; opacityMax: string; Timeout: new () => Timeout; diff --git a/src/typings/types.d.ts b/src/typings/types.d.ts index 893ca62..3dda759 100644 --- a/src/typings/types.d.ts +++ b/src/typings/types.d.ts @@ -99,11 +99,38 @@ export type UserJSEngine = { query?: string; }; +export interface FilterLayout { + enabled: boolean; + name: string; + flag?: string; + regExp: string; +} + +export interface Filters extends FilterLayout { + reg: RegExp; + keyReg: RegExp; + valueReg: RegExp; +} + export type config = { + /** + * List sorting on load + */ + autoSort: string; + /** + * Fetch from engines on load + */ autofetch: boolean; + /** + * Inject list on load + */ autoinject: boolean; /** - * Sync config with UserScript manager + * Clear cache on tab close + */ + clearTabCache: boolean; + /** + * `UserScript:` Sync config with UserScript manager */ cache?: boolean; /** @@ -111,7 +138,7 @@ export type config = { */ codePreview: boolean; /** - * Fullscreen list on load + * `UserScript:` Fullscreen list on load */ autoexpand?: boolean; /** @@ -123,7 +150,7 @@ export type config = { */ sleazyredirect: boolean; /** - * Miliseconds before list closes + * `UserScript:` Miliseconds before list closes */ time?: number; /** @@ -177,40 +204,20 @@ export type config = { author: boolean; others: boolean; }; + /** + * Taken from https://greasyfork.org/scripts/12179 + */ filters: { - [name: string ]: { - enabled: boolean; - name: string; - flag?: string; - regExp: string; - }; - // 'Non-ASCII': { - // enabled: boolean; - // regExp: string; - // }; - // 'Non-Latin': { - // enabled: boolean; - // regExp: string; - // }; - // Games: { - // enabled: boolean; - // regExp: string; - // }; - // 'Social Networks': { - // enabled: boolean; - // regExp: string; - // }; - // Clutter: { - // enabled: boolean; - // regExp: string; - // }; + ASCII: FilterLayout; + Latin: FilterLayout; + Games: FilterLayout; + SocialNetworks: FilterLayout; + Clutter: FilterLayout; }; }; export declare function objToStr(obj: O): string; -export declare function strToURL(str: S): URL; - /** * Object is typeof `RegExp` */ @@ -251,9 +258,14 @@ export declare function isEmpty(obj: O): boolean; */ export declare function normalizeTarget( target: T, - toQuery: boolean, - root: Element | Document + toQuery?: boolean, + root?: Document | Element ): T[]; +// export declare function normalizeTarget( +// target: T, +// toQuery?: boolean, +// root?: Document | Element +// ): T[]; export declare function halt(evt: Event): void; @@ -311,7 +323,7 @@ declare global { export declare function ael( el: E, type: K, - listener: (this: E, ev: HTMLElementEventMap[K]) => any, + listener: EventListenerOrEventListenerObject, options?: AddEventListenerOptions | boolean ): void; @@ -350,9 +362,11 @@ export declare function make< A extends keyof HTMLElementTagNameMap[K] >( tagName: K, - cname?: string, + cname?: string | { + [key in A]: Record; + }, attrs?: { - [key in A]: unknown; + [key in A]: Record; } ): HTMLElementTagNameMap[K]; @@ -374,8 +388,8 @@ export interface dom { ): V | undefined; text(target: T, text?: V): string | null | undefined; cl: { - add(target: T, token: string | string[]): void; - remove(target: T, token: string | string[]): void; + add(target: T, token: string | string[]): boolean; + remove(target: T, token: string | string[]): boolean; toggle(target: T, token: string | string[], force?: boolean): boolean; has(target: T, token: string | string[]): boolean; }; From aedeb67257ca324676d51e8e7cda4c510852a1c8 Mon Sep 17 00:00:00 2001 From: Magic Date: Sun, 2 Mar 2025 12:16:55 -0800 Subject: [PATCH 05/28] Updated build environment Signed-off-by: Magic --- .env.example | 3 + README.md | 83 ++++--- dist/.env.example | 2 - eslint.config.js | 2 +- package.json | 96 +------- pnpm-lock.yaml | 145 ++++++++++- pnpm-workspace.yaml | 2 + tools/languageLoader.js | 54 ----- tools/userscript.js | 400 +------------------------------ utils/builder/README.md | 1 + utils/builder/package.json | 30 +++ utils/builder/src/index.d.ts | 56 +++++ utils/builder/src/index.js | 398 ++++++++++++++++++++++++++++++ utils/builder/typings/index.d.ts | 50 ++++ utils/i18n/README.md | 1 + utils/i18n/package.json | 24 ++ utils/i18n/src/index.js | 59 +++++ utils/i18n/typings/index.d.ts | 9 + utils/user.js/README.md | 1 + utils/user.js/package.json | 29 +++ utils/user.js/src/index.js | 6 + utils/user.js/typings/index.d.ts | 6 + 22 files changed, 870 insertions(+), 587 deletions(-) create mode 100644 .env.example delete mode 100644 dist/.env.example create mode 100644 pnpm-workspace.yaml delete mode 100644 tools/languageLoader.js create mode 100644 utils/builder/README.md create mode 100644 utils/builder/package.json create mode 100644 utils/builder/src/index.d.ts create mode 100644 utils/builder/src/index.js create mode 100644 utils/builder/typings/index.d.ts create mode 100644 utils/i18n/README.md create mode 100644 utils/i18n/package.json create mode 100644 utils/i18n/src/index.js create mode 100644 utils/i18n/typings/index.d.ts create mode 100644 utils/user.js/README.md create mode 100644 utils/user.js/package.json create mode 100644 utils/user.js/src/index.js create mode 100644 utils/user.js/typings/index.d.ts diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..5da5008 --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +JS_ENV="development" +JS_ROOT="./" +JS_i18n="../../../src/_locales" \ No newline at end of file diff --git a/README.md b/README.md index bf9d7a0..5ef775e 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Magic Userscript+ *A complete rewrite of [Userscript+ : Show Site All UserJS](https://github.com/jae-jae/Userscript-Plus)* -Finds available UserScripts for the current webpage, the power of [Greasy Fork](https://greasyfork.org) on the go! +Finds available UserScripts and UserStyles for the current webpage, the power of [Greasy Fork](https://greasyfork.org) on the go! [UserScript Changelog](https://github.com/magicoflolis/Userscript-Plus/blob/master/CHANGELOG.user.md) @@ -33,7 +33,7 @@ Finds available UserScripts for the current webpage, the power of [Greasy Fork]( * [Open UserJS](https://openuserjs.org/scripts/Magic/Magic_Userscript+_Show_Site_All_UserJS) - outdated * [GitHub Repo](https://github.com/magicoflolis/Userscript-Plus/blob/master/dist/magic-userjs.user.js?raw=1) -**Web Extension:** +**Web Extension (under construction):** *Firefox:* @@ -49,7 +49,7 @@ Works for desktop and mobile versions. Magic Userscript+ should be compatible with any Chromium-based browser -**(Not Recommended) Bookmarklet:** +**Bookmarklet (not recommended):** Save this URL as a bookmark, clicking it will cause the **UserScript version** to inject itself into the current webpage. @@ -59,37 +59,47 @@ javascript:(function(){['https://cdn.jsdelivr.net/gh/magicoflolis/Userscript-Plu ## Features -* Designed for mobile and desktop devices -* Support multiple languages - date formats will match your current language -* Query UserScripts from: - * [Greasy Fork](https://greasyfork.org) - * [Sleazy Fork](https://sleazyfork.org) - * [Open UserJS](https://openuserjs.org) ( limited availability, will read `Too many requests...` if limit is reached ) - * [GitHub](https://github.com/search?l=JavaScript&o=desc&q="==UserScript==") ( requires [Personal Access Token](https://github.com/settings/tokens), no permissions are required ) -* Customize the theme -* Import / export config and theme -* Search for UserScripts -* Filter UserScripts which do not match your current language -* Sort UserScripts, default sorting "Daily Installs" -* Preview UserScript code before install -* Built-in UserScript [Greasyfork Search with Sleazyfork Results include](https://greasyfork.org/scripts/23840) -* Save UserScript as a local file -* Highlight UserScripts created by the [author](https://greasyfork.org/users/166061) -* Highlight recommended UserScripts from the [author](https://greasyfork.org/users/166061) +* General: + * UI designed for mobile and desktop devices + * Multiple language support - date formats are based on your current language + * Import / export config and theme + * Customize theme UI +* Query UserScripts and UserStyles from: + * [Greasy Fork](https://greasyfork.org) - enabled by default + * [Sleazy Fork](https://sleazyfork.org) - disabled by default + * [Open UserJS](https://openuserjs.org) ( limited availability, will read `Too many requests...` if limit is reached ) - disabled by default + * [GitHub](https://github.com/search?l=JavaScript&o=desc&q="==UserScript==") ( requires [Personal Access Token](https://github.com/settings/tokens), no permissions are required ) - disabled by default +* Built-in UserScripts: + * [GreasyFork Bullshit Filter](https://greasyfork.org/scripts/12179) - disabled by default + * [Greasyfork Search with Sleazyfork Results include](https://greasyfork.org/scripts/23840) - disabled by default +* Automation: + * Fetch on load - query on page load +* Blacklist: + * Attempts to exclude certain hosts from being queried - localhost, bank, government, etc. +* Menu: + * Search for UserScripts - for shortcuts see [Wiki](https://github.com/magicoflolis/Userscript-Plus/blob/master/wiki/README.md) + * Filter UserScripts which do not match your current language + * Sort UserScripts, default sorting "Daily Installs" + * Preview UserScripts code before install + * Save UserScript as a local file + * UserScript highlights: + * UserScripts created by the [author](https://greasyfork.org/users/166061) - enabled by default + * UserScript recommendations - enabled by default **UserScript Features:** > Tested and compatible with [TamperMonkey](https://www.tampermonkey.net/) or [ViolentMonkey](https://violentmonkey.github.io/) -* Maximize, minimize, or exit the UserScript list -* Change the position of floating counter -* Sync config with UserScript manager or per host - -**Bookmarklet Features:** - -* Maximize, minimize, or exit the UserScript list -* Change the position of floating counter -* Separate config for every host +* General: + * Maximize, minimize, or close menu + * Sync config with UserScript manager or per host + * Customize timeout window - can be re-injected using your managers User Script Commands menu +* Automation: + * Inject on load - injects menu on page load + * Automatic fullscreen - maximizes menu when opened +* UserScript Commands via `GM_registerMenuCommand`: + * Inject Userscript+ - injects menu into the page + * Close Userscript+ - removes menu from the page ## Previews @@ -138,7 +148,7 @@ javascript:(function(){['https://cdn.jsdelivr.net/gh/magicoflolis/Userscript-Plu ## Build -Install [Node.js](https://nodejs.org/) and [pnpm](https://pnpm.io/). *The version of Node.js should match or be greater than the `"node"` key in `package.json`.* +Install [Node.js](https://nodejs.org/) and [pnpm](https://pnpm.io/) - *the version of Node.js should match or be greater than the `"node"` key in `package.json`.* ``` sh # Install dependencies @@ -147,9 +157,15 @@ $ pnpm i ### UserScript Version -**Desktop** - Developed in [ViolentMonkey](https://violentmonkey.github.io/), see [How to edit scripts with your favorite editor?](https://violentmonkey.github.io/posts/how-to-edit-scripts-with-your-favorite-editor/) +Before you begin, rename `.env.example` to `.env` + +**Recommened Testing Environments:** -**Mobile** - Developed in [FireFox Developer Edition](https://www.mozilla.org/firefox/developer/) "Responsive Design Mode" on desktop + [cromite](https://github.com/uazo/cromite) app on Android +* **Desktop:** any browser with [ViolentMonkey](https://violentmonkey.github.io/), see [How to edit scripts with your favorite editor?](https://violentmonkey.github.io/posts/how-to-edit-scripts-with-your-favorite-editor/) +* **Mobile:** + * Desktop: use "Responsive Design Mode(Ctrl+Shift+M)" on [FireFox Developer Edition](https://www.mozilla.org/firefox/developer/) or just [FireFox](https://www.mozilla.org/firefox/) + * Android: any browser that supports User Script or support for installing a User Script manager, I use [Cromite](https://github.com/uazo/cromite) + * IOS: any browser that supports User Script or support for installing a User Script manager ``` sh # Watch and compile to local HTTP server @@ -180,8 +196,7 @@ $ pnpm run webpack:FF ### Roadmap * Finish WebExtension -* Add sorting to the following: "Total installs", "Ratings", "Created date" -* Improve design of blacklist section. +* See TODO section in [UserScript Changelog](https://github.com/magicoflolis/Userscript-Plus/blob/master/CHANGELOG.user.md) ### Source Code diff --git a/dist/.env.example b/dist/.env.example deleted file mode 100644 index ca948fe..0000000 --- a/dist/.env.example +++ /dev/null @@ -1,2 +0,0 @@ -# Please do not change this .env variable -JS_ENV="production" diff --git a/eslint.config.js b/eslint.config.js index 68f464d..273b21a 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -79,7 +79,7 @@ export default [ } }, { - files: ['tools/*.js'], + files: ['tools/*.js', 'utils/**/*.js'], languageOptions: { ecmaVersion: 'latest', sourceType: 'module', diff --git a/package.json b/package.json index 2773e46..bb6b904 100644 --- a/package.json +++ b/package.json @@ -8,101 +8,13 @@ "bugs": { "url": "https://github.com/magicoflolis/Userscript-Plus/issues" }, - "userJS": { - "version": "7.4.0", - "name": "Magic Userscript+ : Show Site All UserJS", - "description": "Finds available userscripts for the current webpage.", - "bugs": "https://github.com/magicoflolis/Userscript-Plus/issues", - "homepage": "https://github.com/magicoflolis/Userscript-Plus", - "icon": "./src/img/icon_64.png", - "downloadURL": "https://github.com/magicoflolis/Userscript-Plus/raw/master/dist/magic-userjs.user.js", - "updateURL": "https://github.com/magicoflolis/Userscript-Plus/raw/master/dist/magic-userjs.meta.js", - "build": { - "source": { - "head": "./src/UserJS/header.js", - "body": "./src/UserJS/main.js", - "extras": { - "mainCSS": "./build/css/magicuserjs.css" - } - }, - "watch": { - "files": [ - "main.js", - "header.js", - "magicuserjs.css" - ], - "dirs": [ - "src/UserJS", - "build/css" - ] - }, - "paths": { - "dev": { - "fileName": "magic-userjs.dev", - "env": "./src/UserJS/.env", - "dir": "./web-server" - }, - "public": { - "fileName": "magic-userjs", - "env": "./dist/.env", - "dir": "./dist" - } - } - }, - "metadata": { - "compatible": [ - "chrome", - "firefox", - "edge", - "opera", - "safari" - ], - "connect": [ - "greasyfork.org", - "sleazyfork.org", - "github.com", - "githubusercontent.com", - "openuserjs.org" - ], - "grant": [ - "GM_addValueChangeListener", - "GM_addElement", - "GM_info", - "GM_getValue", - "GM_openInTab", - "GM_setValue", - "GM_registerMenuCommand", - "GM_removeValueChangeListener", - "GM_xmlhttpRequest", - "GM.addValueChangeListener", - "GM.addElement", - "GM.info", - "GM.getValue", - "GM.openInTab", - "GM.setValue", - "GM.registerMenuCommand", - "GM.removeValueChangeListener", - "GM.xmlHttpRequest" - ], - "exclude": [], - "include": [], - "exclude-match": [], - "match": [ - "https://*/*" - ], - "noframes": true, - "resource": {}, - "require": [], - "run-at": "document-start" - } - }, "type": "module", "scripts": { - "dev:UserJS": "concurrently \"node ./tools/userscript.js\" \"pnpm run dev:Webserver\" \"sass --no-source-map -s expanded -w ./src/sass:./build/css\" ", + "dev:UserJS": "concurrently \"dotenvx run -f .env --quiet -- node ./tools/userscript.js\" \"pnpm run dev:Webserver\" \"sass --no-source-map -s expanded -w ./src/sass:./build/css\"", "dev:FF": "concurrently \"sass --embed-sources -s expanded -w ./src/sass:./build/firefox/css\" \"pnpm run webpack:FF\"", "dev:Cr": "concurrently \"sass --embed-sources -s expanded -w ./src/sass:./build/chrome/css\" \"pnpm run webpack:Cr\"", "dev:Webserver": "http-server ./web-server -p 9090 -s --no-dotfiles -c-1", - "pub:UserJS": "concurrently \"sass --no-source-map -s expanded ./src/sass:./build/css\" \"node -r dotenv/config ./tools/userscript.js dotenv_config_path=./dist/.env\"", + "pub:UserJS": "concurrently \"sass --no-source-map -s expanded ./src/sass:./build/css\" \"dotenvx run --env JS_ENV=production -f .env --quiet -- node ./tools/userscript.js\"", "pub:FF": "webpack --mode production --config=tools/webpack.config.js --env brws=firefox", "pub:Cr": "webpack --mode production --config=tools/webpack.config.js --env brws=chrome", "webpack:Cr": "webpack --progress --mode development --config=tools/webpack.config.js --env brws=chrome", @@ -110,6 +22,7 @@ "web-run:firefox-android": "web-ext run --config=./tools/web-ext.js -t firefox-android --firefox-apk org.mozilla.firefox" }, "devDependencies": { + "@dotenvx/dotenvx": "^1.38.3", "@eslint/js": "^9.20.0", "@swc/cli": "^0.6.0", "@swc/core": "^1.10.16", @@ -127,7 +40,6 @@ "copy-webpack-plugin": "^12.0.2", "crx3": "^1.1.3", "css-loader": "^7.1.2", - "dotenv": "^16.4.7", "eslint": "^9.20.1", "eslint-config-prettier": "^10.0.1", "globals": "^15.15.0", @@ -140,7 +52,7 @@ "swc-loader": "^0.2.6", "terser-webpack-plugin": "^5.3.11", "typescript": "^5.7.3", - "watchpack": "^2.4.2", + "user.js": "workspace:^", "web-ext": "^8.4.0", "webpack": "^5.98.0", "webpack-cli": "^6.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 546bb2b..d834f60 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: devDependencies: + '@dotenvx/dotenvx': + specifier: ^1.38.3 + version: 1.38.3 '@eslint/js': specifier: ^9.20.0 version: 9.20.0 @@ -59,9 +62,6 @@ importers: css-loader: specifier: ^7.1.2 version: 7.1.2(webpack@5.98.0) - dotenv: - specifier: ^16.4.7 - version: 16.4.7 eslint: specifier: ^9.20.1 version: 9.20.1 @@ -98,9 +98,9 @@ importers: typescript: specifier: ^5.7.3 version: 5.7.3 - watchpack: - specifier: ^2.4.2 - version: 2.4.2 + user.js: + specifier: workspace:^ + version: link:utils/user.js web-ext: specifier: ^8.4.0 version: 8.4.0 @@ -114,6 +114,29 @@ importers: specifier: ^6.0.1 version: 6.0.1 + utils/builder: + dependencies: + '@userjs/i18n': + specifier: workspace:^ + version: link:../i18n + minimist: + specifier: ^1.2.8 + version: 1.2.8 + watchpack: + specifier: ^2.4.2 + version: 2.4.2 + + utils/i18n: {} + + utils/user.js: + dependencies: + '@userjs/builder': + specifier: workspace:^ + version: link:../builder + '@userjs/i18n': + specifier: workspace:^ + version: link:../i18n + packages: '@aashutoshrathi/word-wrap@1.2.6': @@ -156,6 +179,16 @@ packages: resolution: {integrity: sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==} engines: {node: '>=14.17.0'} + '@dotenvx/dotenvx@1.38.3': + resolution: {integrity: sha512-6tquYDfAiJbgQbYwWfL0jJHiUumY5EiFXVswk9sTwn5lWICMwOPmMOrM9TEVLzesfNMYwDyUiMp5WAA6yXs+SQ==} + hasBin: true + + '@ecies/ciphers@0.2.2': + resolution: {integrity: sha512-ylfGR7PyTd+Rm2PqQowG08BCKA22QuX8NzrL+LxAAvazN10DMwdJ2fWwAzRj05FI/M8vNFGm3cv9Wq/GFWCBLg==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + peerDependencies: + '@noble/ciphers': ^1.0.0 + '@eslint-community/eslint-utils@4.4.0': resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -263,6 +296,18 @@ packages: '@mdn/browser-compat-data@5.6.31': resolution: {integrity: sha512-E/X4YlErVjBCMvaJbqD2Jb0B/Z+TQJyw4vN6q98iit05RLW9VEcsedaTiL81BAbYF9GICn/KpFGE9dMJi66Ydw==} + '@noble/ciphers@1.2.1': + resolution: {integrity: sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.8.1': + resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.1': + resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + engines: {node: ^14.21.3 || >=16} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -859,6 +904,10 @@ packages: resolution: {integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==} engines: {node: '>=8.0.0'} + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + commander@12.1.0: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} @@ -1054,6 +1103,10 @@ packages: resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} engines: {node: '>=12'} + eciesjs@0.4.14: + resolution: {integrity: sha512-eJAgf9pdv214Hn98FlUzclRMYWF7WfoLlkS9nWMTm1qcCwn6Ad4EGD9lr9HXMBfSrZhYQujRE+p0adPRkctC6A==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + electron-to-chromium@1.5.80: resolution: {integrity: sha512-LTrKpW0AqIuHwmlVNV+cjFYTnXtM9K37OGhpe0ZI10ScPSxqVSryZHIY3WnCS5NSYbBODRTZyhRMS2h5FAEqAw==} @@ -1244,6 +1297,14 @@ packages: fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + fdir@6.4.3: + resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -1476,6 +1537,10 @@ packages: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} engines: {node: '>= 4'} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + image-size@1.2.0: resolution: {integrity: sha512-4S8fwbO6w3GeCVN6OPtA9I5IGKkcDMPcKndtUlpJuCwu7JLjtj7JZpwqLuyY2nrmQT3AWsCJLSKPsc2mPBSl3w==} engines: {node: '>=16.x'} @@ -1627,6 +1692,10 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + isobject@3.0.1: resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} engines: {node: '>=0.10.0'} @@ -1872,6 +1941,10 @@ packages: object-inspect@1.12.3: resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + object-treeify@1.1.33: + resolution: {integrity: sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==} + engines: {node: '>= 10'} + on-exit-leak-free@2.1.0: resolution: {integrity: sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==} @@ -1994,6 +2067,10 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + pino-abstract-transport@1.2.0: resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} @@ -2784,6 +2861,11 @@ packages: engines: {node: '>= 8'} hasBin: true + which@4.0.0: + resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} + engines: {node: ^16.13.0 || >=18.0.0} + hasBin: true + widest-line@5.0.0: resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} engines: {node: '>=18'} @@ -2903,6 +2985,22 @@ snapshots: '@discoveryjs/json-ext@0.6.3': {} + '@dotenvx/dotenvx@1.38.3': + dependencies: + commander: 11.1.0 + dotenv: 16.4.7 + eciesjs: 0.4.14 + execa: 5.1.1 + fdir: 6.4.3(picomatch@4.0.2) + ignore: 5.3.2 + object-treeify: 1.1.33 + picomatch: 4.0.2 + which: 4.0.0 + + '@ecies/ciphers@0.2.2(@noble/ciphers@1.2.1)': + dependencies: + '@noble/ciphers': 1.2.1 + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': dependencies: eslint: 8.57.1 @@ -3021,6 +3119,14 @@ snapshots: '@mdn/browser-compat-data@5.6.31': {} + '@noble/ciphers@1.2.1': {} + + '@noble/curves@1.8.1': + dependencies: + '@noble/hashes': 1.7.1 + + '@noble/hashes@1.7.1': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3682,6 +3788,8 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 + commander@11.1.0: {} + commander@12.1.0: {} commander@2.20.3: {} @@ -3866,6 +3974,13 @@ snapshots: dotenv@16.4.7: {} + eciesjs@0.4.14: + dependencies: + '@ecies/ciphers': 0.2.2(@noble/ciphers@1.2.1) + '@noble/ciphers': 1.2.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + electron-to-chromium@1.5.80: {} emoji-regex@10.4.0: {} @@ -4105,6 +4220,10 @@ snapshots: dependencies: pend: 1.2.0 + fdir@6.4.3(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + file-entry-cache@6.0.1: dependencies: flat-cache: 3.0.4 @@ -4352,6 +4471,8 @@ snapshots: ignore@5.2.4: {} + ignore@5.3.2: {} + image-size@1.2.0: dependencies: queue: 6.0.2 @@ -4458,6 +4579,8 @@ snapshots: isexe@2.0.0: {} + isexe@3.1.1: {} + isobject@3.0.1: {} jest-worker@27.5.1: @@ -4606,7 +4729,7 @@ snapshots: mkdirp@0.5.6: dependencies: - minimist: 1.2.7 + minimist: 1.2.8 mri@1.2.0: {} @@ -4672,6 +4795,8 @@ snapshots: object-inspect@1.12.3: {} + object-treeify@1.1.33: {} + on-exit-leak-free@2.1.0: {} once@1.4.0: @@ -4785,6 +4910,8 @@ snapshots: picomatch@2.3.1: {} + picomatch@4.0.2: {} + pino-abstract-transport@1.2.0: dependencies: readable-stream: 4.3.0 @@ -5557,6 +5684,10 @@ snapshots: dependencies: isexe: 2.0.0 + which@4.0.0: + dependencies: + isexe: 3.1.1 + widest-line@5.0.0: dependencies: string-width: 7.2.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..9a82b7a --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - 'utils/*' diff --git a/tools/languageLoader.js b/tools/languageLoader.js deleted file mode 100644 index 50e8861..0000000 --- a/tools/languageLoader.js +++ /dev/null @@ -1,54 +0,0 @@ -import { readdir, readFile, stat } from 'node:fs/promises'; -import { URL, fileURLToPath } from 'node:url'; - -/** - * Loads all the structures in the provided directory. - * - * @template T - * @param {import('node:fs').PathLike} dir - The directory to load the structures from - * @param {boolean} recursive - Whether to recursively load the structures in the directory - * @returns {Promise} - */ -export async function loadLanguages(dir, recursive = true) { - // Get the stats of the directory - const statDir = await stat(dir); - - // If the provided directory path is not a directory, throw an error - if (!statDir.isDirectory()) { - throw new Error(`The directory '${dir}' is not a directory.`); - } - - // Get all the files in the directory - const files = await readdir(dir); - - // Create an empty array to store the structures - /** @type {T[]} */ - const structures = []; - - // Loop through all the files in the directory - for (const file of files) { - // Get the stats of the file - const statFile = await stat(new URL(`${dir}/${file}`)); - - // If the file is a directory and recursive is true, recursively load the structures in the directory - if (statFile.isDirectory() && recursive) { - structures.push(...(await loadLanguages(new URL(`${dir}/${file}`), recursive))); - continue; - } - - if (!file.endsWith('.json')) { - continue; - } - - const filePath = fileURLToPath(`${dir}/${file}`); - const reg = /_locales\\(.*?)\\messages\.json/g.exec(filePath); - if (reg) { - const structure = await readFile(filePath, 'utf-8'); - structures.push({ - [reg[1]]: JSON.parse(structure.toString('utf-8')) - }); - } - } - - return structures; -} diff --git a/tools/userscript.js b/tools/userscript.js index 2bb3a73..c7c6d0d 100644 --- a/tools/userscript.js +++ b/tools/userscript.js @@ -1,398 +1,4 @@ -import path from 'path'; -import { URL } from 'node:url'; -import fs from 'node:fs'; -import dotenv from 'dotenv'; -import Watchpack from 'watchpack'; -import { loadLanguages } from './languageLoader.js'; +'use strict'; +import build from 'user.js'; -/** - * @typedef { import('../package.json') } CFG - */ - -const replaceTemplate = /\[\[(.*?)\]\]/g; -const metaStr = '[[metadata]]'; - -const log = (...msg) => { - console.log('[LOG]', ...msg); -}; -const err = (...msg) => { - console.error('[ERROR]', ...msg); -}; -/** - * Object is typeof `object` / JSON Object - * @template O - * @param { O } obj - * @returns { boolean } - */ -const isObj = (obj) => { - /** @type { string } */ - const s = Object.prototype.toString.call(obj); - return s.includes('Object'); -}; -/** - * Object is `null` or `undefined` - * @template O - * @param { O } obj - * @returns { boolean } - */ -const isNull = (obj) => { - return Object.is(obj, null) || Object.is(obj, undefined); -}; -/** - * Object is Blank - * @template O - * @param { O } obj - * @returns { boolean } - */ -const isBlank = (obj) => { - return ( - (typeof obj === 'string' && Object.is(obj.trim(), '')) || - ((obj instanceof Set || obj instanceof Map) && Object.is(obj.size, 0)) || - (Array.isArray(obj) && Object.is(obj.length, 0)) || - (isObj(obj) && Object.is(Object.keys(obj).length, 0)) - ); -}; -/** - * Object is Empty - * @template O - * @param { O } obj - * @returns { boolean } - */ -const isEmpty = (obj) => { - return isNull(obj) || isBlank(obj); -}; -/** - * @template { string | { msg: string; } } T - * @template D - * @param { T } template - * @param { D } data - */ -const nano = (template, data) => { - if (typeof template === 'string') { - return template.replace(replaceTemplate, (_match, key) => { - const keys = key.split('.'); - let v = data[keys.shift()]; - for (const i in keys.length) v = v[keys[i]]; - return isEmpty(v) ? '' : v; - }); - } - return ''; -}; -/** - * @param {import('node:fs').PathLike} filePath - * @param {string} encoding - */ -const canAccess = async (filePath, encoding = 'utf-8') => { - const testAccess = await fs.promises.access( - filePath, - fs.promises.constants.R_OK | fs.promises.constants.W_OK - ); - if (isNull(testAccess)) { - const data = await fs.promises.readFile(filePath, encoding); - return data.toString(encoding); - } - return { - msg: `Cannot access provided filePath: ${filePath}` - }; -}; -/** - * @param {import('node:fs').PathLike} filePath - * @param {string} encoding - */ -const fileToJSON = async (filePath, encoding = 'utf-8') => { - const testAccess = await canAccess(filePath, encoding); - if (isObj(testAccess)) { - throw new Error(testAccess.msg); - } - return JSON.parse(testAccess); -}; -/** - * @param {import('node:fs').PathLike} destinationFilePath - * @param data - */ -const writeUserJS = async (destinationFilePath, data) => { - return await fs.promises.writeFile(destinationFilePath, data); -}; -const toTime = () => { - return new Intl.DateTimeFormat('default', { - hour: 'numeric', - minute: 'numeric', - second: 'numeric', - fractionalSecondDigits: 3 - }).format(new Date()); -}; -/** - * @type { Map } - */ -const dataMap = new Map(); -const compareArrays = (a, b) => - a.length === b.length && a.every((element, index) => element === b[index]); -/** - * @template {string} K - * @template V - * @param {K} key - * @param {...V} values - */ -const addTo = (key, ...values) => { - if (values.length === 0) { - return ''; - } - if (dataMap.has(key)) { - if (compareArrays(dataMap.get(key), values)) { - return dataMap.get(key); - } - } - dataMap.set(key, values); - return dataMap.get(key); -}; -const filterData = [ - 'name', - 'description', - 'author', - 'icon', - 'version', - 'url', - 'homepage', - 'bugs', - 'license' -]; - -(async () => { - /** @type { dotenv.DotenvConfigOutput } */ - let result = {}; - try { - /** - * @type { CFG } - */ - const jsonData = await fileToJSON('./package.json'); - if (!isObj(jsonData)) { - throw new Error('"jsonData" must be an object.'); - } - if (!jsonData.userJS) { - throw new Error('Missing "userJS" key'); - } - const userJS = jsonData.userJS; - const { build } = userJS; - - result = dotenv.config({ - path: isEmpty(process.env.JS_ENV) ? build.paths.dev.env : build.paths.public.env - }); - if (result.error) { - throw result.error; - } - if (isNull(result.parsed.JS_ENV)) { - dotenv.populate( - result.parsed, - { - JS_ENV: 'development' - }, - { override: true, debug: true } - ); - } - const env = result.parsed; - const js_env = env.JS_ENV === 'development'; - const dp = js_env ? 'dev' : 'public'; - const compileMetadata = () => { - const metaData = []; - for (const [key, value] of Object.entries(userJS.metadata)) { - if (Array.isArray(value)) { - for (const v of value) { - metaData.push(`// @${key} ${v}`); - } - } else if (isObj(value)) { - for (const [k, v] of Object.entries(value)) { - metaData.push(`// @${key} ${k} ${v}`); - } - } else if (typeof value === 'boolean') { - if (value === true) { - metaData.push(`// @${key}`); - } - } else { - metaData.push(`// @${key} ${value}`); - } - } - return metaData.join('\n'); - }; - const buildUserJS = async () => { - try { - const lngList = await loadLanguages(new URL('../src/_locales', import.meta.url)); - const transformLanguages = () => { - const resp = {}; - for (const obj of lngList) { - for (const [k, v] of Object.entries(obj)) { - const o = {}; - for (const [key, value] of Object.entries(v)) { - if (key.startsWith('ext')) { - continue; - } - if (/userjs_(name|description)/i.test(key)) { - continue; - } - if (isEmpty(value.message)) { - continue; - } - o[key] = value.message; - } - resp[k] = o; - } - } - return JSON.stringify(resp, null, ' '); - }; - const compileLanguage = (type = 'userjs_name') => { - const resp = []; - for (const obj of lngList) { - for (const [k, v] of Object.entries(obj)) { - if (v[type]) { - if (isEmpty(v[type].message)) { - continue; - } - if (k.startsWith('en')) { - continue; - } - const t = type.toLowerCase().replace('userjs_', ''); - if (type === 'userjs_name') { - resp.push( - `// @${t}:${k.replace('_', '-')} ${js_env ? '[Dev] ' : ''}${v[type].message}` - ); - } else { - resp.push(`// @${t}:${k.replace('_', '-')} ${v[type].message}`); - } - } - } - } - return resp; - }; - const getData = () => { - for (const [k, v] of Object.entries(userJS)) { - if (typeof v !== 'string') { - continue; - } - if (k === 'name') { - addTo( - k, - `// @${k} ${js_env ? '[Dev] ' : ''}${v}`, - ...compileLanguage('userjs_name') - ); - } else if (k === 'description') { - addTo(k, `// @${k} ${v}`, ...compileLanguage('userjs_description')); - } else if (k === 'author') { - addTo(k, `// @${k} ${v}`); - } else if (k === 'icon') { - const buff = new Buffer.from(fs.readFileSync(v)); - const base64data = buff.toString('base64'); - if (v.endsWith('.png')) { - addTo(k, `// @${k} data:image/png;base64,${base64data}`); - } else if (v.endsWith('.svg')) { - addTo(k, `// @${k} data:image/svg+xml;base64,${base64data}`); - } - } else if (k === 'downloadURL') { - addTo(k, `// @downloadURL ${v}`); - } else if (k === 'updateURL') { - addTo(k, `// @updateURL ${v}`); - } else if (k === 'url') { - addTo(k, `// @downloadURL ${v}`, `// @updateURL ${v}`); - } else if (k === 'version') { - addTo(k, `// @${k} ${js_env ? +new Date() : v}`); - } else if (k === 'homepage') { - addTo(k, `// @namespace ${v}`, `// @homepageURL ${v}`); - } else if (k === 'bugs') { - addTo(k, `// @supportURL ${v}`); - } else if (k === 'license') { - addTo(k, `// @${k} ${v}`); - } else { - addTo(k, v); - } - } - for (const [k, v] of Object.entries(jsonData)) { - if (typeof v !== 'string') { - continue; - } - if (!filterData.includes(k)) { - continue; - } - if (dataMap.has(k)) { - continue; - } - if (k === 'license') { - addTo(k, `// @${k} ${v}`); - } else if (k === 'author') { - addTo(k, `// @${k} ${v}`); - } - } - if (userJS.metadata) { - addTo('metaData', compileMetadata()); - } - return [...dataMap.values()].flat().join('\n'); - }; - const userJSHeader = `// ==UserScript==\n${getData()}\n// ==/UserScript==`; - const headerFile = await canAccess(build.source.head); - const mainFile = await canAccess(build.source.body); - const nanoCFG = { - metadata: userJSHeader, - languageList: transformLanguages(), - code: mainFile - }; - if (build.source.extras) { - for (const [k, v] of Object.entries(build.source.extras)) { - const extraFile = await canAccess(v); - if (typeof extraFile === 'string') { - nanoCFG[k] = extraFile; - } - } - } - const outFile = `${build.paths[dp].dir}/${build.paths[dp].fileName}.user.js`; - await writeUserJS(outFile, nano(headerFile, nanoCFG)); - log('UserJS Build:', { - path: outFile, - time: toTime() - }); - if (!js_env) { - const outMeta = `${build.paths[dp].dir}/${build.paths[dp].fileName}.meta.js`; - await writeUserJS(outMeta, nano(metaStr, { metadata: userJSHeader })); - log('UserJS Metadata:', { - path: outMeta, - time: toTime() - }); - } - } catch (ex) { - err(ex); - } - }; - //#region Start Process - log(`Node ENV: ${env.JS_ENV}`); - - if (js_env) { - const wp = new Watchpack(); - let changed = new Set(); - wp.watch(build.watch.files, build.watch.dirs); - wp.on('change', (changedFile, mtime) => { - if (mtime === null) { - changed.delete(changedFile); - } else { - changed.add(changedFile); - } - }); - wp.on('aggregated', async () => { - // Filter out files that start with a dot from detected changes - // (as they are hidden files or temp files created by an editor). - const changes = Array.from(changed).filter((filePath) => { - return !path.basename(filePath).startsWith('.'); - }); - changed = new Set(); - - if (changes.length === 0) { - return; - } - - await buildUserJS(); - }); - return; - } - await buildUserJS(); - - process.exit(0); - //#endregion - } catch (ex) { - err(ex); - } -})(); +build(); diff --git a/utils/builder/README.md b/utils/builder/README.md new file mode 100644 index 0000000..b69b879 --- /dev/null +++ b/utils/builder/README.md @@ -0,0 +1 @@ +# UserScript Builder diff --git a/utils/builder/package.json b/utils/builder/package.json new file mode 100644 index 0000000..c42ffd6 --- /dev/null +++ b/utils/builder/package.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://json.schemastore.org/package.json", + "name": "@userjs/builder", + "description": "Create a UserScript", + "version": "1.0.0", + "license": "MIT", + "type": "module", + "main": "./src/index.js", + "types": "./typings/index.d.ts", + "exports": { + ".": { + "import": { + "types": "./typings/index.d.ts", + "default": "./src/index.js" + } + } + }, + "directories": { + "lib": "src" + }, + "files": [ + "src", + "typings" + ], + "dependencies": { + "@userjs/i18n": "workspace:^", + "minimist": "^1.2.8", + "watchpack": "^2.4.2" + } +} diff --git a/utils/builder/src/index.d.ts b/utils/builder/src/index.d.ts new file mode 100644 index 0000000..1ca7e43 --- /dev/null +++ b/utils/builder/src/index.d.ts @@ -0,0 +1,56 @@ +import { PathLike } from 'node:fs'; + +/** + * Loads all the structures in the provided directory. + * + * @param dir - The directory to load the structures from + * @param recursive - Whether to recursively load the structures in the directory + */ +export declare function loadLanguages(dir: PathLike, recursive?: boolean): Promise; +export declare function build(): Promise; +export interface UserJS { + name: string; + description: string; + version: string; + license?: string; + bugs?: URL; + homepage?: URL; + icon?: PathLike; + downloadURL?: URL; + updateURL?: URL; + url_source?: URL; + url?: URL; + build: { + source: { + languageList: string; + [source: string]: PathLike; + }; + watch: { + files: string[]; + dirs: PathLike[]; + }; + paths: { + fileName: string; + dir: PathLike; + dev?: { + fileName?: string; + dir?: PathLike; + }; + }; + }; + metadata: { + compatible: string[]; + connect: string[]; + grant: string[]; + exclude: string[]; + include: string[]; + 'exclude-match': string[]; + match: string[]; + noframes: boolean; + resource: { + [name: string]: string; + }; + require: string[]; + 'run-at': 'document-start' | 'document-body' | 'document-end' | 'document-idle'; + }; +} diff --git a/utils/builder/src/index.js b/utils/builder/src/index.js new file mode 100644 index 0000000..4f8f350 --- /dev/null +++ b/utils/builder/src/index.js @@ -0,0 +1,398 @@ +'use strict'; +import path from 'path'; +import { URL } from 'node:url'; +import fs from 'node:fs'; +import Watchpack from 'watchpack'; +import minimist from 'minimist'; +import { loadLanguages } from '@userjs/i18n'; + +/** + * @typedef { import('../typings/index.d.ts').UserJS } CFG + */ + +const replaceTemplate = /\[\[(.*?)\]\]/g; +const metaStr = '[[metadata]]'; + +const log = (...msg) => { + console.log('[LOG]', ...msg); +}; +const err = (...msg) => { + console.error('[ERROR]', ...msg); +}; +/** + * Object is typeof `object` / JSON Object + * @template O + * @param { O } obj + * @returns { boolean } + */ +const isObj = (obj) => { + /** @type { string } */ + const s = Object.prototype.toString.call(obj); + return s.includes('Object'); +}; +/** + * Object is `null` or `undefined` + * @template O + * @param { O } obj + * @returns { boolean } + */ +const isNull = (obj) => { + return Object.is(obj, null) || Object.is(obj, undefined); +}; +/** + * Object is Blank + * @template O + * @param { O } obj + * @returns { boolean } + */ +const isBlank = (obj) => { + return ( + (typeof obj === 'string' && Object.is(obj.trim(), '')) || + ((obj instanceof Set || obj instanceof Map) && Object.is(obj.size, 0)) || + (Array.isArray(obj) && Object.is(obj.length, 0)) || + (isObj(obj) && Object.is(Object.keys(obj).length, 0)) + ); +}; +/** + * Object is Empty + * @template O + * @param { O } obj + * @returns { boolean } + */ +const isEmpty = (obj) => { + return isNull(obj) || isBlank(obj); +}; +/** + * @template { string | { msg: string; } } T + * @template D + * @param { T } template + * @param { D } data + */ +const nano = (template, data) => { + if (typeof template === 'string') { + return template.replace(replaceTemplate, (_match, key) => { + const keys = key.split('.'); + let v = data[keys.shift()]; + for (const i in keys.length) v = v[keys[i]]; + return isEmpty(v) ? '' : v; + }); + } + return ''; +}; +/** + * @param {import('node:fs').PathLike} filePath + * @param {string} encoding + */ +const canAccess = async (filePath, encoding = 'utf-8') => { + const testAccess = await fs.promises.access( + filePath, + fs.promises.constants.R_OK | fs.promises.constants.W_OK + ); + if (isNull(testAccess)) { + const data = await fs.promises.readFile(filePath, encoding); + return data.toString(encoding); + } + return { + msg: `Cannot access provided filePath: ${filePath}` + }; +}; +/** + * @param {import('node:fs').PathLike} filePath + * @param {string} encoding + */ +const fileToJSON = async (filePath, encoding = 'utf-8') => { + const testAccess = await canAccess(filePath, encoding); + if (isObj(testAccess)) { + throw new Error(testAccess.msg); + } + return JSON.parse(testAccess); +}; +/** + * @param {import('node:fs').PathLike} destinationFilePath + * @param data + */ +const writeUserJS = async (destinationFilePath, data) => { + return await fs.promises.writeFile(destinationFilePath, data); +}; +const toTime = () => { + return new Intl.DateTimeFormat('default', { + hour: 'numeric', + minute: 'numeric', + second: 'numeric', + fractionalSecondDigits: 3 + }).format(new Date()); +}; +/** + * @type { Map } + */ +const dataMap = new Map(); +const compareArrays = (a, b) => + a.length === b.length && a.every((element, index) => element === b[index]); +/** + * @template {string} K + * @template V + * @param {K} key + * @param {...V} values + */ +const addTo = (key, ...values) => { + if (values.length === 0) { + return ''; + } + if (dataMap.has(key)) { + if (compareArrays(dataMap.get(key), values)) { + return dataMap.get(key); + } + } + dataMap.set(key, values); + return dataMap.get(key); +}; + +async function build() { + try { + const getEnv = () => { + const argv = minimist(process.argv.slice(2)); + if (argv.JS_ROOT && argv.JS_ENV) { + return { + JS_ROOT: argv.JS_ROOT, + JS_ENV: argv.JS_ENV, + JS_i18n: `${argv.JS_ROOT}src/_locales` + }; + } + return process.env; + }; + const { JS_ROOT, JS_ENV, JS_i18n } = getEnv(); + const jsonRecords = await Promise.all([ + // fileToJSON('./package.json').then(({ userJS }) => { + // return userJS ?? {}; + // }), + fileToJSON('./UserJS.json') + .then((userJS) => { + return userJS ?? {}; + }) + .catch(() => { + return {}; + }) + ]); + if (isEmpty(jsonRecords)) + throw new Error('"UserJS.json" not found + no "userJS" key in package.json'); + /** + * @type { CFG } + */ + const userJS = {}; + for (const r of jsonRecords) Object.assign(userJS, r); + const isDev = isEmpty(JS_ENV) || JS_ENV === 'development'; + const buildUserJS = async () => { + try { + const i18nList = await loadLanguages(new URL(JS_i18n ?? `${JS_ROOT}src/_locales`, import.meta.url)); + const compileLanguage = (type = 'userjs_name') => { + const resp = []; + for (const obj of i18nList) { + for (const [k, v] of Object.entries(obj)) { + if (v[type]) { + if (isEmpty(v[type].message)) { + continue; + } + if (k.startsWith('en')) { + continue; + } + const t = type.toLowerCase().replace('userjs_', ''); + if (type === 'userjs_name') { + resp.push( + `// @${t}:${k.replace('_', '-')} ${isDev ? '[Dev] ' : ''}${v[type].message}` + ); + } else { + resp.push(`// @${t}:${k.replace('_', '-')} ${v[type].message}`); + } + } + } + } + return resp; + }; + const compileData = () => { + if (isDev && !isEmpty(dataMap)) { + addTo('version', `// @version ${+new Date()}`); + return `// ==UserScript==\n${[...dataMap.values()].flat().join('\n')}\n// ==/UserScript==`; + } + for (const [k, v] of Object.entries(userJS)) { + if (k === 'metadata') { + const metaData = []; + for (const [key, value] of Object.entries(v)) { + if (Array.isArray(value)) { + for (const v of value) { + metaData.push(`// @${key} ${v}`); + } + } else if (isObj(value)) { + for (const [k, v] of Object.entries(value)) { + metaData.push(`// @${key} ${k} ${v}`); + } + } else if (typeof value === 'boolean') { + if (value === true) { + metaData.push(`// @${key}`); + } + } else { + metaData.push(`// @${key} ${value}`); + } + } + addTo('metaData', metaData.join('\n')); + } + if (typeof v !== 'string') { + continue; + } + if (k === 'name') { + addTo( + k, + `// @${k} ${isDev ? '[Dev] ' : ''}${v}`, + ...compileLanguage('userjs_name') + ); + } else if (k === 'description') { + addTo(k, `// @${k} ${v}`, ...compileLanguage('userjs_description')); + } else if (k === 'author') { + addTo(k, `// @${k} ${v}`); + } else if (k === 'icon') { + if (v.startsWith('.') || v.startsWith('/')) { + const buff = new Buffer.from(fs.readFileSync(v)); + const base64data = buff.toString('base64'); + if (v.endsWith('.png')) { + addTo(k, `// @${k} data:image/png;base64,${base64data}`); + } else if (v.endsWith('.svg')) { + addTo(k, `// @${k} data:image/svg+xml;base64,${base64data}`); + } + } else { + addTo(k, `// @${k} ${v}`); + } + } else if (k === 'downloadURL') { + addTo(k, `// @downloadURL ${v}`); + } else if (k === 'updateURL') { + addTo(k, `// @updateURL ${v}`); + } else if (k === 'url_source') { + addTo(k, `// @url_source ${v}`); + } else if (k === 'url') { + addTo(k, `// @downloadURL ${v}`, `// @updateURL ${v}`); + } else if (k === 'version') { + addTo(k, `// @${k} ${isDev ? +new Date() : v}`); + } else if (k === 'homepage') { + addTo(k, `// @namespace ${v}`, `// @homepageURL ${v}`); + } else if (k === 'bugs') { + addTo(k, `// @supportURL ${v}`); + } else if (k === 'license') { + addTo(k, `// @${k} ${v}`); + } else { + addTo(k, v); + } + } + return `// ==UserScript==\n${[...dataMap.values()].flat().join('\n')}\n// ==/UserScript==`; + }; + const cfg = { + nano: { + languageList: {}, + metadata: compileData() + }, + path: { + fileName: 'main-userjs', + dir: './dist' + }, + file: '', + meta: '', + metaPath: '' + }; + for (const [k, v] of Object.entries(userJS.build.source)) { + const f = await canAccess(v); + if (typeof f !== 'string') continue; + if (k === 'metadata') { + cfg.meta = f; + } else { + cfg.nano[k] = f; + } + } + if (!isEmpty(i18nList)) { + for (const i18n of i18nList) { + for (const [k, v] of Object.entries(i18n)) { + const o = {}; + for (const [key, value] of Object.entries(v)) { + if (key.startsWith('ext')) { + continue; + } + if (/userjs_(name|description)/i.test(key)) { + continue; + } + if (isEmpty(value.message)) { + continue; + } + o[key] = value.message; + } + cfg.nano.languageList[k] = o; + } + } + } + for (const [k, v] of Object.entries(userJS.build.paths)) { + if (isEmpty(v)) continue; + if (isDev && /dev/i.test(k)) { + for (const [key, value] of Object.entries(v)) { + cfg.path[key] = value; + } + } else { + cfg.path[k] = v; + } + } + cfg.file = `${cfg.path.dir}/${cfg.path.fileName}.user.js`; + cfg.metaPath = `${cfg.path.dir}/${cfg.path.fileName}.meta.js`; + cfg.nano.languageList = JSON.stringify(cfg.nano.languageList, null, ' '); + + await writeUserJS(cfg.file, nano(cfg.meta, cfg.nano)); + log('UserJS Build:', { + path: cfg.file, + time: toTime() + }); + if (!isDev) { + await writeUserJS( + cfg.metaPath, + nano(metaStr, { + metadata: cfg.nano.metadata + }) + ); + log('UserJS Metadata:', { + path: cfg.metaPath, + time: toTime() + }); + } + } catch (ex) { + err(ex); + } + }; + log(`Node ENV: ${JS_ENV}`); + await buildUserJS(); + if (isDev) { + const wp = new Watchpack(); + let changed = new Set(); + wp.watch(userJS.build.watch.files, userJS.build.watch.dirs); + wp.on('change', (changedFile, mtime) => { + if (mtime === null) { + changed.delete(changedFile); + } else { + changed.add(changedFile); + } + }); + wp.on('aggregated', async () => { + // Filter out files that start with a dot from detected changes + // (as they are hidden files or temp files created by an editor). + const changes = Array.from(changed).filter((filePath) => { + return !path.basename(filePath).startsWith('.'); + }); + changed = new Set(); + + if (changes.length === 0) { + return; + } + + await buildUserJS(); + }); + } else { + process.exit(0); + } + } catch (ex) { + err(ex); + } +} + +export { build }; +export default build; diff --git a/utils/builder/typings/index.d.ts b/utils/builder/typings/index.d.ts new file mode 100644 index 0000000..6eacd4f --- /dev/null +++ b/utils/builder/typings/index.d.ts @@ -0,0 +1,50 @@ +import { PathLike } from 'node:fs'; + +export interface UserJS { + name: string; + description: string; + version: string; + license?: string; + bugs?: URL; + homepage?: URL; + icon?: PathLike; + downloadURL?: URL; + updateURL?: URL; + url_source?: URL; + url?: URL; + build: { + source: { + languageList: string; + [source: string]: PathLike; + }; + watch: { + files: string[]; + dirs: PathLike[]; + }; + paths: { + fileName: string; + dir: PathLike; + dev?: { + fileName?: string; + dir?: PathLike; + }; + }; + }; + metadata: { + compatible: string[]; + connect: string[]; + grant: string[]; + exclude: string[]; + include: string[]; + 'exclude-match': string[]; + match: string[]; + noframes: boolean; + resource: { + [name: string]: string; + }; + require: string[]; + 'run-at': 'document-start' | 'document-body' | 'document-end' | 'document-idle'; + }; +} + +export declare function build(): Promise; diff --git a/utils/i18n/README.md b/utils/i18n/README.md new file mode 100644 index 0000000..90c84e3 --- /dev/null +++ b/utils/i18n/README.md @@ -0,0 +1 @@ +# UserScript i18n diff --git a/utils/i18n/package.json b/utils/i18n/package.json new file mode 100644 index 0000000..3b931be --- /dev/null +++ b/utils/i18n/package.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json.schemastore.org/package.json", + "name": "@userjs/i18n", + "description": "Loads languages", + "version": "1.0.0", + "license": "MIT", + "main": "./src/index.js", + "types": "./typings/index.d.ts", + "exports": { + ".": { + "import": { + "types": "./typings/index.d.ts", + "default": "./src/index.js" + } + } + }, + "directories": { + "lib": "src" + }, + "files": [ + "src", + "typings" + ] +} diff --git a/utils/i18n/src/index.js b/utils/i18n/src/index.js new file mode 100644 index 0000000..0179325 --- /dev/null +++ b/utils/i18n/src/index.js @@ -0,0 +1,59 @@ +'use strict'; +import { readdir, readFile, stat } from 'node:fs/promises'; +import { URL, fileURLToPath } from 'node:url'; + +/** + * + * @type { import('../typings/index.d.ts').loadLanguages } + */ +async function loadLanguages(dir, recursive = true) { + try { + // Get the stats of the directory + const statDir = await stat(dir); + + // If the provided directory path is not a directory, throw an error + if (!statDir.isDirectory()) { + throw new Error(`The directory '${dir}' is not a directory.`); + } + + // Get all the files in the directory + const files = await readdir(dir); + + // Create an empty array to store the structures + /** @type {T[]} */ + const structures = []; + + // Loop through all the files in the directory + for (const file of files) { + // Get the stats of the file + const statFile = await stat(new URL(`${dir}/${file}`)); + + // If the file is a directory and recursive is true, recursively load the structures in the directory + if (statFile.isDirectory() && recursive) { + structures.push(...(await loadLanguages(new URL(`${dir}/${file}`), recursive))); + continue; + } + + if (!file.endsWith('.json')) { + continue; + } + + const filePath = fileURLToPath(`${dir}/${file}`); + const reg = /_locales\\(.*?)\\messages\.json/g.exec(filePath); + if (reg) { + const structure = await readFile(filePath, 'utf-8'); + structures.push({ + [reg[1]]: JSON.parse(structure.toString('utf-8')) + }); + } + } + + return structures; + // eslint-disable-next-line no-unused-vars + } catch (ex) { + return []; + } +} + +export { loadLanguages }; +export default loadLanguages; diff --git a/utils/i18n/typings/index.d.ts b/utils/i18n/typings/index.d.ts new file mode 100644 index 0000000..27f7743 --- /dev/null +++ b/utils/i18n/typings/index.d.ts @@ -0,0 +1,9 @@ +import { PathLike } from 'node:fs'; + +/** + * Loads all the structures in the provided directory. + * + * @param dir - The directory to load the structures from + * @param recursive - Whether to recursively load the structures in the directory + */ +export declare function loadLanguages(dir: PathLike, recursive?: boolean): Promise; diff --git a/utils/user.js/README.md b/utils/user.js/README.md new file mode 100644 index 0000000..b69b879 --- /dev/null +++ b/utils/user.js/README.md @@ -0,0 +1 @@ +# UserScript Builder diff --git a/utils/user.js/package.json b/utils/user.js/package.json new file mode 100644 index 0000000..47fb61a --- /dev/null +++ b/utils/user.js/package.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://json.schemastore.org/package.json", + "name": "user.js", + "description": "Create a UserScript", + "version": "1.0.0", + "license": "MIT", + "type": "module", + "main": "./src/index.js", + "types": "./typings/index.d.ts", + "exports": { + ".": { + "import": { + "types": "./typings/index.d.ts", + "default": "./src/index.js" + } + } + }, + "directories": { + "lib": "src" + }, + "files": [ + "src", + "typings" + ], + "dependencies": { + "@userjs/builder": "workspace:^", + "@userjs/i18n": "workspace:^" + } +} diff --git a/utils/user.js/src/index.js b/utils/user.js/src/index.js new file mode 100644 index 0000000..f8f2a95 --- /dev/null +++ b/utils/user.js/src/index.js @@ -0,0 +1,6 @@ +'use strict'; +import { build } from '@userjs/builder'; +import { loadLanguages } from '@userjs/i18n'; + +export { build, loadLanguages }; +export default build; diff --git a/utils/user.js/typings/index.d.ts b/utils/user.js/typings/index.d.ts new file mode 100644 index 0000000..f8f2a95 --- /dev/null +++ b/utils/user.js/typings/index.d.ts @@ -0,0 +1,6 @@ +'use strict'; +import { build } from '@userjs/builder'; +import { loadLanguages } from '@userjs/i18n'; + +export { build, loadLanguages }; +export default build; From b04ff3e07ba49c8ffd698e3b50c838889b45ec84 Mon Sep 17 00:00:00 2001 From: Magic Date: Sun, 2 Mar 2025 12:18:28 -0800 Subject: [PATCH 06/28] v7.5.0 Signed-off-by: Magic --- CHANGELOG.user.md | 24 ++++++++++++++ UserJS.json | 69 +++++++++++++++++++++++++++++++++++++++ dist/magic-userjs.meta.js | 4 +-- dist/magic-userjs.user.js | 41 ++++++++++------------- src/UserJS/header.js | 9 ----- src/UserJS/main.js | 20 +++++------- 6 files changed, 120 insertions(+), 47 deletions(-) create mode 100644 UserJS.json diff --git a/CHANGELOG.user.md b/CHANGELOG.user.md index 81b66f2..5786ca2 100644 --- a/CHANGELOG.user.md +++ b/CHANGELOG.user.md @@ -1,5 +1,25 @@ # Changelog +## v7.5.0 + +* Merged https://github.com/magicoflolis/Userscript-Plus/pull/64 +* Cleaned up old comments + +**Known Issues:** + +* Enabling a engine requires the page to be reloaded, while disabling a engine does not. + * This is caused by the cache system. +* "Filter out other languages" may not filter _every_ userscript that is not in your language. +* SVG elements don't load on every webpage, _can be blocked by the page, external script, or extensions._ + +**TODO:** + +* Finish translations. +* Finish blacklist section. +* Finish config section. + +--- + ## v7.4.0 * Merged https://github.com/magicoflolis/Userscript-Plus/pull/59 @@ -136,3 +156,7 @@ * Improve design of blacklist section --- + +## Previous Changes + +[https://github.com/magicoflolis/Userscript-Plus/releases](https://github.com/magicoflolis/Userscript-Plus/releases) diff --git a/UserJS.json b/UserJS.json new file mode 100644 index 0000000..31269ec --- /dev/null +++ b/UserJS.json @@ -0,0 +1,69 @@ +{ + "version": "7.5.0", + "name": "Magic Userscript+ : Show Site All UserJS", + "description": "Finds available userscripts for the current webpage.", + "author": "Magic ", + "bugs": "https://github.com/magicoflolis/Userscript-Plus/issues", + "homepage": "https://github.com/magicoflolis/Userscript-Plus", + "icon": "./src/img/icon_64.png", + "downloadURL": "https://github.com/magicoflolis/Userscript-Plus/raw/master/dist/magic-userjs.user.js", + "updateURL": "https://github.com/magicoflolis/Userscript-Plus/raw/master/dist/magic-userjs.meta.js", + "license": "MIT", + "build": { + "source": { + "metadata": "./src/UserJS/header.js", + "code": "./src/UserJS/main.js", + "mainCSS": "./build/css/magicuserjs.css" + }, + "watch": { + "files": ["main.js", "header.js", "magicuserjs.css"], + "dirs": ["src/UserJS", "build/css"] + }, + "paths": { + "fileName": "magic-userjs", + "dir": "./dist", + "dev": { + "fileName": "magic-userjs.dev", + "dir": "./web-server" + } + } + }, + "metadata": { + "compatible": ["chrome", "firefox", "edge", "opera", "safari"], + "connect": [ + "greasyfork.org", + "sleazyfork.org", + "github.com", + "githubusercontent.com", + "openuserjs.org" + ], + "grant": [ + "GM_addValueChangeListener", + "GM_addElement", + "GM_info", + "GM_getValue", + "GM_openInTab", + "GM_setValue", + "GM_registerMenuCommand", + "GM_removeValueChangeListener", + "GM_xmlhttpRequest", + "GM.addValueChangeListener", + "GM.addElement", + "GM.info", + "GM.getValue", + "GM.openInTab", + "GM.setValue", + "GM.registerMenuCommand", + "GM.removeValueChangeListener", + "GM.xmlHttpRequest" + ], + "exclude": [], + "include": [], + "exclude-match": [], + "match": ["https://*/*"], + "noframes": true, + "resource": {}, + "require": [], + "run-at": "document-start" + } +} diff --git a/dist/magic-userjs.meta.js b/dist/magic-userjs.meta.js index 6dd5d1d..a6aab9d 100644 --- a/dist/magic-userjs.meta.js +++ b/dist/magic-userjs.meta.js @@ -1,5 +1,5 @@ // ==UserScript== -// @version 7.4.0 +// @version 7.5.0 // @name Magic Userscript+ : Show Site All UserJS // @name:ar Magic Userscript+: عرض جميع ملفات UserJS // @name:de Magic Userscript+ : Website anzeigen Alle UserJS @@ -24,13 +24,13 @@ // @description:zh 为当前网页查找可用的用户脚本。 // @description:zh-CN 为当前网页查找可用的用户脚本。 // @description:zh-TW 为当前网页查找可用的用户脚本。 +// @author Magic // @supportURL https://github.com/magicoflolis/Userscript-Plus/issues // @namespace https://github.com/magicoflolis/Userscript-Plus // @homepageURL https://github.com/magicoflolis/Userscript-Plus // @icon data:image/png;base64,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 // @downloadURL https://github.com/magicoflolis/Userscript-Plus/raw/master/dist/magic-userjs.user.js // @updateURL https://github.com/magicoflolis/Userscript-Plus/raw/master/dist/magic-userjs.meta.js -// @author Magic // @license MIT // @compatible chrome // @compatible firefox diff --git a/dist/magic-userjs.user.js b/dist/magic-userjs.user.js index a624bdd..6f288aa 100644 --- a/dist/magic-userjs.user.js +++ b/dist/magic-userjs.user.js @@ -1,5 +1,5 @@ // ==UserScript== -// @version 7.4.0 +// @version 7.5.0 // @name Magic Userscript+ : Show Site All UserJS // @name:ar Magic Userscript+: عرض جميع ملفات UserJS // @name:de Magic Userscript+ : Website anzeigen Alle UserJS @@ -24,13 +24,13 @@ // @description:zh 为当前网页查找可用的用户脚本。 // @description:zh-CN 为当前网页查找可用的用户脚本。 // @description:zh-TW 为当前网页查找可用的用户脚本。 +// @author Magic // @supportURL https://github.com/magicoflolis/Userscript-Plus/issues // @namespace https://github.com/magicoflolis/Userscript-Plus // @homepageURL https://github.com/magicoflolis/Userscript-Plus // @icon data:image/png;base64,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 // @downloadURL https://github.com/magicoflolis/Userscript-Plus/raw/master/dist/magic-userjs.user.js // @updateURL https://github.com/magicoflolis/Userscript-Plus/raw/master/dist/magic-userjs.meta.js -// @author Magic // @license MIT // @compatible chrome // @compatible firefox @@ -104,11 +104,7 @@ const createPolicy = () => { }; createPolicy(); /** - * Uncompressed locales + compiler - * * [_locales](https://github.com/magicoflolis/Userscript-Plus/tree/master/src/_locales) - * - * [languageLoader.js](https://github.com/magicoflolis/Userscript-Plus/blob/master/tools/languageLoader.js) */ const translations = { "ar": { @@ -245,7 +241,7 @@ const translations = { "prmpt_css": "Install as UserStyle?", "userjs_inject": "Inject Userscript+", "userjs_close": "Close Userscript+", - "userjs_sync": "Sync with UserScript Manager", + "userjs_sync": "Sync", "userjs_autoinject": "Inject on load", "auto_fetch": "Fetch on load" }, @@ -710,11 +706,6 @@ const translations = { "auto_fetch": "Fetch on load" } }; -/** - * To compile this CSS `pnpm run build:Sass` - * - * [Uncompiled Cascading Style Sheet](https://github.com/magicoflolis/Userscript-Plus/tree/master/src/sass) - */ const main_css = `mujs-root { --mujs-even-row: hsl(222, 14%, 22%); --mujs-odd-row: hsl(222, 14%, 11%); @@ -1893,7 +1884,7 @@ const DEFAULT_CONFIG = { class i18nHandler { constructor() { if (userjs.pool !== undefined) { - return userjs.pool; + return this; } userjs.pool = new Map(); for (const [k, v] of Object.entries(translations)) { @@ -1922,7 +1913,7 @@ class i18nHandler { i18n$(key) { const { navigator } = safeSelf(); const current = navigator.language.split('-')[0] ?? 'en'; - return userjs.pool.get(current)?.[key] ?? 'Unknown'; + return userjs.pool.get(current)?.[key] ?? 'Invalid Key'; } } const language = new i18nHandler(); @@ -2114,7 +2105,7 @@ const getGMInfo = () => { icon: '', name: 'Magic Userscript+', namespace: 'https://github.com/magicoflolis/Userscript-Plus', - updateURL: 'https://github.com/magicoflolis/Userscript-Plus/releases', + updateURL: 'https://github.com/magicoflolis/Userscript-Plus/raw/master/dist/magic-userjs.js', version: 'Bookmarklet', bugs: 'https://github.com/magicoflolis/Userscript-Plus/issues' } @@ -2922,7 +2913,8 @@ class Container { this.tab.create(host); const tabbody = this.tabbody; - const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent; + const getCellValue = (tr, idx) => + tr.children[idx].dataset.value || tr.children[idx].innerText || tr.children[idx].textContent; const comparer = (idx, asc) => (a, b) => ((v1, v2) => v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) @@ -3814,9 +3806,6 @@ function primaryFN() { data_names; constructor(code) { this.code = code; - this.get_all(); - } - get_all() { this.get_meta_block(); this.get_code_block(); this.parse_meta(); @@ -4154,16 +4143,17 @@ function primaryFN() { if (badUserJS.includes(ujs.id) || badUserJS.includes(ujs.url)) { return; } - if (!container.userjsCache.has(ujs.id)) { - container.userjsCache.set(ujs.id, ujs); - } + if (!container.userjsCache.has(ujs.id)) container.userjsCache.set(ujs.id, ujs); const eframe = make('td', 'install-btn'); const uframe = make('td', 'mujs-uframe'); const fdaily = make('td', 'mujs-list', { textContent: ujs.daily_installs }); const fupdated = make('td', 'mujs-list', { - textContent: language.toDate(ujs.code_updated_at) + textContent: language.toDate(ujs.code_updated_at), + dataset: { + value: new Date(ujs.code_updated_at).toISOString() + } }); const fname = make('td', 'mujs-name'); const fmore = make('mujs-column', 'mujs-list hidden', { @@ -4187,7 +4177,10 @@ function primaryFN() { textContent: `${i18n$('version_number')}: ${ujs.version}` }); const fcreated = make('mu-js', 'mujs-list', { - textContent: `${i18n$('created_date')}: ${language.toDate(ujs.created_at)}` + textContent: `${i18n$('created_date')}: ${language.toDate(ujs.created_at)}`, + dataset: { + value: new Date(ujs.created_at).toISOString() + } }); const flicense = make('mu-js', 'mujs-list', { title: ujs.license ?? i18n$('no_license'), diff --git a/src/UserJS/header.js b/src/UserJS/header.js index 9b48860..fe229de 100644 --- a/src/UserJS/header.js +++ b/src/UserJS/header.js @@ -39,18 +39,9 @@ const createPolicy = () => { }; createPolicy(); /** - * Uncompressed locales + compiler - * * [_locales](https://github.com/magicoflolis/Userscript-Plus/tree/master/src/_locales) - * - * [languageLoader.js](https://github.com/magicoflolis/Userscript-Plus/blob/master/tools/languageLoader.js) */ const translations = [[languageList]]; -/** - * To compile this CSS `pnpm run build:Sass` - * - * [Uncompiled Cascading Style Sheet](https://github.com/magicoflolis/Userscript-Plus/tree/master/src/sass) - */ const main_css = `[[mainCSS]]`; /******************************************************************************/ [[code]] diff --git a/src/UserJS/main.js b/src/UserJS/main.js index cf28c30..87c6905 100644 --- a/src/UserJS/main.js +++ b/src/UserJS/main.js @@ -310,7 +310,7 @@ const DEFAULT_CONFIG = { class i18nHandler { constructor() { if (userjs.pool !== undefined) { - return userjs.pool; + return this; } userjs.pool = new Map(); for (const [k, v] of Object.entries(translations)) { @@ -339,7 +339,7 @@ class i18nHandler { i18n$(key) { const { navigator } = safeSelf(); const current = navigator.language.split('-')[0] ?? 'en'; - return userjs.pool.get(current)?.[key] ?? 'Unknown'; + return userjs.pool.get(current)?.[key] ?? 'Invalid Key'; } } const language = new i18nHandler(); @@ -531,7 +531,7 @@ const getGMInfo = () => { icon: '', name: 'Magic Userscript+', namespace: 'https://github.com/magicoflolis/Userscript-Plus', - updateURL: 'https://github.com/magicoflolis/Userscript-Plus/releases', + updateURL: 'https://github.com/magicoflolis/Userscript-Plus/raw/master/dist/magic-userjs.js', version: 'Bookmarklet', bugs: 'https://github.com/magicoflolis/Userscript-Plus/issues' } @@ -1339,7 +1339,8 @@ class Container { this.tab.create(host); const tabbody = this.tabbody; - const getCellValue = (tr, idx) => tr.children[idx].dataset.value || tr.children[idx].innerText || tr.children[idx].textContent; + const getCellValue = (tr, idx) => + tr.children[idx].dataset.value || tr.children[idx].innerText || tr.children[idx].textContent; const comparer = (idx, asc) => (a, b) => ((v1, v2) => v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) @@ -2231,9 +2232,6 @@ function primaryFN() { data_names; constructor(code) { this.code = code; - this.get_all(); - } - get_all() { this.get_meta_block(); this.get_code_block(); this.parse_meta(); @@ -2571,9 +2569,7 @@ function primaryFN() { if (badUserJS.includes(ujs.id) || badUserJS.includes(ujs.url)) { return; } - if (!container.userjsCache.has(ujs.id)) { - container.userjsCache.set(ujs.id, ujs); - } + if (!container.userjsCache.has(ujs.id)) container.userjsCache.set(ujs.id, ujs); const eframe = make('td', 'install-btn'); const uframe = make('td', 'mujs-uframe'); const fdaily = make('td', 'mujs-list', { @@ -2582,7 +2578,7 @@ function primaryFN() { const fupdated = make('td', 'mujs-list', { textContent: language.toDate(ujs.code_updated_at), dataset: { - value: (new Date(ujs.code_updated_at)).toISOString() + value: new Date(ujs.code_updated_at).toISOString() } }); const fname = make('td', 'mujs-name'); @@ -2609,7 +2605,7 @@ function primaryFN() { const fcreated = make('mu-js', 'mujs-list', { textContent: `${i18n$('created_date')}: ${language.toDate(ujs.created_at)}`, dataset: { - value: (new Date(ujs.created_at)).toISOString() + value: new Date(ujs.created_at).toISOString() } }); const flicense = make('mu-js', 'mujs-list', { From 3132d5534de47c8bde83bfdd9f31410124933b42 Mon Sep 17 00:00:00 2001 From: Magic Date: Sun, 2 Mar 2025 12:21:56 -0800 Subject: [PATCH 07/28] Updated README.md Signed-off-by: Magic --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 5ef775e..cd6701d 100644 --- a/README.md +++ b/README.md @@ -40,15 +40,11 @@ Finds available UserScripts and UserStyles for the current webpage, the power of * [Firefox Add-ons](https://addons.mozilla.org/firefox/addon/userscript-plus/) * [GitHub Repo](https://github.com/magicoflolis/Userscript-Plus/releases/tag/webext/latest) -Works for desktop and mobile versions. - *Chromium:* * ~~[Chrome Web Store](https://github.com/magicoflolis/Userscript-Plus/releases/tag/webext/latest)~~ * [GitHub Repo](https://github.com/magicoflolis/Userscript-Plus/releases/tag/webext/latest) -Magic Userscript+ should be compatible with any Chromium-based browser - **Bookmarklet (not recommended):** Save this URL as a bookmark, clicking it will cause the **UserScript version** to inject itself into the current webpage. From fefd7aefbec16be7c0d5a16195f8dee6408550f5 Mon Sep 17 00:00:00 2001 From: Magic Date: Sun, 2 Mar 2025 13:33:51 -0800 Subject: [PATCH 08/28] Updated README.md Signed-off-by: Magic --- README.md | 49 ++---------------------- src/UserJS/.env.example | 2 - wiki/Build.md | 84 +++++++++++++++++++++++++++++++++++++++++ wiki/README.md | 9 ++++- 4 files changed, 95 insertions(+), 49 deletions(-) delete mode 100644 src/UserJS/.env.example create mode 100644 wiki/Build.md diff --git a/README.md b/README.md index cd6701d..79bb3ba 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ javascript:(function(){['https://cdn.jsdelivr.net/gh/magicoflolis/Userscript-Plu * Blacklist: * Attempts to exclude certain hosts from being queried - localhost, bank, government, etc. * Menu: - * Search for UserScripts - for shortcuts see [Wiki](https://github.com/magicoflolis/Userscript-Plus/blob/master/wiki/README.md) + * Search for UserScripts - for shortcuts see [Wiki](https://github.com/magicoflolis/Userscript-Plus/blob/master/wiki/README.md#shortcuts) * Filter UserScripts which do not match your current language * Sort UserScripts, default sorting "Daily Installs" * Preview UserScripts code before install @@ -142,52 +142,11 @@ javascript:(function(){['https://cdn.jsdelivr.net/gh/magicoflolis/Userscript-Plu * **If nothing appears, this means the script is not executing at all!** * For any additional help, submit a [New Issue](https://github.com/magicoflolis/Userscript-Plus/issues/new/choose) -## Build +## Want to Contribute? -Install [Node.js](https://nodejs.org/) and [pnpm](https://pnpm.io/) - *the version of Node.js should match or be greater than the `"node"` key in `package.json`.* +Fork this repo and open a [pull request](https://github.com/magicoflolis/Userscript-Plus/pulls) - [Rules](https://github.com/magicoflolis/Userscript-Plus/blob/master/wiki/Build.md#contribution-rules) - [Guide](https://github.com/magicoflolis/Userscript-Plus/blob/master/wiki/Build.md#contribution-guide) -``` sh -# Install dependencies -$ pnpm i -``` - -### UserScript Version - -Before you begin, rename `.env.example` to `.env` - -**Recommened Testing Environments:** - -* **Desktop:** any browser with [ViolentMonkey](https://violentmonkey.github.io/), see [How to edit scripts with your favorite editor?](https://violentmonkey.github.io/posts/how-to-edit-scripts-with-your-favorite-editor/) -* **Mobile:** - * Desktop: use "Responsive Design Mode(Ctrl+Shift+M)" on [FireFox Developer Edition](https://www.mozilla.org/firefox/developer/) or just [FireFox](https://www.mozilla.org/firefox/) - * Android: any browser that supports User Script or support for installing a User Script manager, I use [Cromite](https://github.com/uazo/cromite) - * IOS: any browser that supports User Script or support for installing a User Script manager - -``` sh -# Watch and compile to local HTTP server -$ pnpm run dev:UserJS - -# Compile UserScript to "./dist" -$ pnpm run pub:UserJS -``` - -### WebExtension Version - -``` sh -# Compile WebExtension (developer version) for "Chromium" to "./build/chrome" -$ pnpm run dev:Cr -# Compile WebExtension (developer version) for "Firefox" to "./build/firefox" -$ pnpm run dev:FF -# Compile WebExtension (public version) for "Chromium" to "./build/chrome" -$ pnpm run webpack:Cr -# Compile WebExtension (public version) for "Firefox" to "./build/firefox" -$ pnpm run webpack:FF - -# [ Testing ] -# Browsers can be launched via "Run and Debug" in VSCode. -# Edit runtimeExecutable in ".vscode/launch.json" to your Chrome executable. -# Recommended to create an additional profile "about:profiles" for Firefox. -``` +How to add or edit translations? How to build? - [Build](https://github.com/magicoflolis/Userscript-Plus/blob/master/wiki/Build.md) ### Roadmap diff --git a/src/UserJS/.env.example b/src/UserJS/.env.example deleted file mode 100644 index 2d29ccc..0000000 --- a/src/UserJS/.env.example +++ /dev/null @@ -1,2 +0,0 @@ -# Please do not change this .env variable -JS_ENV="development" diff --git a/wiki/Build.md b/wiki/Build.md new file mode 100644 index 0000000..4d1ef16 --- /dev/null +++ b/wiki/Build.md @@ -0,0 +1,84 @@ +# Build + +Install [Node.js](https://nodejs.org/) and [pnpm](https://pnpm.io/) - *the version of Node.js should match or be greater than the `"node"` key in `package.json`.* + +```sh +# Install dependencies +$ pnpm i +``` + +**UserScript:** + +Before you begin, rename `.env.example` to `.env` + +**Recommened Testing Environments:** + +- **Desktop:** any browser with [ViolentMonkey](https://violentmonkey.github.io/), see [How to edit scripts with your favorite editor?](https://violentmonkey.github.io/posts/how-to-edit-scripts-with-your-favorite-editor/) +- **Mobile:** + - Desktop: use "Responsive Design Mode (Ctrl+Shift+M)" on [FireFox Developer Edition](https://www.mozilla.org/firefox/developer/) or [FireFox](https://www.mozilla.org/firefox/) + - Android: any browser with UserScript support or support for installing a UserScript manager, I use [Cromite](https://github.com/uazo/cromite) + - IOS: any browser with UserScript support or support for installing a UserScript manager + +```sh +# Watch and build to local HTTP server +$ pnpm run dev:UserJS + +# Build UserScript to "./dist" +$ pnpm run pub:UserJS +``` + +--- + +**WebExtension:** + +```sh +# Build WebExtension (developer version) for "Chromium" to "./build/chrome" +$ pnpm run dev:Cr +# Build WebExtension (developer version) for "Firefox" to "./build/firefox" +$ pnpm run dev:FF +# Build WebExtension (public version) for "Chromium" to "./build/chrome" +$ pnpm run webpack:Cr +# Build WebExtension (public version) for "Firefox" to "./build/firefox" +$ pnpm run webpack:FF + +# [ Testing ] +# Browsers can be launched via "Run and Debug" in VSCode. +# Edit runtimeExecutable in ".vscode/launch.json" to your Chrome executable. +# Recommended to create an additional profile "about:profiles" for Firefox. +``` + +## Contribution Rules + +**General:** + +Follow [Semantic Versioning](https://semver.org/) standards, if your unsure you don't need to update the version + +--- + +**Translations:** + +Translations follow [Web Extension Internationalization](https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/Internationalization) standards + +--- + +**UserScript:** + +Do not edit the UserScript found in the `./dist` directory, the file is auto generated from `dev:UserJS` command. Instead edit it from `./src/UserJS` + +## Contribution Guide + +Fork this repo, make your changes, and open a [pull request](https://github.com/magicoflolis/Userscript-Plus/pulls) + +**Translations:** + +Translations are located in `./src/_locales` + +For versioning translations are a PATCH + +**Adding:** + +Recommend using `./src/_locales/en/messages.json` as a template + +**Updating:** + +Update any key from `messages.json` file diff --git a/wiki/README.md b/wiki/README.md index c4a70f4..8bffd31 100644 --- a/wiki/README.md +++ b/wiki/README.md @@ -1,6 +1,11 @@ # Wiki Page (Under Construction) -## New Tab +- [Wiki Page (Under Construction)](#wiki-page-under-construction) + - [Shortcuts](#shortcuts) + +## Shortcuts + +**New Tab:** Syntax: `*` - Shortcut for userscipts that apply to `All sites` @@ -25,7 +30,7 @@ mujs:settings --- -## Search Bar +**Search Bar:** By default it will search by name and description, you can refine your searches using the examples listed below. From 50dbc988c85e3b85380272fe3f23074a2739eacb Mon Sep 17 00:00:00 2001 From: Magic Date: Mon, 3 Mar 2025 13:55:22 -0800 Subject: [PATCH 09/28] Updated package.json Signed-off-by: Magic --- utils/i18n/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/i18n/package.json b/utils/i18n/package.json index 3b931be..65555d5 100644 --- a/utils/i18n/package.json +++ b/utils/i18n/package.json @@ -4,6 +4,7 @@ "description": "Loads languages", "version": "1.0.0", "license": "MIT", + "type": "module", "main": "./src/index.js", "types": "./typings/index.d.ts", "exports": { From 369711533656fb5edc37799916080794333074a0 Mon Sep 17 00:00:00 2001 From: Magic Date: Wed, 5 Mar 2025 15:42:42 -0800 Subject: [PATCH 10/28] UserJS v7.6.0 Signed-off-by: Magic --- CHANGELOG.user.md | 31 + README.md | 6 +- UserJS.json | 2 +- dist/magic-userjs.meta.js | 2 +- dist/magic-userjs.user.js | 1502 ++++++++++------- package.json | 4 +- src/UserJS/main.js | 1288 +++++++------- src/UserJS/svg/bug-svgrepo-com.svg | 1 - src/UserJS/svg/close-svgrepo-com.svg | 8 - src/UserJS/svg/download-svgrepo-com.svg | 1 - .../expand-full-fullscreen-svgrepo-com.svg | 1 - src/UserJS/svg/filter-svgrepo-com.svg | 5 - src/UserJS/svg/fork-svgrepo-com.svg | 1 - src/UserJS/svg/fullscreen-svgrepo-com.svg | 63 - src/UserJS/svg/github-svgrepo-com.svg | 1 - src/UserJS/svg/minus-svgrepo-com.svg | 2 - src/UserJS/svg/navigation-svgrepo-com.svg | 11 - src/UserJS/svg/plus-svgrepo-com.svg | 5 - src/UserJS/svg/search-svgrepo-com.svg | 1 - src/UserJS/svg/settings-svgrepo-com.svg | 4 - src/_locales/en/messages.json | 4 +- src/sass/_main.scss | 319 ++-- src/sass/magicuserjs.scss | 2 +- src/typings/UserJS.d.ts | 1 + src/typings/types.d.ts | 37 +- 25 files changed, 1838 insertions(+), 1464 deletions(-) delete mode 100644 src/UserJS/svg/bug-svgrepo-com.svg delete mode 100644 src/UserJS/svg/close-svgrepo-com.svg delete mode 100644 src/UserJS/svg/download-svgrepo-com.svg delete mode 100644 src/UserJS/svg/expand-full-fullscreen-svgrepo-com.svg delete mode 100644 src/UserJS/svg/filter-svgrepo-com.svg delete mode 100644 src/UserJS/svg/fork-svgrepo-com.svg delete mode 100644 src/UserJS/svg/fullscreen-svgrepo-com.svg delete mode 100644 src/UserJS/svg/github-svgrepo-com.svg delete mode 100644 src/UserJS/svg/minus-svgrepo-com.svg delete mode 100644 src/UserJS/svg/navigation-svgrepo-com.svg delete mode 100644 src/UserJS/svg/plus-svgrepo-com.svg delete mode 100644 src/UserJS/svg/search-svgrepo-com.svg delete mode 100644 src/UserJS/svg/settings-svgrepo-com.svg diff --git a/CHANGELOG.user.md b/CHANGELOG.user.md index 5786ca2..4094647 100644 --- a/CHANGELOG.user.md +++ b/CHANGELOG.user.md @@ -1,5 +1,36 @@ # Changelog +## v7.6.0 + +* New feature, `Preview Metadata` - same as `Preview Code` but loads userscripts metadata head +* Config changes, moved `codePreview` value to `preview: code`, recommended resetting your config to clear any old/unused settings. + * If you had `Preview Code` enabled, you will need to re-enable it +* When `Preview Metadata` and `Preview Code` are both enabled, it will display the entire userscript +* Icon changes, svgs are now from [fontawesome.com](fontawesome.com) +* Search engines have been moved to the `Search Engines` section +* Improved mobile UI +* Improved userscript parsing +* Improved load times - added custom event to handle async item changes +* Improved GitHub engine + * Number of stars for a repo = daily installs + * Number of watchers for a repo = good rating +* Cleanup old css +* Minor bug fixes + +**Known Issues:** + +* Enabling a engine requires the page to be reloaded, while disabling a engine does not. + * This is caused by the cache system. +* SVG elements don't load on every webpage, _can be blocked by the page, external scripts, or web extensions._ +* If an item changes after the list is sorted, the sorting won't be updated + +**TODO:** + +* Finish translations. +* Finish blacklist section. + +--- + ## v7.5.0 * Merged https://github.com/magicoflolis/Userscript-Plus/pull/64 diff --git a/README.md b/README.md index 79bb3ba..58acd8e 100644 --- a/README.md +++ b/README.md @@ -2,17 +2,17 @@ [![Badge Issues](https://img.shields.io/github/issues/magicoflolis/Userscript-Plus?style=flat-square)](https://github.com/magicoflolis/Userscript-Plus/issues) [![Badge Greasy Fork](https://img.shields.io/greasyfork/dt/421603?style=flat-square)](https://greasyfork.org/scripts/421603) [![Badge Stars](https://img.shields.io/github/stars/magicoflolis/Userscript-Plus?style=flat-square)](https://github.com/magicoflolis/Userscript-Plus/stargazers) -[![UserScript](https://img.shields.io/badge/Userscript-Download-brightgreen.svg?style=flat-square&label=Greasy+Fork&logo=javascript&logoColor=white)](https://greasyfork.org/scripts/421603) -[![UserScript](https://img.shields.io/badge/Userscript-Download-brightgreen.svg?style=flat-square&label=GitHub+Repo&logo=javascript&logoColor=white)](https://github.com/magicoflolis/Userscript-Plus/blob/master/dist/magic-userjs.user.js?raw=1) --- -

+
+

Magic Userscript+

+
*A complete rewrite of [Userscript+ : Show Site All UserJS](https://github.com/jae-jae/Userscript-Plus)* diff --git a/UserJS.json b/UserJS.json index 31269ec..24fd9a8 100644 --- a/UserJS.json +++ b/UserJS.json @@ -1,5 +1,5 @@ { - "version": "7.5.0", + "version": "7.6.0", "name": "Magic Userscript+ : Show Site All UserJS", "description": "Finds available userscripts for the current webpage.", "author": "Magic ", diff --git a/dist/magic-userjs.meta.js b/dist/magic-userjs.meta.js index a6aab9d..091b951 100644 --- a/dist/magic-userjs.meta.js +++ b/dist/magic-userjs.meta.js @@ -1,5 +1,5 @@ // ==UserScript== -// @version 7.5.0 +// @version 7.6.0 // @name Magic Userscript+ : Show Site All UserJS // @name:ar Magic Userscript+: عرض جميع ملفات UserJS // @name:de Magic Userscript+ : Website anzeigen Alle UserJS diff --git a/dist/magic-userjs.user.js b/dist/magic-userjs.user.js index 6f288aa..4a35efc 100644 --- a/dist/magic-userjs.user.js +++ b/dist/magic-userjs.user.js @@ -1,5 +1,5 @@ // ==UserScript== -// @version 7.5.0 +// @version 7.6.0 // @name Magic Userscript+ : Show Site All UserJS // @name:ar Magic Userscript+: عرض جميع ملفات UserJS // @name:de Magic Userscript+ : Website anzeigen Alle UserJS @@ -225,7 +225,7 @@ const translations = { "save": "Save", "reset": "Reset", "preview_code": "Preview Code", - "saveFile": "Save File", + "saveFile": "Download", "newTab": "New Tab", "applies_to": "Applies to", "license": "License", @@ -737,6 +737,9 @@ const main_css = `mujs-root { } mujs-root * { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; scrollbar-color: var(--mujs-txt-color, hsl(0, 0%, 100%)) hsl(224, 14%, 21%); scrollbar-width: thin; } @@ -783,10 +786,6 @@ td.mujs-list { font-weight: 500; } -.mujs-sty-flex > mujs-btn { - margin: auto; -} - .mujs-invalid { border-radius: 8px !important; border-width: 2px !important; @@ -806,11 +805,6 @@ mujs-row { gap: 0.5em; } -@media screen and (max-width: 800px) { - mujs-column { - flex-flow: row wrap; - } -} mujs-column count-frame[data-counter=greasyfork] { background: var(--mujs-gf-color, hsl(204, 100%, 40%)); } @@ -823,6 +817,11 @@ mujs-column count-frame[data-counter=github] { mujs-column count-frame[data-counter=openuserjs] { background: hsla(12, 86%, 50%, 0.568); } +@media screen and (max-width: 800px) { + mujs-column { + flex-flow: row wrap; + } +} mujs-row { flex-flow: column wrap; @@ -920,6 +919,11 @@ mujs-main mujs-tabs mujs-tab { border-radius: 4px; background: transparent; } +@media screen and (max-width: 800px) { + mujs-main mujs-tabs mujs-tab { + min-width: 6em !important; + } +} mujs-main mujs-tabs mujs-tab.active { background: var(--mujs-even-row, hsl(222, 14%, 18%)); } @@ -962,17 +966,25 @@ mujs-main input:not([type=checkbox]) { border: transparent; outline: none !important; } +mujs-main mujs-page, mujs-main textarea { background: inherit; overflow-y: auto; - color: var(--mujs-placeholder, hsl(81, 56%, 54%)); border: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); - border-radius: 10px; - resize: vertical; + border-radius: 5px; outline: none; font-family: monospace; font-size: 14px; } +mujs-main mujs-page { + padding: 0.5em; + margin: 0.5em; +} +mujs-main textarea { + overflow-y: auto; + color: var(--mujs-placeholder, hsl(81, 56%, 54%)); + resize: vertical; +} mujs-main textarea:focus { outline: none; } @@ -1002,8 +1014,7 @@ mujs-main .mujs-prompt { align-items: center; justify-content: center; } -mujs-main .mujs-prompt svg, -mujs-main .mujs-prompt img { +mujs-main .mujs-prompt svg { width: 14px; height: 14px; background: transparent; @@ -1119,9 +1130,6 @@ mujs-header mujs-url > input { mujs-header .rate-container { order: 1; } -mujs-header .mujs-sty-flex { - order: 2; -} mujs-header .btn-frame { order: 999999999999; } @@ -1168,13 +1176,11 @@ mujs-body table { display: flex; flex-flow: row wrap; align-items: center; - border-bottom: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); padding-top: 0.5em; padding-bottom: 0.5em; } mujs-body table .frame:not(.webext-page) td { margin: auto; - border-bottom: 1px solid transparent; } mujs-body table .frame:not(.webext-page) td > mujs-a, mujs-body table .frame:not(.webext-page) td > mu-js, @@ -1182,9 +1188,32 @@ mujs-body table { text-align: center; justify-content: center; } + mujs-body table .frame:not(.webext-page) td > mujs-a { + width: 100%; + } +} +@media screen and (max-width: 1180px) and (max-width: 800px) { + mujs-body table .frame:not(.webext-page) td > mujs-column { + flex-flow: column wrap; + } + mujs-body table .frame:not(.webext-page) td > mujs-column > mujs-row { + align-content: center; + } + mujs-body table .frame:not(.webext-page) td > mujs-column mujs-column { + justify-content: center; + } +} +@media screen and (max-width: 1180px) { mujs-body table .frame:not(.webext-page) td:not(.mujs-name, .install-btn) { width: 25%; } +} +@media screen and (max-width: 1180px) and (max-width: 800px) { + mujs-body table .frame:not(.webext-page) td.install-btn { + width: 100%; + } +} +@media screen and (max-width: 1180px) { mujs-body table .frame:not(.webext-page) .mujs-name { width: 100%; } @@ -1197,15 +1226,12 @@ mujs-body table { width: auto !important; } } -mujs-body table th, -mujs-body table td { - border-bottom: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); -} mujs-body table th { position: -webkit-sticky; position: sticky; top: 0; background: hsla(222, 14%, 33%, 0.75); + border-bottom: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); } mujs-body table th.mujs-header-name { width: 50%; @@ -1218,9 +1244,15 @@ mujs-body table th.mujs-header-name { mujs-body table .frame:nth-child(even) { background: var(--mujs-even-row, hsl(222, 14%, 18%)) !important; } +mujs-body table .frame:nth-child(even) textarea { + background: var(--mujs-odd-row, hsl(222, 14%, 33%)) !important; +} mujs-body table .frame:nth-child(odd) { background: var(--mujs-odd-row, hsl(222, 14%, 33%)) !important; } +mujs-body table .frame:nth-child(odd) textarea { + background: var(--mujs-even-row, hsl(222, 14%, 18%)) !important; +} mujs-body table .frame:not([data-engine=sleazyfork], [data-engine=greasyfork]) mujs-a { color: var(--mujs-sf-txt-color, hsl(12, 79%, 55%)); } @@ -1295,12 +1327,9 @@ mujs-body table .frame .mujs-ratings[data-el=bad] { color: hsl(0, 100%, 50%); } mujs-body table .frame svg { + width: 12px; + height: 12px; fill: currentColor; -} -mujs-body table .frame svg, -mujs-body table .frame img { - width: 14px; - height: 14px; background: transparent; } mujs-body table .frame > td:not(.mujs-name) { @@ -1323,6 +1352,11 @@ mujs-body table .frame > .mujs-name > mu-jsbtn { mujs-body table .frame > .mujs-name > mujs-column > mu-jsbtn { padding: 0px 7px; } +@media screen and (max-width: 800px) { + mujs-body table .frame > .mujs-name > mujs-column > mu-jsbtn { + width: 100%; + } +} mujs-body table .frame > .mujs-uframe > mujs-a { font-size: 16px; font-weight: 500; @@ -1363,6 +1397,26 @@ mujs-body table .frame [data-el=matches] .mujs-grants > mujs-a::after { mujs-body table .frame [data-el=matches] .mujs-grants > mujs-a:last-child::after { content: ""; } +@media screen and (max-width: 800px) { + mujs-body table .frame [data-el=matches] { + width: 30em !important; + } +} +mujs-body table .frame [data-name=license] { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; +} +@media screen and (max-width: 800px) { + mujs-body table .frame [data-name=license] { + width: 100% !important; + width: -moz-available !important; + width: -webkit-fill-available !important; + } +} @media screen and (max-width: 1150px) { .mujs-cfg { @@ -1374,18 +1428,6 @@ mujs-body table .frame [data-el=matches] .mujs-grants > mujs-a:last-child::after height: -moz-fit-content; height: -webkit-fit-content; } -@media screen and (max-height: 720px) { - .mujs-cfg:not(.webext-page) { - height: 100%; - height: -moz-available; - height: -webkit-fill-available; - width: 100%; - width: -moz-available; - width: -webkit-fill-available; - overflow-x: auto; - padding: 0.5em; - } -} .mujs-cfg mujs-section { border-radius: 16px; padding: 0.5em; @@ -1393,15 +1435,43 @@ mujs-body table .frame [data-el=matches] .mujs-grants > mujs-a:last-child::after .mujs-cfg mujs-section:nth-child(even) { background: var(--mujs-even-row, hsl(222, 14%, 18%)) !important; } +.mujs-cfg mujs-section:nth-child(even) input, +.mujs-cfg mujs-section:nth-child(even) select { + background: var(--mujs-odd-row, hsl(222, 14%, 33%)); +} +.mujs-cfg mujs-section:nth-child(even) select option { + background: var(--mujs-odd-row, hsl(222, 14%, 33%)); +} +.mujs-cfg mujs-section:nth-child(even) select option:hover { + background: var(--mujs-even-row, hsl(222, 14%, 18%)) !important; +} .mujs-cfg mujs-section:nth-child(odd) { background: var(--mujs-odd-row, hsl(222, 14%, 33%)) !important; } -.mujs-cfg mujs-section[data-name=theme], .mujs-cfg mujs-section[data-name=blacklist] { +.mujs-cfg mujs-section:nth-child(odd) input, +.mujs-cfg mujs-section:nth-child(odd) select { + background: var(--mujs-even-row, hsl(222, 14%, 18%)); +} +.mujs-cfg mujs-section:nth-child(odd) select option { + background: var(--mujs-even-row, hsl(222, 14%, 18%)); +} +.mujs-cfg mujs-section:nth-child(odd) select option:hover { + background: var(--mujs-odd-row, hsl(222, 14%, 33%)) !important; +} +.mujs-cfg mujs-section[data-name=theme], .mujs-cfg mujs-section[data-name=exp], .mujs-cfg mujs-section[data-name=blacklist] { display: flex; justify-content: space-between; flex-direction: column; gap: 0.25em; } +.mujs-cfg mujs-section[data-name=theme] > mujs-btn, .mujs-cfg mujs-section[data-name=exp] > mujs-btn, .mujs-cfg mujs-section[data-name=blacklist] > mujs-btn { + width: 100%; + width: -moz-available; + width: -webkit-fill-available; +} +.mujs-cfg mujs-section[data-name=theme] > mujs-btn:hover, .mujs-cfg mujs-section[data-name=exp] > mujs-btn:hover, .mujs-cfg mujs-section[data-name=blacklist] > mujs-btn:hover { + background: var(--mujs-even-row, hsl(222, 14%, 18%)) !important; +} .mujs-cfg mujs-section input[type=text]::-webkit-input-placeholder { color: var(--mujs-placeholder, hsl(81, 56%, 54%)); } @@ -1434,22 +1504,37 @@ mujs-body table .frame [data-el=matches] .mujs-grants > mujs-a:last-child::after .mujs-cfg mujs-section > label.new-list mujs-add { font-size: 20px; } -.mujs-cfg mujs-section > label.sub-section { - padding: 0.2em; -} .mujs-cfg mujs-section > label input:not([type=checkbox]) { font-size: 14px; position: relative; border-radius: 4px; border: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); } -.mujs-cfg mujs-section > input { +.mujs-cfg mujs-section select, +.mujs-cfg mujs-section select option { + color: var(--mujs-txt-color, hsl(0, 0%, 100%)); + border: 1px solid transparent; + list-style: none; + outline-style: none; + pointer-events: auto; +} +.mujs-cfg mujs-section select { + text-align: center; + border-radius: 4px; +} +.mujs-cfg mujs-section > *.sub-section { + padding: 0.2em; +} +.mujs-cfg mujs-section > *.sub-section[data-engine] { + flex-wrap: wrap; +} +.mujs-cfg mujs-section > *.sub-section[data-engine] input { width: 100%; width: -moz-available; width: -webkit-fill-available; - margin-top: 5px; - border-radius: 4px; - border: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); +} +.mujs-cfg mujs-section > *.sub-section input[type=text] { + margin: 0.2em 0px; } .mujs-cfg .mujs-inlab { position: relative; @@ -1465,8 +1550,11 @@ mujs-body table .frame [data-el=matches] .mujs-grants > mujs-a:last-child::after .mujs-cfg .mujs-inlab input[type=checkbox]:checked + label:before { right: 0px; } -.mujs-cfg .mujs-inlab input[type=checkbox][data-name=greasyfork]:checked + label, .mujs-cfg .mujs-inlab input[type=checkbox][data-name=sleazyfork]:checked + label { - background: var(--mujs-chck-gf, hsla(197, 100%, 50%, 0.568)); +.mujs-cfg .mujs-inlab input[type=checkbox][data-name=greasyfork]:checked + label { + background: var(--mujs-gf-color, hsl(204, 100%, 40%)); +} +.mujs-cfg .mujs-inlab input[type=checkbox][data-name=sleazyfork]:checked + label { + background: var(--mujs-sf-color, hsl(12, 86%, 50%)); } .mujs-cfg .mujs-inlab input[type=checkbox][data-name=openuserjs]:checked + label { background: var(--mujs-chck-open, hsla(12, 86%, 50%, 0.568)); @@ -1494,6 +1582,9 @@ mujs-body table .frame [data-el=matches] .mujs-grants > mujs-a:last-child::after right: 20px; border-radius: 20px; } +.mujs-cfg .mujs-sty-flex mujs-btn { + margin: auto; +} .mujs-cfg .mujs-sty-flex mujs-btn[data-command=reset] { background: var(--mujs-sf-btn-color, hsl(12, 86%, 50%)); border-color: var(--mujs-sf-btn-color, hsl(12, 86%, 50%)); @@ -1513,6 +1604,18 @@ mujs-body table .frame [data-el=matches] .mujs-grants > mujs-a:last-child::after .mujs-cfg:not(.webext-page) { margin: 1rem 25rem; } +@media screen and (max-height: 720px) { + .mujs-cfg:not(.webext-page) { + height: 100%; + height: -moz-available; + height: -webkit-fill-available; + width: 100%; + width: -moz-available; + width: -webkit-fill-available; + overflow-x: auto; + padding: 0.5em; + } +} mujs-a { display: inline-block; @@ -1541,12 +1644,9 @@ mujs-btn { padding: 6px 15px; } mujs-btn svg { - fill: var(--mujs-txt-color, hsl(0, 0%, 100%)); -} -mujs-btn svg, -mujs-btn img { width: 14px; height: 14px; + fill: var(--mujs-txt-color, hsl(0, 0%, 100%)); } mu-jsbtn { @@ -1564,7 +1664,7 @@ mu-jsbtn { mujs-a, mu-jsbtn, .mujs-pointer, -.mujs-cfg mujs-section *:not(input[type=password], input[type=text], input[type=number], [data-theme], [data-blacklist]), +.mujs-cfg mujs-section *:not(input[type=text], input[type=number], [data-theme], [data-blacklist]), .mainbtn, .mainframe, mujs-btn { @@ -1624,6 +1724,65 @@ const log = (...msg) => { */ let cfg = {}; +// #region Validators +/** + * @type { import("../typings/types.d.ts").objToStr } + */ +const objToStr = (obj) => Object.prototype.toString.call(obj); +/** + * @type { import("../typings/types.d.ts").isRegExp } + */ +const isRegExp = (obj) => { + const s = objToStr(obj); + return s.includes('RegExp'); +}; +/** + * @type { import("../typings/types.d.ts").isElem } + */ +const isElem = (obj) => { + const s = objToStr(obj); + return s.includes('Element'); +}; +/** + * @type { import("../typings/types.d.ts").isObj } + */ +const isObj = (obj) => { + const s = objToStr(obj); + return s.includes('Object'); +}; +/** + * @type { import("../typings/types.d.ts").isFN } + */ +const isFN = (obj) => { + const s = objToStr(obj); + return s.includes('Function'); +}; +/** + * @type { import("../typings/types.d.ts").isNull } + */ +const isNull = (obj) => { + return Object.is(obj, null) || Object.is(obj, undefined); +}; +/** + * @type { import("../typings/types.d.ts").isBlank } + */ +const isBlank = (obj) => { + return ( + (typeof obj === 'string' && Object.is(obj.trim(), '')) || + ((obj instanceof Set || obj instanceof Map) && Object.is(obj.size, 0)) || + (Array.isArray(obj) && Object.is(obj.length, 0)) || + (isObj(obj) && Object.is(Object.keys(obj).length, 0)) + ); +}; +/** + * @type { import("../typings/types.d.ts").isEmpty } + */ +const isEmpty = (obj) => { + return isNull(obj) || isBlank(obj); +}; +// #endregion + +// #region Globals /** * https://github.com/zloirock/core-js/blob/master/packages/core-js/internals/global-this.js * @returns {typeof globalThis} @@ -1643,7 +1802,6 @@ function globalWin() { Function('return this')() ); } - /** @type { import("../typings/UserJS.d.ts").safeSelf } */ function safeSelf() { if (userjs.safeSelf) { @@ -1653,6 +1811,7 @@ function safeSelf() { /** @type { import("../typings/UserJS.d.ts").safeHandles } */ const safe = { XMLHttpRequest: g.XMLHttpRequest, + CustomEvent: g.CustomEvent, createElement: g.document.createElement.bind(g.document), createElementNS: g.document.createElementNS.bind(g.document), createTextNode: g.document.createTextNode.bind(g.document), @@ -1689,9 +1848,20 @@ function safeSelf() { } } }; + for (const [k, v] of Object.entries(safe)) { + if (k === 'scheduler') { + continue; + } else if (k === 'navigator') { + continue; + } else if (isFN(v)) { + continue; + } + err({ message: `Safe handles "${k}" returned "${v}"`, cause: 'safeSelf' }); + } userjs.safeSelf = safe; return userjs.safeSelf; } +// #endregion const BLANK_PAGE = 'about:blank'; // Lets highlight me :) @@ -1786,12 +1956,15 @@ const DEFAULT_CONFIG = { autoSort: 'daily_installs', clearTabCache: true, cache: true, - codePreview: false, autoexpand: false, filterlang: false, sleazyredirect: false, time: 10000, blacklist: ['userjs-local', 'userjs-finance', 'userjs-social', 'userjs-unsupported'], + preview: { + code: false, + metadata: false + }, engines: [ { enabled: true, @@ -1943,61 +2116,6 @@ const qsA = (selectors, root) => { } return []; }; -/** - * @type { import("../typings/types.d.ts").objToStr } - */ -const objToStr = (obj) => Object.prototype.toString.call(obj); -/** - * @type { import("../typings/types.d.ts").isRegExp } - */ -const isRegExp = (obj) => { - const s = objToStr(obj); - return s.includes('RegExp'); -}; -/** - * @type { import("../typings/types.d.ts").isElem } - */ -const isElem = (obj) => { - const s = objToStr(obj); - return s.includes('Element'); -}; -/** - * @type { import("../typings/types.d.ts").isObj } - */ -const isObj = (obj) => { - const s = objToStr(obj); - return s.includes('Object'); -}; -/** - * @type { import("../typings/types.d.ts").isFN } - */ -const isFN = (obj) => { - const s = objToStr(obj); - return s.includes('Function'); -}; -/** - * @type { import("../typings/types.d.ts").isNull } - */ -const isNull = (obj) => { - return Object.is(obj, null) || Object.is(obj, undefined); -}; -/** - * @type { import("../typings/types.d.ts").isBlank } - */ -const isBlank = (obj) => { - return ( - (typeof obj === 'string' && Object.is(obj.trim(), '')) || - ((obj instanceof Set || obj instanceof Map) && Object.is(obj.size, 0)) || - (Array.isArray(obj) && Object.is(obj.length, 0)) || - (isObj(obj) && Object.is(Object.keys(obj).length, 0)) - ); -}; -/** - * @type { import("../typings/types.d.ts").isEmpty } - */ -const isEmpty = (obj) => { - return isNull(obj) || isBlank(obj); -}; /** * @type { import("../typings/types.d.ts").normalizeTarget } */ @@ -2201,61 +2319,57 @@ class Memorize { const memory = new Memorize(); //#region Icon SVGs const iconSVG = { - cfg: { - viewBox: '0 0 24 24', - html: '' - }, close: { - viewBox: '0 0 24 24', - html: '' + viewBox: '0 0 384 512', + html: '' }, - filter: { - viewBox: '0 0 24 24', - html: '' + code: { + viewBox: '0 0 640 512', + html: '' }, - fsClose: { - viewBox: '0 0 24 24', - html: ' ' + collapse: { + viewBox: '0 0 448 512', + html: '' }, - fsOpen: { - viewBox: '0 0 24 24', - html: ' ' + download: { + viewBox: '0 0 384 512', + html: '' }, - fullscreen: { - viewBox: '0 0 96 96', - html: '' + expand: { + viewBox: '0 0 448 512', + html: '' }, - gf: { - viewBox: '0 0 510.4 510.4', - html: '' + gear: { + viewBox: '0 0 512 512', + html: '' }, - gh: { - viewBox: '0 0 16 16', - html: '' + github: { + viewBox: '0 0 496 512', + html: '' }, - hide: { - viewBox: '0 0 24 24', - html: ' ' + globe: { + viewBox: '0 0 512 512', + html: '' }, install: { - viewBox: '0 0 16 16', - html: '' + viewBox: '0 0 512 512', + html: '' }, issue: { - viewBox: '0 0 24 24', - html: '' + viewBox: '0 0 512 512', + html: '' }, - nav: { - viewBox: '0 0 24 24', - html: ' ' + minus: { + viewBox: '0 0 448 512', + html: '' }, - plus: { - viewBox: '0 0 24 24', - html: '' + nav: { + viewBox: '0 0 448 512', + html: '' }, - search: { - viewBox: '0 0 24 24', - html: '' + pager: { + viewBox: '0 0 512 512', + html: '' }, verified: { viewBox: '0 0 56 56', @@ -2264,9 +2378,9 @@ const iconSVG = { html: '' }, refresh: { - viewBox: '0 0 1024 1024', + viewBox: '0 0 512 512', fill: 'currentColor', - html: '' + html: '' }, load(type, container) { const { createElementNS } = safeSelf(); @@ -2610,6 +2724,7 @@ const Counter = { } } }; + // #region Container /** * @type { import("../typings/UserJS.d.ts").Container } @@ -2675,11 +2790,7 @@ class Container { } }); if (this.supported) { - this.shadowRoot = this.frame.attachShadow({ - mode: 'closed' - // clonable: false, - // delegatesfocus: false - }); + this.shadowRoot = this.frame.attachShadow({ mode: 'closed' }); this.ready = true; } this.cache = memory.maps.container; @@ -2698,6 +2809,7 @@ class Container { } set(delay, reason) { + const { setTimeout } = safeSelf(); return new Promise((resolve, reject) => { const id = setTimeout(() => { Object.is(reason, null) || Object.is(reason, undefined) ? resolve() : reject(reason); @@ -2708,6 +2820,7 @@ class Container { } clear(...ids) { + const { clearTimeout } = safeSelf(); this.ids = this.ids.filter((id) => { if (ids.includes(id)) { clearTimeout(id); @@ -2773,7 +2886,7 @@ class Container { Counter.cnt.total.root = this.mainbtn; for (const engine of cfg.engines) this.countframe.append(Counter.set(engine)); - const { cfgpage, table, exBtn, supported, frame, refresh, cache, urlBar, host } = this; + const { cfgpage, table, supported, frame, refresh, cache, urlBar, host } = this; class Tabs { /** @@ -2818,7 +2931,7 @@ class Container { return; } if (hostname.match(this.protoReg)[1] === 'settings') { - dom.cl.remove([cfgpage, exBtn], 'hidden'); + dom.cl.remove(cfgpage, 'hidden'); dom.cl.add(table, 'hidden'); if (!supported) { dom.attr(frame, 'style', 'height: 100%;'); @@ -2831,7 +2944,7 @@ class Container { */ active(tab, build = true) { if (!this.pool.has(tab)) this.pool.add(tab); - dom.cl.add([cfgpage, exBtn], 'hidden'); + dom.cl.add(cfgpage, 'hidden'); dom.cl.remove(table, 'hidden'); dom.cl.remove([...this.pool], 'active'); dom.cl.add(tab, 'active'); @@ -2913,8 +3026,7 @@ class Container { this.tab.create(host); const tabbody = this.tabbody; - const getCellValue = (tr, idx) => - tr.children[idx].dataset.value || tr.children[idx].innerText || tr.children[idx].textContent; + const getCellValue = (tr, idx) => tr.children[idx].dataset.value; const comparer = (idx, asc) => (a, b) => ((v1, v2) => v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) @@ -2961,43 +3073,18 @@ class Container { this.tbody = make('mujs-body'); this.cfgpage = make('mujs-row', 'mujs-cfg hidden'); this.btnframe = make('mujs-column', 'btn-frame'); - this.exBtn = make('mujs-column', 'mujs-sty-flex hidden'); this.fsearch = make('mujs-btn', 'hidden'); - this.exportCFG = make('mujs-btn', 'mujs-export', { - textContent: i18n$('export_config'), - dataset: { - command: 'export-cfg' - } - }); - this.importCFG = make('mujs-btn', 'mujs-import', { - textContent: i18n$('import_config'), - dataset: { - command: 'import-cfg' - } - }); - this.exportTheme = make('mujs-btn', 'mujs-export', { - textContent: i18n$('export_theme'), - dataset: { - command: 'export-theme' - } - }); - this.importTheme = make('mujs-btn', 'mujs-import', { - textContent: i18n$('import_theme'), - dataset: { - command: 'import-theme' - } - }); this.btnHandles = make('mujs-column', 'btn-handles'); this.btnHide = make('mujs-btn', 'hide-list', { title: i18n$('min'), - innerHTML: iconSVG.load('hide'), + innerHTML: iconSVG.load('minus'), dataset: { command: 'hide-list' } }); this.btnfullscreen = make('mujs-btn', 'fullscreen', { title: i18n$('max'), - innerHTML: iconSVG.load('fullscreen'), + innerHTML: iconSVG.load('expand'), dataset: { command: 'fullscreen' } @@ -3013,7 +3100,7 @@ class Container { }); this.btncfg = make('mujs-btn', 'settings hidden', { title: 'Settings', - innerHTML: iconSVG.load('cfg'), + innerHTML: iconSVG.load('gear'), dataset: { command: 'settings' } @@ -3024,7 +3111,7 @@ class Container { ? $info.script.version : $info.script.version.slice(0, 5) })`, - innerHTML: iconSVG.load('gh'), + innerHTML: iconSVG.load('github'), dataset: { command: 'open-tab', webpage: $info.script.namespace @@ -3040,7 +3127,7 @@ class Container { }); this.btngreasy = make('mujs-btn', 'greasy hidden', { title: 'Greasy Fork', - innerHTML: iconSVG.load('gf'), + innerHTML: iconSVG.load('globe'), dataset: { command: 'open-tab', webpage: 'https://greasyfork.org/scripts/421603' @@ -3081,17 +3168,30 @@ class Container { } ]); // #endregion - - this.btnHandles.append(this.btnHide, this.btnfullscreen, this.closebtn); - this.btnframe.append(this.btnhome, this.btngreasy, this.btnissue, this.btncfg, this.btnnav); + if (isMobile) { + dom.cl.add([this.btnHide, this.btnfullscreen, this.closebtn], 'hidden'); + this.btnframe.append( + this.btnHide, + this.btnfullscreen, + this.closebtn, + this.btnhome, + this.btngreasy, + this.btnissue, + this.btncfg, + this.btnnav + ); + } else { + this.btnHandles.append(this.btnHide, this.btnfullscreen, this.closebtn); + this.btnframe.append(this.btnhome, this.btngreasy, this.btnissue, this.btncfg, this.btnnav); + } this.toolbar.append(this.btnHandles); this.urlContainer.append(this.urlBar); this.header.append(this.urlContainer, this.rateContainer, this.countframe, this.btnframe); this.tbody.append(this.table, this.cfgpage); this.main.append(this.toolbar, this.header, this.tbody, this.footer, this.promptElem); this.mainframe.append(this.mainbtn); - this.exBtn.append(this.importCFG, this.importTheme, this.exportCFG, this.exportTheme); - this.header.append(this.exBtn); + // this.exBtn.append(this.importCFG, this.importTheme, this.exportCFG, this.exportTheme); + // this.header.append(this.exBtn); this.root.append(this.mainframe, this.main); return true; @@ -3390,10 +3490,6 @@ function primaryFN() { fsearch, btnfullscreen, main, - btncfg, - btnhome, - btnissue, - btngreasy, tab, showError } = container; @@ -3438,8 +3534,75 @@ function primaryFN() { installLink.remove(); await init(); }; + const applyTo = (ujs, name, elem, root) => { + const n = ujs._mujs.code[name] ?? ujs._mujs.code.data_meta[name]; + if (isEmpty(n)) { + const el = make('mujs-a', { + textContent: i18n$('listing_none') + }); + elem.append(el); + return; + } + dom.prop(elem, 'innerHTML', ''); + dom.cl.remove(root, 'hidden'); + if (isObj(n)) { + if (name === 'resource') { + for (const [k, v] of Object.entries(n)) { + const el = make('mujs-a', { + textContent: k ?? 'ERROR' + }); + if (v.startsWith('http')) { + el.dataset.command = 'open-tab'; + el.dataset.webpage = v; + } + elem.append(el); + } + } else { + const el = make('mujs-a', { + textContent: n.text + }); + if (n.domain) { + el.dataset.command = 'open-tab'; + el.dataset.webpage = `https://${n.text}`; + } + elem.append(el); + } + } else if (typeof n === 'string') { + const el = make('mujs-a', { + textContent: n + }); + elem.append(el); + } else { + for (const c of n) { + if (typeof c === 'string' && c.startsWith('http')) { + const el = make('mujs-a', { + textContent: c, + dataset: { + command: 'open-tab', + webpage: c + } + }); + elem.append(el); + } else if (isObj(c)) { + const el = make('mujs-a', { + textContent: c.text + }); + if (c.domain) { + el.dataset.command = 'open-tab'; + el.dataset.webpage = `https://${c.text}`; + } + elem.append(el); + } else { + const el = make('mujs-a', { + textContent: c + }); + elem.append(el); + } + } + } + }; // #region Main event handlers - ael(main, 'click', async (evt) => { + ael(main, isMobile ? 'touchend' : 'click', async (evt) => { try { /** @type { HTMLElement } */ const target = evt.target.closest('[data-command]'); @@ -3485,10 +3648,13 @@ function primaryFN() { } return window.open(dataset.webpage, '_blank'); } else if (cmd === 'navigation') { - if (dom.cl.has(btngreasy, 'hidden')) { - dom.cl.remove([btncfg, btngreasy, btnhome, btnissue], 'hidden'); - } else { - dom.cl.add([btncfg, btngreasy, btnhome, btnissue], 'hidden'); + for (const e of qsA('mujs-btn', target.parentElement)) { + if (dom.cl.has(e, 'nav')) continue; + if (dom.cl.has(e, 'hidden')) { + dom.cl.remove(e, 'hidden'); + } else { + dom.cl.add(e, 'hidden'); + } } } else if (cmd === 'list-description') { const arr = []; @@ -3520,10 +3686,10 @@ function primaryFN() { } else if (cmd === 'fullscreen') { if (dom.cl.has(btnfullscreen, 'expanded')) { dom.cl.remove([btnfullscreen, main], 'expanded'); - dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('fsOpen')); + dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('expand')); } else { dom.cl.add([btnfullscreen, main], 'expanded'); - dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('fsClose')); + dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('collapse')); } } else if (cmd === 'hide-list') { dom.cl.add(main, 'hidden'); @@ -3592,81 +3758,115 @@ function primaryFN() { dlBtn.click(); URL.revokeObjectURL(dlBtn.href); dlBtn.remove(); - } else if (cmd === 'load-userjs') { + } else if (cmd === 'load-userjs' || cmd === 'load-header') { if (!container.userjsCache.has(+dataset.userjs)) { return; } const codeArea = qs('textarea', target.parentElement.parentElement); - if (!isEmpty(codeArea.value)) { + if (!isEmpty(codeArea.value) && cmd === codeArea.dataset.load) { dom.cl.toggle(codeArea, 'hidden'); return; } + codeArea.dataset.load = cmd; const dataUserJS = container.userjsCache.get(+dataset.userjs); - const r = await dataUserJS._mujs.code.request(); - const txt = r.data; - if (typeof txt !== 'string') { + const code_obj = await dataUserJS._mujs.code.request(); + if (typeof code_obj.data_code_block !== 'string') { + codeArea.value = 'An error occured'; return; } - const code_obj = new ParseUserJS(txt); - codeArea.value = code_obj.get_code_block(); + codeArea.value = + cmd === 'load-userjs' ? code_obj.data_code_block : code_obj.data_meta_block; dom.cl.remove(codeArea, 'hidden'); - const apTo = (name, elem, root) => { - const n = dataUserJS._mujs.code[name]; - if (isEmpty(n)) { - const el = make('mujs-a', { - textContent: i18n$('listing_none') + for (const e of qsA( + 'mujs-column[data-el="matches"]', + target.parentElement.parentElement + )) { + applyTo(dataUserJS, e.dataset.type, qs('.mujs-grants', e), e); + } + } else if (cmd === 'load-page') { + if (!container.userjsCache.has(+dataset.userjs)) { + return; + } + let pageArea = qs('mujs-page', target.parentElement.parentElement); + if (!pageArea) { + pageArea = make('mujs-page'); + target.parentElement.parentElement.append(pageArea); + const dataUserJS = container.userjsCache.get(+dataset.userjs); + const engine = dataUserJS._mujs.info.engine; + let pageURL; + if (engine.name.includes('fork')) { + const { navigator } = safeSelf(); + const current = navigator.language.split('-')[0] ?? 'en'; + pageURL = dataUserJS.url.replace( + /\/scripts/, + `/${/^(zh|fr|es)/.test(current) ? navigator.language : current}/scripts` + ); + } else if (engine.name.includes('github')) { + const page_url = await Network.req(dataUserJS.page_url, 'GET', 'json', { + headers: { + Accept: 'application/vnd.github+json', + Authorization: `Bearer ${engine.token}`, + 'X-GitHub-Api-Version': '2022-11-28' + } + }).catch(() => { + return {}; }); - elem.append(el); + if (!page_url.download_url) { + return; + } + const page = await Network.req(page_url.download_url, 'GET', 'text'); + if (container.supported) { + const shadow = pageArea.attachShadow({ mode: 'closed' }); + const div = make('div', { + innerHTML: page + }); + shadow.append(div); + } return; + } else { + pageURL = dataUserJS.url; } - dom.prop(elem, 'innerHTML', ''); - dom.cl.remove(root, 'hidden'); - for (const c of n) { - if (typeof c === 'string' && c.startsWith('http')) { - const el = make('mujs-a', { - textContent: c, - dataset: { - command: 'open-tab', - webpage: c - } - }); - elem.append(el); - } else if (isObj(c)) { - if (name === 'resource') { - for (const [k, v] of Object.entries(c)) { - const el = make('mujs-a', { - textContent: k ?? 'ERROR' - }); - if (v.startsWith('http')) { - el.dataset.command = 'open-tab'; - el.dataset.webpage = v; - } - elem.append(el); - } - } else { - const el = make('mujs-a', { - textContent: c.text - }); - if (c.domain) { - el.dataset.command = 'open-tab'; - el.dataset.webpage = `https://${c.text}`; - } - elem.append(el); + if (!pageURL) { + return; + } + const page = await Network.req(pageURL, 'GET', 'document'); + const getContent = () => { + let content = 'An error occured'; + const h = new URL(dataUserJS.url); + const root = qs('.user-content', page.documentElement); + for (const e of qsA('[href]', root)) { + e.target = '_blank'; + e.style = 'pointer-events: auto;'; + if (e.href.startsWith('/')) { + e.href = `${h.origin}${e.href}`; } + } + for (const e of qsA('img[src]', root)) { + e.style = + 'max-width: 25em; max-height: 25em; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;'; + } + if (root) { + content = root.innerHTML; } else { - const el = make('mujs-a', { - textContent: c - }); - elem.append(el); + content = 'No additional info available'; } + return content; + }; + if (container.supported) { + const shadow = pageArea.attachShadow({ mode: 'closed' }); + const div = make('div', { + style: 'pointer-events: none;', + innerHTML: getContent() + }); + shadow.append(div); } - }; - for (const e of qsA( - 'mujs-column[data-el="matches"]', - target.parentElement.parentElement - )) { - apTo(e.dataset.type, qs('.mujs-grants', e), e); + return; + } + if (!dom.cl.has(pageArea, 'hidden')) { + dom.cl.add(pageArea, 'hidden'); + return; } + dom.cl.remove(pageArea, 'hidden'); } else if (/export-/.test(cmd)) { const str = JSON.stringify(cmd === 'export-cfg' ? cfg : cfg.theme, null, ' '); const bytes = new TextEncoder().encode(str); @@ -3767,9 +3967,50 @@ function primaryFN() { }); } } + ael(main, 'updateditem', (evt) => { + /** + * @type {import("../typings/types.d.ts").GSForkQuery} + */ + const ujs = evt.detail; + if (!ujs._mujs) return; + for (const elem of qsA('[data-name]', ujs._mujs.root)) { + const name = elem.dataset.name; + if (name === 'code') { + if (ujs._mujs.code.data_code_block) { + if (cfg.preview.code && !cfg.preview.metadata) { + elem.value = ujs._mujs.code.data_code_block; + } else if (cfg.preview.metadata && !cfg.preview.code) { + elem.value = ujs._mujs.code.data_meta_block; + } else { + elem.value = `${ujs._mujs.code.META_START_COMMENT}${ujs._mujs.code.data_meta_block}${ujs._mujs.code.META_END_COMMENT}${ujs._mujs.code.data_code_block}`; + } + } + continue; + } + if (!ujs[name]) continue; + if (name === 'license') { + dom.attr(elem, 'title', ujs.license ?? i18n$('no_license')); + dom.text(elem, `${i18n$('license')}: ${ujs.license ?? i18n$('no_license')}`); + } else if (name === 'code_updated_at') { + dom.text(elem, language.toDate(ujs.code_updated_at)); + elem.dataset.value = new Date(ujs.code_updated_at).toISOString(); + } else if (name === 'created_date') { + dom.text(elem, `${i18n$('created_date')}: ${language.toDate(ujs.created_at)}`); + elem.dataset.value = new Date(ujs.created_at).toISOString(); + } else if (name === 'total_installs') { + dom.text(elem, `${i18n$('total_installs')}: ${language.toNumber(ujs.total_installs)}`); + } else { + dom.text(elem, ujs[name]); + } + } + if (ujs._mujs.code.data_code_block) { + for (const e of qsA('mujs-column[data-el="matches"]', ujs._mujs.root)) { + applyTo(ujs, e.dataset.type, qs('.mujs-grants', e), e); + } + } + if (container.userjsCache.has(ujs.id)) container.userjsCache.set(ujs.id, ujs); + }); // #endregion - const META_START_COMMENT = '// ==UserScript=='; - const META_END_COMMENT = '// ==/UserScript=='; const TLD_EXPANSION = ['com', 'net', 'org', 'de', 'co.uk']; const APPLIES_TO_ALL_PATTERNS = [ 'http://*', @@ -3797,15 +4038,17 @@ function primaryFN() { */ data_code_block; /** - * @type { { [meta: string]: any } } + * @type { { [meta: string]: string | string[] | { [resource: string]: string } } } */ data_meta; /** - * @type { string[] } + * @type { {text: string;domain: boolean;tld_extra: boolean}[] } */ data_names; - constructor(code) { + constructor(code, isUserCSS) { this.code = code; + this.META_START_COMMENT = isUserCSS ? '/* ==UserStyle==' : '// ==UserScript=='; + this.META_END_COMMENT = isUserCSS ? '==/UserStyle== */' : '// ==/UserScript=='; this.get_meta_block(); this.get_code_block(); this.parse_meta(); @@ -3818,17 +4061,20 @@ function primaryFN() { if (this.data_meta_block) { return this.data_meta_block; } - const start_block = this.code.indexOf(META_START_COMMENT); + const start_block = this.code.indexOf(this.META_START_COMMENT); if (isNull(start_block)) { return null; } - const end_block = this.code.indexOf(META_END_COMMENT, start_block); + const end_block = this.code.indexOf(this.META_END_COMMENT, start_block); if (isNull(end_block)) { return null; } - const meta_block = this.code.substring(start_block + META_START_COMMENT.length, end_block); + const meta_block = this.code.substring( + start_block + this.META_START_COMMENT.length, + end_block + ); this.data_meta_block = meta_block; - return meta_block; + return this.data_meta_block; } get_code_block() { if (isEmpty(this.code)) { @@ -3837,28 +4083,23 @@ function primaryFN() { if (this.data_code_block) { return this.data_code_block; } - const start_block = this.code.indexOf(META_START_COMMENT); + const start_block = this.code.indexOf(this.META_START_COMMENT); if (isNull(start_block)) { return null; } - const end_block = this.code.indexOf(META_END_COMMENT, start_block); + const end_block = this.code.indexOf(this.META_END_COMMENT, start_block); if (isNull(end_block)) { return null; } const code_block = this.code.substring( - end_block + META_END_COMMENT.length, + end_block + this.META_END_COMMENT.length, this.code.length ); - const lines = []; - for (const l of code_block.split('\n')) { - if (isEmpty(l)) { - continue; - } - lines.push(l); - } - const clean_code = lines.join('\n'); - this.data_code_block = clean_code; - return clean_code; + this.data_code_block = code_block + .split('\n') + .filter((l) => !isEmpty(l)) + .join('\n'); + return this.data_code_block; } parse_meta() { if (isEmpty(this.code)) { @@ -3868,11 +4109,10 @@ function primaryFN() { return this.data_meta; } const meta = {}; - const meta_block = this.get_meta_block(); const meta_block_map = new Map(); - for (const meta_line of meta_block.split('\n')) { - const meta_match = meta_line.match(/\/\/\s+@([a-zA-Z:-]+)\s+(.*)/); - if (isNull(meta_match)) { + for (const meta_line of this.get_meta_block().split('\n')) { + const meta_match = /\/\/\s+@([a-zA-Z:-]+)\s+(.*)/.exec(meta_line); + if (!meta_match) { continue; } const key = meta_match[1].trim(); @@ -3894,9 +4134,6 @@ function primaryFN() { this.data_meta = meta; return this.data_meta; } - /** - * @returns { string[] } - */ calculate_applies_to_names() { if (isEmpty(this.code)) { return null; @@ -3904,10 +4141,9 @@ function primaryFN() { if (this.data_names) { return this.data_names; } - const meta = this.parse_meta(); let patterns = []; - for (const [k, v] of Object.entries(meta)) { - if (/include|match/.test(k)) { + for (const [k, v] of Object.entries(this.parse_meta())) { + if (/include|match/i.test(k)) { if (Array.isArray(v)) { patterns = patterns.concat(v); } else { @@ -3919,14 +4155,21 @@ function primaryFN() { return []; } if (this.intersect(patterns, APPLIES_TO_ALL_PATTERNS)) { - return []; + this.data_names = [ + { + domain: false, + text: 'All sites', + tld_extra: false + } + ]; + return this.data_names; } - const name_set = new Set(); + const name_map = new Map(); const addObj = (obj) => { - if (name_set.has(obj)) { + if (name_map.has(obj.text)) { return; } - name_set.add(obj); + name_map.set(obj.text, obj); }; for (let p of patterns) { try { @@ -3935,8 +4178,8 @@ function primaryFN() { if (p.match(/^\/(.*)\/$/)) { pre_wildcards = [p]; } else { - let m = p.match(/^\*(https?:.*)/i); - if (!isNull(m)) { + let m = /^\*(https?:.*)/i.exec(p); + if (m) { p = m[1]; } p = p @@ -3944,20 +4187,20 @@ function primaryFN() { .replace(/^\*\/\//i, 'http://') .replace(/^http\*:/i, 'http:') .replace(/^(https?):([^/])/i, '$1://$2'); - m = p.match(/^([a-z]+:\/\/)\*\.?([a-z0-9-]+(?:.[a-z0-9-]+)+.*)/i); - if (!isNull(m)) { + m = /^([a-z]+:\/\/)\*\.?([a-z0-9-]+(?:.[a-z0-9-]+)+.*)/i.exec(p); + if (m) { p = m[1] + m[2]; } - m = p.match(/^\*\.?([a-z0-9-]+\.[a-z0-9-]+.*)/i); - if (!isNull(m)) { + m = /^\*\.?([a-z0-9-]+\.[a-z0-9-]+.*)/i.exec(p); + if (m) { p = `http://${m[1]}`; } - m = p.match(/^http\*(?:\/\/)?\.?((?:[a-z0-9-]+)(?:\.[a-z0-9-]+)+.*)/i); - if (!isNull(m)) { + m = /^http\*(?:\/\/)?\.?((?:[a-z0-9-]+)(?:\.[a-z0-9-]+)+.*)/i.exec(p); + if (m) { p = `http://${m[1]}`; } - m = p.match(/^([a-z]+:\/\/([a-z0-9-]+(?:\.[a-z0-9-]+)*\.))\*(.*)/); - if (!isNull(m)) { + m = /^([a-z]+:\/\/([a-z0-9-]+(?:\.[a-z0-9-]+)*\.))\*(.*)/.exec(p); + if (m) { if (m[2].match(/A([0-9]+\.){2,}z/)) { p = `${m[1]}tld${m[3]}`; pre_wildcards = [p.split('*')[0]]; @@ -4007,26 +4250,12 @@ function primaryFN() { err(ex); } } - const arr = [...name_set]; - this.data_names = arr; + this.data_names = [...name_map.values()]; return this.data_names; } - intersect(a = [], b = []) { - for (const v of a) { - if (b.includes(v)) { - return true; - } - } - for (const v of b) { - if (a.includes(v)) { - return true; - } - } - return false; + intersect(a, ...arr) { + return !isBlank([...new Set(a)].filter((v) => arr.every((b) => b.includes(v)))); } - // intersect(a, ...arr) { - // return [...new Set(a)].filter((v) => arr.every((b) => b.includes(v))); - // } } const template = { id: 0, @@ -4147,11 +4376,15 @@ function primaryFN() { const eframe = make('td', 'install-btn'); const uframe = make('td', 'mujs-uframe'); const fdaily = make('td', 'mujs-list', { - textContent: ujs.daily_installs + textContent: ujs.daily_installs, + dataset: { + name: 'daily_installs' + } }); const fupdated = make('td', 'mujs-list', { textContent: language.toDate(ujs.code_updated_at), dataset: { + name: 'code_updated_at', value: new Date(ujs.code_updated_at).toISOString() } }); @@ -4179,17 +4412,22 @@ function primaryFN() { const fcreated = make('mu-js', 'mujs-list', { textContent: `${i18n$('created_date')}: ${language.toDate(ujs.created_at)}`, dataset: { + name: 'created_at', value: new Date(ujs.created_at).toISOString() } }); const flicense = make('mu-js', 'mujs-list', { title: ujs.license ?? i18n$('no_license'), textContent: `${i18n$('license')}: ${ujs.license ?? i18n$('no_license')}`, - style: - 'text-overflow: ellipsis; overflow: hidden; white-space: nowrap; width: fit-content; max-width: 20em;' + dataset: { + name: 'license' + } }); const ftotal = make('mu-js', 'mujs-list', { - textContent: `${i18n$('total_installs')}: ${language.toNumber(ujs.total_installs)}` + textContent: `${i18n$('total_installs')}: ${language.toNumber(ujs.total_installs)}`, + dataset: { + name: 'total_installs' + } }); const fratings = make('mu-js', 'mujs-list', { title: i18n$('ratings'), @@ -4199,6 +4437,7 @@ function primaryFN() { title: i18n$('good'), textContent: ujs.good_ratings, dataset: { + name: 'good_ratings', el: 'good' } }); @@ -4206,6 +4445,7 @@ function primaryFN() { title: i18n$('ok'), textContent: ujs.ok_ratings, dataset: { + name: 'ok_ratings', el: 'ok' } }); @@ -4213,6 +4453,7 @@ function primaryFN() { title: i18n$('bad'), textContent: ujs.bad_ratings, dataset: { + name: 'bad_ratings', el: 'bad' } }); @@ -4232,7 +4473,7 @@ function primaryFN() { } }); const scriptDownload = make('mu-jsbtn', { - innerHTML: `${iconSVG.load('install')} ${i18n$('saveFile')}`, + innerHTML: `${iconSVG.load('download')} ${i18n$('saveFile')}`, dataset: { command: 'download-userjs', userjs: ujs.id, @@ -4254,23 +4495,22 @@ function primaryFN() { wrap: 'soft' }); const loadCode = make('mu-jsbtn', { - innerHTML: `${iconSVG.load('search')} ${i18n$('preview_code')}`, + innerHTML: `${iconSVG.load('code')} ${i18n$('preview_code')}`, dataset: { command: 'load-userjs', userjs: ujs.id } }); - if (engine) { - tr.dataset.engine = engine; - // if (engine.includes('fork')) { - // fdaily.dataset.command = 'open-tab'; - // fdaily.dataset.webpage = `${ujs.url}/stats`; - // fupdated.dataset.command = 'open-tab'; - // fupdated.dataset.webpage = `${ujs.url}/versions`; - // } - if (!engine.includes('fork') && cfg.recommend.others && goodUserJS.includes(ujs.url)) { - tr.dataset.good = 'upsell'; + const loadMetadata = make('mu-jsbtn', { + innerHTML: `${iconSVG.load('code')} Metadata`, + dataset: { + command: 'load-header', + userjs: ujs.id } + }); + tr.dataset.engine = engine; + if (!engine.includes('fork') && cfg.recommend.others && goodUserJS.includes(ujs.url)) { + tr.dataset.good = 'upsell'; } for (const u of ujs.users) { const user = make('mujs-a', { @@ -4287,7 +4527,7 @@ function primaryFN() { } uframe.append(user); } - if (engine.includes('fork') && cfg.recommend.others && goodUserJS.includes(ujs.id)) { + if (cfg.recommend.others && goodUserJS.includes(ujs.id)) { tr.dataset.good = 'upsell'; } eframe.append(scriptInstall); @@ -4295,53 +4535,55 @@ function primaryFN() { jsInfo.append(ftotal, ratings, fver, fcreated); mkList(i18n$('code_size'), { list: ujs._mujs.code.code_size, - type: 'size', + type: 'code_size', root: jsInfo }); jsInfoB.append(flicense); + const data_meta = ujs._mujs.code?.data_meta ?? {}; mkList(i18n$('antifeatures'), { - list: ujs._mujs.code.antifeatures, + list: data_meta.antifeatures ?? [], type: 'antifeatures', root: jsInfoB }); mkList(i18n$('applies_to'), { - list: ujs._mujs.code.match, - type: 'match', + list: ujs._mujs.code?.data_names ?? [], + type: 'data_names', root: jsInfoB }); mkList('@grant', { - list: ujs._mujs.code.grant, + list: data_meta.grant ?? [], type: 'grant', root: jsInfoB }); mkList('@require', { - list: ujs._mujs.code.meta?.require, + list: data_meta.require, type: 'require', root: jsInfoB }); - const script_resources = ujs._mujs.code.meta?.resource; mkList('@resource', { - list: isNull(script_resources) ? [] : [script_resources], + list: isNull(data_meta.resource) ? [] : [data_meta.resource], type: 'resource', root: jsInfoB }); fmore.append(jsInfo, jsInfoB); - fBtns.append(scriptDownload, loadCode); + fBtns.append(scriptDownload, loadCode, loadMetadata); fname.append(ftitle, fdesc, fmore, fBtns, codeArea); - const code_data = ujs._mujs.code.data; - if (code_data) { - const code_obj = new ParseUserJS(code_data); - codeArea.value = code_obj.get_code_block(); - } + const loadPage = make('mu-jsbtn', { + innerHTML: `${iconSVG.load('pager')} Page`, + dataset: { + command: 'load-page', + userjs: ujs.id + } + }); + fBtns.append(loadPage); if (ujs._mujs.code?.translated) tr.classList.add('translated'); for (const e of [fname, uframe, fdaily, fupdated, eframe]) tr.append(e); ujs._mujs.root = tr; - - return tr; + return ujs._mujs.root; }; // #endregion const loadFilters = () => { @@ -4399,12 +4641,19 @@ function primaryFN() { this.build = this.build.bind(this); this.toArr = this.toArr.bind(this); this.groupBy = this.groupBy.bind(this); + this.dispatch = this.dispatch.bind(this); this.sortRecords = this.sortRecords.bind(this); if (isEmpty(hostname)) hostname = container.host; this.engines = cfg.engines; this.host = hostname; } + dispatch(ujs) { + const { CustomEvent } = safeSelf(); + const customEvent = new CustomEvent('updateditem', { detail: ujs }); + main.dispatchEvent(customEvent); + } + set host(hostname) { this.intHost = hostname; @@ -4443,7 +4692,7 @@ function primaryFN() { build() { try { container.refresh(); - const { blacklisted, engines, host, toArr } = this; + const { blacklisted, engines, host, toArr, dispatch } = this; if (blacklisted || isEmpty(engines)) { container.opacityMin = '0'; mainframe.style.opacity = container.opacityMin; @@ -4477,92 +4726,59 @@ function primaryFN() { host }, code: { - antifeatures: [], - grant: [], - match: [], meta: {}, request: async function (translate = false, code_url) { - if (this.data) { + if (this.data_code_block) { return this; } - this.data = ''; + code_url = code_url ?? d.code_url; /** @type { string } */ - const code = await Network.req(code_url ?? d.code_url, 'GET', 'text').catch( - showError - ); + const code = await Network.req(code_url, 'GET', 'text').catch(showError); if (typeof code !== 'string') { return this; } - Object.assign(this, { - data: code, - code_size: [Network.format(code.length)] - }); - const grantSet = new Set(); - const afSet = new Set(); - const code_obj = new ParseUserJS(code); - const meta = code_obj.parse_meta(); - const applies_to_names = code_obj.calculate_applies_to_names(); - + const code_obj = new ParseUserJS(code, /\.user\.css/.test(code_url)); + const { data_meta } = code_obj; if (translate) { for (const k of userjs.pool.keys()) { - if (meta[`name:${k}`]) { + if (data_meta[`name:${k}`]) { Object.assign(obj, { - name: meta[`name:${k}`] + name: data_meta[`name:${k}`] }); this.translated = true; } - if (meta[`description:${k}`]) { + if (data_meta[`description:${k}`]) { Object.assign(obj, { - description: meta[`description:${k}`] + description: data_meta[`description:${k}`] }); this.translated = true; } } } - - for (const [key, value] of Object.entries(meta)) { - if (/grant/.test(key)) { - for (const v of normalizeTarget(value, false)) { - if (grantSet.has(v)) { - continue; - } - grantSet.add(v); - } - } else if (/antifeature/.test(key)) { - for (const v of normalizeTarget(value, false)) { - if (afSet.has(v)) { - continue; - } - afSet.add(v); - } - } - } - if (typeof meta.require === 'string') { - const s = meta.require; - meta.require = [s]; + if (Array.isArray(data_meta.grant)) { + data_meta.grant = union(data_meta.grant); } - if (meta.resource) { + if (data_meta.resource) { const obj = {}; - if (typeof meta.resource === 'string') { - const reg = /(.+)\s+(.+)/.exec(meta.resource); + if (typeof data_meta.resource === 'string') { + const reg = /(.+)\s+(.+)/.exec(data_meta.resource); if (reg) { obj[reg[1].trim()] = reg[2]; } } else { - for (const r of meta.resource) { + for (const r of data_meta.resource) { const reg = /(.+)\s+(http.+)/.exec(r); if (reg) { obj[reg[1].trim()] = reg[2]; } } } - meta.resource = obj; + data_meta.resource = obj; } Object.assign(this, { - meta, - match: applies_to_names, - grant: [...grantSet], - antifeatures: [...afSet] + code_size: [Network.format(code.length)], + meta: data_meta, + ...code_obj }); return this; @@ -4637,8 +4853,13 @@ function primaryFN() { finalList = union(hds, filterLang); for (const ujs of finalList) { - if (cfg.codePreview && !ujs._mujs.code.data) { - await ujs._mujs.code.request(); + if ( + !ujs._mujs.code.data_code_block && + (cfg.preview.code || cfg.preview.metadata) + ) { + ujs._mujs.code.request().then(() => { + dispatch(ujs); + }); } createjs(ujs, engine.name); } @@ -4654,7 +4875,8 @@ function primaryFN() { } const selected = htmlDocument.documentElement; if (/openuserjs/gi.test(engine.name)) { - for (const i of qsA('.col-sm-8 .tr-link', selected)) { + const col = qsA('.col-sm-8 .tr-link', selected) ?? []; + for (const i of col) { while (isNull(qs('.script-version', i))) { await new Promise((resolve) => requestAnimationFrame(resolve)); } @@ -4683,8 +4905,13 @@ function primaryFN() { if (bsFilter.match(ujs)) { continue; } - if (cfg.codePreview && !ujs._mujs.code.data) { - await ujs._mujs.code.request(); + if ( + !ujs._mujs.code.data_code_block && + (cfg.preview.code || cfg.preview.metadata) + ) { + ujs._mujs.code.request().then(() => { + dispatch(ujs); + }); } createjs(ujs, engine.name); } @@ -4693,7 +4920,7 @@ function primaryFN() { showError(ex); } }; - const gitFN = async (data) => { + const gitFN = (data) => { try { if (isBlank(data.items)) { showError('Invalid data received from the server, TODO fix this'); @@ -4701,14 +4928,14 @@ function primaryFN() { } for (const r of data.items) { const ujs = _mujs({ - name: r.name, + id: r.repository.id ?? r.id ?? 0, + name: r.repository.name ?? r.name, description: isEmpty(r.repository.description) ? i18n$('no_license') : r.repository.description, - url: r.html_url, + url: r.repository.html_url, code_url: r.html_url.replace(/\/blob\//g, '/raw/'), - code_updated_at: r.commit || Date.now(), - total_installs: r.score, + page_url: `${r.repository.url}/contents/README.md`, users: [ { name: r.repository.owner.login, @@ -4716,11 +4943,30 @@ function primaryFN() { } ] }); - if (bsFilter.match(ujs)) { - continue; - } - if (cfg.codePreview && !ujs._mujs.code.data) { - await ujs._mujs.code.request(); + // if (bsFilter.match(ujs)) { + // continue; + // } + Network.req(r.repository.url, 'GET', 'json', { + headers: { + Accept: 'application/vnd.github+json', + Authorization: `Bearer ${engine.token}`, + 'X-GitHub-Api-Version': '2022-11-28' + } + }).then((repository) => { + ujs.code_updated_at = r.commit || repository.updated_at || Date.now(); + ujs.created_at = repository.created_at; + ujs.daily_installs = repository.watchers_count ?? 0; + ujs.good_ratings = repository.stargazers_count ?? 0; + if (repository.license?.name) ujs.license = repository.license.name; + dispatch(ujs); + }); + if ( + !ujs._mujs.code.data_code_block && + (cfg.preview.code || cfg.preview.metadata) + ) { + ujs._mujs.code.request().then(() => { + dispatch(ujs); + }); } createjs(ujs, engine.name); } @@ -4847,6 +5093,8 @@ function primaryFN() { command: 'reset' } }); + cbtn.append(resetbtn, savebtn); + const makesection = (name, tag) => { tag = tag ?? i18n$('no_license'); name = name ?? i18n$('no_license'); @@ -4871,7 +5119,7 @@ function primaryFN() { } const cmd = target.dataset.command; if (cmd === tag) { - const a = qsA(`label[data-${tag}]`, sec); + const a = qsA(`[data-${tag}]`, sec); if (dom.cl.has(a, 'hidden')) { dom.cl.remove(a, 'hidden'); } else { @@ -4885,133 +5133,24 @@ function primaryFN() { cfgpage.append(sec); return sec; }; - const sections = { general: makesection('General', 'general'), load: makesection('Automation', 'load'), list: makesection('List', 'list'), filters: makesection('List Filters', 'filters'), blacklist: makesection('Blacklist (WIP)', 'blacklist'), - // engine: makesection('Search Engine', 'engine'), - theme: makesection('Theme Colors', 'theme') - }; - - const makerow = (desc, type = null, nm, attrs = {}) => { - desc = desc ?? i18n$('no_license'); - nm = nm ?? i18n$('no_license'); - const sec = make('mujs-section', { - dataset: { - name: nm - } - }); - const lb = make('label'); - const divDesc = make('mu-js', { - textContent: desc - }); - lb.append(divDesc); - sec.append(lb); - cfgpage.append(sec); - if (isNull(type)) { - return lb; - } - const inp = make('input', { - type, - dataset: { - name: nm - }, - ...attrs - }); - if (!cfgMap.has(nm)) { - cfgMap.set(nm, inp); - } - if (type === 'checkbox') { - const inlab = make('mu-js', 'mujs-inlab'); - const la = make('label', { - onclick() { - inp.dispatchEvent(new MouseEvent('click')); - } - }); - inlab.append(inp, la); - lb.append(inlab); - if (nm.includes('-')) { - return inp; - } - if (/(greasy|sleazy)fork|openuserjs|gi(thub|st)/gi.test(nm)) { - const engine = cfg.engines.find((engine) => engine.name === nm); - if (engine) { - inp.checked = engine.enabled; - inp.dataset.engine = engine.name; - ael(inp, 'change', (evt) => { - container.unsaved = true; - container.rebuild = true; - engine.enabled = evt.target.checked; - }); - - if (engine.query) { - const d = DEFAULT_CONFIG.engines.find((e) => e.name === engine.name); - const urlInp = make('input', { - type: 'text', - defaultValue: '', - value: decodeURIComponent(engine.query) ?? '', - placeholder: decodeURIComponent(d.query) ?? '', - dataset: { - name: nm, - engine: engine.name - }, - onchange(evt) { - container.unsaved = true; - container.rebuild = true; - try { - engine.query = encodeURIComponent(new URL(evt.target.value).toString()); - } catch (ex) { - err(ex); - } - } - }); - sec.append(urlInp); - } - if (engine.name === 'github') { - const ghToken = make('input', { - type: 'text', - defaultValue: '', - value: engine.token ?? '', - placeholder: 'Paste Access Token', - dataset: { - engine: 'github-token' - }, - onchange(evt) { - container.unsaved = true; - container.rebuild = true; - engine.token = evt.target.value; - } - }); - sec.append(ghToken); - cfgMap.set('github-token', ghToken); - } - } - } else { - inp.checked = cfg[nm]; - ael(inp, 'change', (evt) => { - container.unsaved = true; - if (/filterlang/i.test(nm)) { - container.rebuild = true; - } - cfg[nm] = evt.target.checked; - }); - } - } else { - lb.append(inp); - } - return inp; + engine: makesection('Search Engines', 'engine'), + theme: makesection('Theme Colors', 'theme'), + exp: makesection('Import / Export', 'exp') }; - const mkSection = (text, value, type = 'checkbox', tag = 'general', attrs = {}) => { - cfgMap.set(text, value); + const makeRow = (text, value, type = 'checkbox', tag = 'general', attrs = {}) => { const lb = make('label', 'sub-section hidden', { textContent: text, dataset: { [tag]: text } }); + cfgMap.set(text, value); if (type === 'select') { const inp = make('select', { dataset: { @@ -5042,6 +5181,10 @@ function primaryFN() { ...attrs }); + if (tag === 'engine') { + inp.dataset.name = value; + } + if (sections[tag]) { sections[tag].append(lb); } @@ -5081,6 +5224,61 @@ function primaryFN() { cfg[value] = evt.target.checked; } }); + + if (tag === 'engine') { + const engine = cfg.engines.find((engine) => engine.name === value); + if (engine) { + inp.checked = engine.enabled; + inp.dataset.engine = engine.name; + ael(inp, 'change', (evt) => { + container.unsaved = true; + container.rebuild = true; + engine.enabled = evt.target.checked; + }); + + if (engine.query) { + const d = DEFAULT_CONFIG.engines.find((e) => e.name === engine.name); + const urlInp = make('input', { + type: 'text', + defaultValue: '', + value: decodeURIComponent(engine.query) ?? '', + placeholder: decodeURIComponent(d.query) ?? '', + dataset: { + name: nm, + engine: engine.name + }, + onchange(evt) { + container.unsaved = true; + container.rebuild = true; + try { + engine.query = encodeURIComponent(new URL(evt.target.value).toString()); + } catch (ex) { + err(ex); + } + } + }); + lb.append(urlInp); + } + if (engine.name === 'github') { + const ghToken = make('input', { + type: 'text', + defaultValue: '', + value: engine.token ?? '', + placeholder: 'Paste Access Token', + dataset: { + engine: 'github-token' + }, + onchange(evt) { + container.unsaved = true; + container.rebuild = true; + engine.token = evt.target.value; + } + }); + lb.append(ghToken); + cfgMap.set('github-token', ghToken); + } + } + } } else { if (type === 'text') { inp.defaultValue = ''; @@ -5094,11 +5292,11 @@ function primaryFN() { return lb; }; if (isGM) { - mkSection(i18n$('userjs_sync'), 'cache'); - mkSection(i18n$('userjs_autoinject'), 'autoinject', 'checkbox', 'load'); + makeRow(i18n$('userjs_sync'), 'cache'); + makeRow(i18n$('userjs_autoinject'), 'autoinject', 'checkbox', 'load'); } - mkSection(i18n$('redirect'), 'sleazyredirect'); - mkSection(`${i18n$('dtime')} (ms)`, 'time', 'number', 'general', { + makeRow(i18n$('redirect'), 'sleazyredirect'); + makeRow(`${i18n$('dtime')} (ms)`, 'time', 'number', 'general', { defaultValue: 10000, value: cfg.time, min: 0, @@ -5126,34 +5324,35 @@ function primaryFN() { } }); - mkSection(i18n$('auto_fetch'), 'autofetch', 'checkbox', 'load'); - mkSection(i18n$('userjs_fullscreen'), 'autoexpand', 'checkbox', 'load', { + makeRow(i18n$('auto_fetch'), 'autofetch', 'checkbox', 'load'); + makeRow(i18n$('userjs_fullscreen'), 'autoexpand', 'checkbox', 'load', { onchange(e) { if (e.target.checked) { dom.cl.add([btnfullscreen, main], 'expanded'); - dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('fsClose')); + dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('collapse')); } else { dom.cl.remove([btnfullscreen, main], 'expanded'); - dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('fsOpen')); + dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('expand')); } } }); - mkSection('Clear on Tab close', 'clearTabCache', 'checkbox', 'load'); + makeRow('Clear on Tab close', 'clearTabCache', 'checkbox', 'load'); - mkSection('Default Sort', 'autoSort', 'select', 'list'); - mkSection(i18n$('filter'), 'filterlang', 'checkbox', 'list'); - mkSection(i18n$('preview_code'), 'codePreview', 'checkbox', 'list'); - mkSection('Recommend author', 'recommend-author', 'checkbox', 'list'); - mkSection('Recommend scripts', 'recommend-others', 'checkbox', 'list'); + makeRow('Default Sort', 'autoSort', 'select', 'list'); + makeRow(i18n$('filter'), 'filterlang', 'checkbox', 'list'); + makeRow(i18n$('preview_code'), 'preview-code', 'checkbox', 'list'); + makeRow('Preview Metadata', 'preview-metadata', 'checkbox', 'list'); + makeRow('Recommend author', 'recommend-author', 'checkbox', 'list'); + makeRow('Recommend scripts', 'recommend-others', 'checkbox', 'list'); for (const [k, v] of Object.entries(cfg.filters)) { - mkSection(v.name, `filters-${k}`, 'checkbox', 'filters'); + makeRow(v.name, `filters-${k}`, 'checkbox', 'filters'); } - makerow('Greasy Fork', 'checkbox', 'greasyfork'); - makerow('Sleazy Fork', 'checkbox', 'sleazyfork'); - makerow('Open UserJS', 'checkbox', 'openuserjs'); - makerow('GitHub API', 'checkbox', 'github'); + makeRow('Greasy Fork', 'greasyfork', 'checkbox', 'engine'); + makeRow('Sleazy Fork', 'sleazyfork', 'checkbox', 'engine'); + makeRow('Open UserJS', 'openuserjs', 'checkbox', 'engine'); + makeRow('GitHub API', 'github', 'checkbox', 'engine'); for (const [k, v] of Object.entries(cfg.theme)) { const lb = make('label', 'hidden', { @@ -5207,6 +5406,66 @@ function primaryFN() { sections.theme.append(lb); } + // const blacklist = make('textarea', { + // dataset: { + // name: 'blacklist' + // }, + // rows: '10', + // autocomplete: false, + // spellcheck: false, + // wrap: 'soft', + // value: JSON.stringify(cfg.blacklist, null, ' '), + // oninput(evt) { + // let isvalid = true; + // try { + // cfg.blacklist = JSON.parse(evt.target.value); + // isvalid = true; + // } catch (ex) { + // err(ex); + // isvalid = false; + // } finally { + // if (isvalid) { + // dom.cl.remove(evt.target, 'mujs-invalid'); + // dom.prop(savebtn, 'disabled', false); + // } else { + // dom.cl.add(evt.target, 'mujs-invalid'); + // dom.prop(savebtn, 'disabled', true); + // } + // } + // } + // }); + // cfgMap.set('blacklist', blacklist); + // const addList = make('mujs-add', { + // textContent: '+', + // dataset: { + // command: 'new-list' + // } + // }); + // const n = make('input', { + // type: 'text', + // defaultValue: '', + // value: '', + // placeholder: 'Name', + // }); + // const inpValue = make('input', { + // type: 'text', + // defaultValue: '', + // value: '', + // placeholder: 'Value', + // }); + // const label = make('label', 'new-list hidden', { + // dataset: { + // blacklist: 'new-list' + // } + // }); + // label.append(n, inpValue, addList); + // listSec.append(label); + // ael(addList, 'click', () => { + // if (isEmpty(n.value) || isEmpty(inpValue.value)) { + // return + // }; + // createList(n.value, n.value, inpValue.value); + // }); const createList = (key, v = '', disabled = false, type = 'String') => { let txt = key; if (typeof key === 'string') { @@ -5292,72 +5551,50 @@ function primaryFN() { lb.append(inp, selType); sections.blacklist.append(lb); }; - // const blacklist = make('textarea', { - // dataset: { - // name: 'blacklist' - // }, - // rows: '10', - // autocomplete: false, - // spellcheck: false, - // wrap: 'soft', - // value: JSON.stringify(cfg.blacklist, null, ' '), - // oninput(evt) { - // let isvalid = true; - // try { - // cfg.blacklist = JSON.parse(evt.target.value); - // isvalid = true; - // } catch (ex) { - // err(ex); - // isvalid = false; - // } finally { - // if (isvalid) { - // dom.cl.remove(evt.target, 'mujs-invalid'); - // dom.prop(savebtn, 'disabled', false); - // } else { - // dom.cl.add(evt.target, 'mujs-invalid'); - // dom.prop(savebtn, 'disabled', true); - // } - // } - // } - // }); - // cfgMap.set('blacklist', blacklist); - // const addList = make('mujs-add', { - // textContent: '+', - // dataset: { - // command: 'new-list' - // } - // }); - // const n = make('input', { - // type: 'text', - // defaultValue: '', - // value: '', - // placeholder: 'Name', - // }); - // const inpValue = make('input', { - // type: 'text', - // defaultValue: '', - // value: '', - // placeholder: 'Value', - // }); - // const label = make('label', 'new-list hidden', { - // dataset: { - // blacklist: 'new-list' - // } - // }); - // label.append(n, inpValue, addList); - // listSec.append(label); - // ael(addList, 'click', () => { - // if (isEmpty(n.value) || isEmpty(inpValue.value)) { - // return - // }; - // createList(n.value, n.value, inpValue.value); - // }); - for (const key of cfg.blacklist) { createList(key); } - cbtn.append(resetbtn, savebtn); + const transfers = { + export: { + cfg: make('mujs-btn', 'mujs-export sub-section hidden', { + textContent: i18n$('export_config'), + dataset: { + command: 'export-cfg', + exp: 'export-cfg' + } + }), + theme: make('mujs-btn', 'mujs-export sub-section hidden', { + textContent: i18n$('export_theme'), + dataset: { + command: 'export-theme', + exp: 'export-theme' + } + }) + }, + import: { + cfg: make('mujs-btn', 'mujs-import sub-section hidden', { + textContent: i18n$('import_config'), + dataset: { + command: 'import-cfg', + exp: 'import-cfg' + } + }), + theme: make('mujs-btn', 'mujs-import sub-section hidden', { + textContent: i18n$('import_theme'), + dataset: { + command: 'import-theme', + exp: 'import-theme' + } + }) + } + }; + for (const value of Object.values(transfers)) { + for (const v of Object.values(value)) { + sections.exp.append(v); + } + } + cfgpage.append(cbtn); }; // #endregion @@ -5384,7 +5621,7 @@ function primaryFN() { dom.cl.add(mainframe, 'hidden'); if (cfg.autoexpand) { dom.cl.add([btnfullscreen, main], 'expanded'); - dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('fsClose')); + dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('collapse')); } if (dom.cl.has(mainframe, 'error')) { tab.create('mujs:settings'); @@ -5512,11 +5749,8 @@ function primaryFN() { for (const v of cacheValues) { if (v.name && v.name.match(reg)) finds.add(v._mujs.root); if (v.description && v.description.match(reg)) finds.add(v._mujs.root); - const code_data = v._mujs.code.data; - if (code_data) { - const code_obj = new ParseUserJS(code_data); - const meta = code_obj.parse_meta(code_data); - for (const key of Object.keys(meta)) { + if (v._mujs.code.data_meta) { + for (const key of Object.keys(v._mujs.code.data_meta)) { if (/name|desc/i.test(key) && key.match(reg)) finds.add(v._mujs.root); } } diff --git a/package.json b/package.json index bb6b904..3b7f4ba 100644 --- a/package.json +++ b/package.json @@ -80,8 +80,8 @@ "sourceDir": "./build/firefox" }, "engines": { - "node": ">=18", - "pnpm": ">=9" + "node": ">=20", + "pnpm": ">=10" }, "packageManager": "pnpm@10.3.0+sha512.ee592eda8815a8a293c206bb0917c4bb0ff274c50def7cbc17be05ec641fc2d1b02490ce660061356bd0d126a4d7eb2ec8830e6959fb8a447571c631d5a2442d", "pnpm": { diff --git a/src/UserJS/main.js b/src/UserJS/main.js index 87c6905..941cb25 100644 --- a/src/UserJS/main.js +++ b/src/UserJS/main.js @@ -50,6 +50,65 @@ const log = (...msg) => { */ let cfg = {}; +// #region Validators +/** + * @type { import("../typings/types.d.ts").objToStr } + */ +const objToStr = (obj) => Object.prototype.toString.call(obj); +/** + * @type { import("../typings/types.d.ts").isRegExp } + */ +const isRegExp = (obj) => { + const s = objToStr(obj); + return s.includes('RegExp'); +}; +/** + * @type { import("../typings/types.d.ts").isElem } + */ +const isElem = (obj) => { + const s = objToStr(obj); + return s.includes('Element'); +}; +/** + * @type { import("../typings/types.d.ts").isObj } + */ +const isObj = (obj) => { + const s = objToStr(obj); + return s.includes('Object'); +}; +/** + * @type { import("../typings/types.d.ts").isFN } + */ +const isFN = (obj) => { + const s = objToStr(obj); + return s.includes('Function'); +}; +/** + * @type { import("../typings/types.d.ts").isNull } + */ +const isNull = (obj) => { + return Object.is(obj, null) || Object.is(obj, undefined); +}; +/** + * @type { import("../typings/types.d.ts").isBlank } + */ +const isBlank = (obj) => { + return ( + (typeof obj === 'string' && Object.is(obj.trim(), '')) || + ((obj instanceof Set || obj instanceof Map) && Object.is(obj.size, 0)) || + (Array.isArray(obj) && Object.is(obj.length, 0)) || + (isObj(obj) && Object.is(Object.keys(obj).length, 0)) + ); +}; +/** + * @type { import("../typings/types.d.ts").isEmpty } + */ +const isEmpty = (obj) => { + return isNull(obj) || isBlank(obj); +}; +// #endregion + +// #region Globals /** * https://github.com/zloirock/core-js/blob/master/packages/core-js/internals/global-this.js * @returns {typeof globalThis} @@ -69,7 +128,6 @@ function globalWin() { Function('return this')() ); } - /** @type { import("../typings/UserJS.d.ts").safeSelf } */ function safeSelf() { if (userjs.safeSelf) { @@ -79,6 +137,7 @@ function safeSelf() { /** @type { import("../typings/UserJS.d.ts").safeHandles } */ const safe = { XMLHttpRequest: g.XMLHttpRequest, + CustomEvent: g.CustomEvent, createElement: g.document.createElement.bind(g.document), createElementNS: g.document.createElementNS.bind(g.document), createTextNode: g.document.createTextNode.bind(g.document), @@ -115,9 +174,20 @@ function safeSelf() { } } }; + for (const [k, v] of Object.entries(safe)) { + if (k === 'scheduler') { + continue; + } else if (k === 'navigator') { + continue; + } else if (isFN(v)) { + continue; + } + err({ message: `Safe handles "${k}" returned "${v}"`, cause: 'safeSelf' }); + } userjs.safeSelf = safe; return userjs.safeSelf; } +// #endregion const BLANK_PAGE = 'about:blank'; // Lets highlight me :) @@ -212,12 +282,15 @@ const DEFAULT_CONFIG = { autoSort: 'daily_installs', clearTabCache: true, cache: true, - codePreview: false, autoexpand: false, filterlang: false, sleazyredirect: false, time: 10000, blacklist: ['userjs-local', 'userjs-finance', 'userjs-social', 'userjs-unsupported'], + preview: { + code: false, + metadata: false + }, engines: [ { enabled: true, @@ -369,61 +442,6 @@ const qsA = (selectors, root) => { } return []; }; -/** - * @type { import("../typings/types.d.ts").objToStr } - */ -const objToStr = (obj) => Object.prototype.toString.call(obj); -/** - * @type { import("../typings/types.d.ts").isRegExp } - */ -const isRegExp = (obj) => { - const s = objToStr(obj); - return s.includes('RegExp'); -}; -/** - * @type { import("../typings/types.d.ts").isElem } - */ -const isElem = (obj) => { - const s = objToStr(obj); - return s.includes('Element'); -}; -/** - * @type { import("../typings/types.d.ts").isObj } - */ -const isObj = (obj) => { - const s = objToStr(obj); - return s.includes('Object'); -}; -/** - * @type { import("../typings/types.d.ts").isFN } - */ -const isFN = (obj) => { - const s = objToStr(obj); - return s.includes('Function'); -}; -/** - * @type { import("../typings/types.d.ts").isNull } - */ -const isNull = (obj) => { - return Object.is(obj, null) || Object.is(obj, undefined); -}; -/** - * @type { import("../typings/types.d.ts").isBlank } - */ -const isBlank = (obj) => { - return ( - (typeof obj === 'string' && Object.is(obj.trim(), '')) || - ((obj instanceof Set || obj instanceof Map) && Object.is(obj.size, 0)) || - (Array.isArray(obj) && Object.is(obj.length, 0)) || - (isObj(obj) && Object.is(Object.keys(obj).length, 0)) - ); -}; -/** - * @type { import("../typings/types.d.ts").isEmpty } - */ -const isEmpty = (obj) => { - return isNull(obj) || isBlank(obj); -}; /** * @type { import("../typings/types.d.ts").normalizeTarget } */ @@ -627,61 +645,57 @@ class Memorize { const memory = new Memorize(); //#region Icon SVGs const iconSVG = { - cfg: { - viewBox: '0 0 24 24', - html: '' - }, close: { - viewBox: '0 0 24 24', - html: '' + viewBox: '0 0 384 512', + html: '' }, - filter: { - viewBox: '0 0 24 24', - html: '' + code: { + viewBox: '0 0 640 512', + html: '' }, - fsClose: { - viewBox: '0 0 24 24', - html: ' ' + collapse: { + viewBox: '0 0 448 512', + html: '' }, - fsOpen: { - viewBox: '0 0 24 24', - html: ' ' + download: { + viewBox: '0 0 384 512', + html: '' }, - fullscreen: { - viewBox: '0 0 96 96', - html: '' + expand: { + viewBox: '0 0 448 512', + html: '' }, - gf: { - viewBox: '0 0 510.4 510.4', - html: '' + gear: { + viewBox: '0 0 512 512', + html: '' }, - gh: { - viewBox: '0 0 16 16', - html: '' + github: { + viewBox: '0 0 496 512', + html: '' }, - hide: { - viewBox: '0 0 24 24', - html: ' ' + globe: { + viewBox: '0 0 512 512', + html: '' }, install: { - viewBox: '0 0 16 16', - html: '' + viewBox: '0 0 512 512', + html: '' }, issue: { - viewBox: '0 0 24 24', - html: '' + viewBox: '0 0 512 512', + html: '' }, - nav: { - viewBox: '0 0 24 24', - html: ' ' + minus: { + viewBox: '0 0 448 512', + html: '' }, - plus: { - viewBox: '0 0 24 24', - html: '' + nav: { + viewBox: '0 0 448 512', + html: '' }, - search: { - viewBox: '0 0 24 24', - html: '' + pager: { + viewBox: '0 0 512 512', + html: '' }, verified: { viewBox: '0 0 56 56', @@ -690,9 +704,9 @@ const iconSVG = { html: '' }, refresh: { - viewBox: '0 0 1024 1024', + viewBox: '0 0 512 512', fill: 'currentColor', - html: '' + html: '' }, load(type, container) { const { createElementNS } = safeSelf(); @@ -1036,6 +1050,7 @@ const Counter = { } } }; + // #region Container /** * @type { import("../typings/UserJS.d.ts").Container } @@ -1101,11 +1116,7 @@ class Container { } }); if (this.supported) { - this.shadowRoot = this.frame.attachShadow({ - mode: 'closed' - // clonable: false, - // delegatesfocus: false - }); + this.shadowRoot = this.frame.attachShadow({ mode: 'closed' }); this.ready = true; } this.cache = memory.maps.container; @@ -1124,6 +1135,7 @@ class Container { } set(delay, reason) { + const { setTimeout } = safeSelf(); return new Promise((resolve, reject) => { const id = setTimeout(() => { Object.is(reason, null) || Object.is(reason, undefined) ? resolve() : reject(reason); @@ -1134,6 +1146,7 @@ class Container { } clear(...ids) { + const { clearTimeout } = safeSelf(); this.ids = this.ids.filter((id) => { if (ids.includes(id)) { clearTimeout(id); @@ -1199,7 +1212,7 @@ class Container { Counter.cnt.total.root = this.mainbtn; for (const engine of cfg.engines) this.countframe.append(Counter.set(engine)); - const { cfgpage, table, exBtn, supported, frame, refresh, cache, urlBar, host } = this; + const { cfgpage, table, supported, frame, refresh, cache, urlBar, host } = this; class Tabs { /** @@ -1244,7 +1257,7 @@ class Container { return; } if (hostname.match(this.protoReg)[1] === 'settings') { - dom.cl.remove([cfgpage, exBtn], 'hidden'); + dom.cl.remove(cfgpage, 'hidden'); dom.cl.add(table, 'hidden'); if (!supported) { dom.attr(frame, 'style', 'height: 100%;'); @@ -1257,7 +1270,7 @@ class Container { */ active(tab, build = true) { if (!this.pool.has(tab)) this.pool.add(tab); - dom.cl.add([cfgpage, exBtn], 'hidden'); + dom.cl.add(cfgpage, 'hidden'); dom.cl.remove(table, 'hidden'); dom.cl.remove([...this.pool], 'active'); dom.cl.add(tab, 'active'); @@ -1339,8 +1352,7 @@ class Container { this.tab.create(host); const tabbody = this.tabbody; - const getCellValue = (tr, idx) => - tr.children[idx].dataset.value || tr.children[idx].innerText || tr.children[idx].textContent; + const getCellValue = (tr, idx) => tr.children[idx].dataset.value; const comparer = (idx, asc) => (a, b) => ((v1, v2) => v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) @@ -1387,43 +1399,18 @@ class Container { this.tbody = make('mujs-body'); this.cfgpage = make('mujs-row', 'mujs-cfg hidden'); this.btnframe = make('mujs-column', 'btn-frame'); - this.exBtn = make('mujs-column', 'mujs-sty-flex hidden'); this.fsearch = make('mujs-btn', 'hidden'); - this.exportCFG = make('mujs-btn', 'mujs-export', { - textContent: i18n$('export_config'), - dataset: { - command: 'export-cfg' - } - }); - this.importCFG = make('mujs-btn', 'mujs-import', { - textContent: i18n$('import_config'), - dataset: { - command: 'import-cfg' - } - }); - this.exportTheme = make('mujs-btn', 'mujs-export', { - textContent: i18n$('export_theme'), - dataset: { - command: 'export-theme' - } - }); - this.importTheme = make('mujs-btn', 'mujs-import', { - textContent: i18n$('import_theme'), - dataset: { - command: 'import-theme' - } - }); this.btnHandles = make('mujs-column', 'btn-handles'); this.btnHide = make('mujs-btn', 'hide-list', { title: i18n$('min'), - innerHTML: iconSVG.load('hide'), + innerHTML: iconSVG.load('minus'), dataset: { command: 'hide-list' } }); this.btnfullscreen = make('mujs-btn', 'fullscreen', { title: i18n$('max'), - innerHTML: iconSVG.load('fullscreen'), + innerHTML: iconSVG.load('expand'), dataset: { command: 'fullscreen' } @@ -1439,7 +1426,7 @@ class Container { }); this.btncfg = make('mujs-btn', 'settings hidden', { title: 'Settings', - innerHTML: iconSVG.load('cfg'), + innerHTML: iconSVG.load('gear'), dataset: { command: 'settings' } @@ -1450,7 +1437,7 @@ class Container { ? $info.script.version : $info.script.version.slice(0, 5) })`, - innerHTML: iconSVG.load('gh'), + innerHTML: iconSVG.load('github'), dataset: { command: 'open-tab', webpage: $info.script.namespace @@ -1466,7 +1453,7 @@ class Container { }); this.btngreasy = make('mujs-btn', 'greasy hidden', { title: 'Greasy Fork', - innerHTML: iconSVG.load('gf'), + innerHTML: iconSVG.load('globe'), dataset: { command: 'open-tab', webpage: 'https://greasyfork.org/scripts/421603' @@ -1507,17 +1494,30 @@ class Container { } ]); // #endregion - - this.btnHandles.append(this.btnHide, this.btnfullscreen, this.closebtn); - this.btnframe.append(this.btnhome, this.btngreasy, this.btnissue, this.btncfg, this.btnnav); + if (isMobile) { + dom.cl.add([this.btnHide, this.btnfullscreen, this.closebtn], 'hidden'); + this.btnframe.append( + this.btnHide, + this.btnfullscreen, + this.closebtn, + this.btnhome, + this.btngreasy, + this.btnissue, + this.btncfg, + this.btnnav + ); + } else { + this.btnHandles.append(this.btnHide, this.btnfullscreen, this.closebtn); + this.btnframe.append(this.btnhome, this.btngreasy, this.btnissue, this.btncfg, this.btnnav); + } this.toolbar.append(this.btnHandles); this.urlContainer.append(this.urlBar); this.header.append(this.urlContainer, this.rateContainer, this.countframe, this.btnframe); this.tbody.append(this.table, this.cfgpage); this.main.append(this.toolbar, this.header, this.tbody, this.footer, this.promptElem); this.mainframe.append(this.mainbtn); - this.exBtn.append(this.importCFG, this.importTheme, this.exportCFG, this.exportTheme); - this.header.append(this.exBtn); + // this.exBtn.append(this.importCFG, this.importTheme, this.exportCFG, this.exportTheme); + // this.header.append(this.exBtn); this.root.append(this.mainframe, this.main); return true; @@ -1816,10 +1816,6 @@ function primaryFN() { fsearch, btnfullscreen, main, - btncfg, - btnhome, - btnissue, - btngreasy, tab, showError } = container; @@ -1864,8 +1860,75 @@ function primaryFN() { installLink.remove(); await init(); }; + const applyTo = (ujs, name, elem, root) => { + const n = ujs._mujs.code[name] ?? ujs._mujs.code.data_meta[name]; + if (isEmpty(n)) { + const el = make('mujs-a', { + textContent: i18n$('listing_none') + }); + elem.append(el); + return; + } + dom.prop(elem, 'innerHTML', ''); + dom.cl.remove(root, 'hidden'); + if (isObj(n)) { + if (name === 'resource') { + for (const [k, v] of Object.entries(n)) { + const el = make('mujs-a', { + textContent: k ?? 'ERROR' + }); + if (v.startsWith('http')) { + el.dataset.command = 'open-tab'; + el.dataset.webpage = v; + } + elem.append(el); + } + } else { + const el = make('mujs-a', { + textContent: n.text + }); + if (n.domain) { + el.dataset.command = 'open-tab'; + el.dataset.webpage = `https://${n.text}`; + } + elem.append(el); + } + } else if (typeof n === 'string') { + const el = make('mujs-a', { + textContent: n + }); + elem.append(el); + } else { + for (const c of n) { + if (typeof c === 'string' && c.startsWith('http')) { + const el = make('mujs-a', { + textContent: c, + dataset: { + command: 'open-tab', + webpage: c + } + }); + elem.append(el); + } else if (isObj(c)) { + const el = make('mujs-a', { + textContent: c.text + }); + if (c.domain) { + el.dataset.command = 'open-tab'; + el.dataset.webpage = `https://${c.text}`; + } + elem.append(el); + } else { + const el = make('mujs-a', { + textContent: c + }); + elem.append(el); + } + } + } + }; // #region Main event handlers - ael(main, 'click', async (evt) => { + ael(main, isMobile ? 'touchend' : 'click', async (evt) => { try { /** @type { HTMLElement } */ const target = evt.target.closest('[data-command]'); @@ -1911,10 +1974,13 @@ function primaryFN() { } return window.open(dataset.webpage, '_blank'); } else if (cmd === 'navigation') { - if (dom.cl.has(btngreasy, 'hidden')) { - dom.cl.remove([btncfg, btngreasy, btnhome, btnissue], 'hidden'); - } else { - dom.cl.add([btncfg, btngreasy, btnhome, btnissue], 'hidden'); + for (const e of qsA('mujs-btn', target.parentElement)) { + if (dom.cl.has(e, 'nav')) continue; + if (dom.cl.has(e, 'hidden')) { + dom.cl.remove(e, 'hidden'); + } else { + dom.cl.add(e, 'hidden'); + } } } else if (cmd === 'list-description') { const arr = []; @@ -1946,10 +2012,10 @@ function primaryFN() { } else if (cmd === 'fullscreen') { if (dom.cl.has(btnfullscreen, 'expanded')) { dom.cl.remove([btnfullscreen, main], 'expanded'); - dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('fsOpen')); + dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('expand')); } else { dom.cl.add([btnfullscreen, main], 'expanded'); - dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('fsClose')); + dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('collapse')); } } else if (cmd === 'hide-list') { dom.cl.add(main, 'hidden'); @@ -2018,81 +2084,115 @@ function primaryFN() { dlBtn.click(); URL.revokeObjectURL(dlBtn.href); dlBtn.remove(); - } else if (cmd === 'load-userjs') { + } else if (cmd === 'load-userjs' || cmd === 'load-header') { if (!container.userjsCache.has(+dataset.userjs)) { return; } const codeArea = qs('textarea', target.parentElement.parentElement); - if (!isEmpty(codeArea.value)) { + if (!isEmpty(codeArea.value) && cmd === codeArea.dataset.load) { dom.cl.toggle(codeArea, 'hidden'); return; } + codeArea.dataset.load = cmd; const dataUserJS = container.userjsCache.get(+dataset.userjs); - const r = await dataUserJS._mujs.code.request(); - const txt = r.data; - if (typeof txt !== 'string') { + const code_obj = await dataUserJS._mujs.code.request(); + if (typeof code_obj.data_code_block !== 'string') { + codeArea.value = 'An error occured'; return; } - const code_obj = new ParseUserJS(txt); - codeArea.value = code_obj.get_code_block(); + codeArea.value = + cmd === 'load-userjs' ? code_obj.data_code_block : code_obj.data_meta_block; dom.cl.remove(codeArea, 'hidden'); - const apTo = (name, elem, root) => { - const n = dataUserJS._mujs.code[name]; - if (isEmpty(n)) { - const el = make('mujs-a', { - textContent: i18n$('listing_none') + for (const e of qsA( + 'mujs-column[data-el="matches"]', + target.parentElement.parentElement + )) { + applyTo(dataUserJS, e.dataset.type, qs('.mujs-grants', e), e); + } + } else if (cmd === 'load-page') { + if (!container.userjsCache.has(+dataset.userjs)) { + return; + } + let pageArea = qs('mujs-page', target.parentElement.parentElement); + if (!pageArea) { + pageArea = make('mujs-page'); + target.parentElement.parentElement.append(pageArea); + const dataUserJS = container.userjsCache.get(+dataset.userjs); + const engine = dataUserJS._mujs.info.engine; + let pageURL; + if (engine.name.includes('fork')) { + const { navigator } = safeSelf(); + const current = navigator.language.split('-')[0] ?? 'en'; + pageURL = dataUserJS.url.replace( + /\/scripts/, + `/${/^(zh|fr|es)/.test(current) ? navigator.language : current}/scripts` + ); + } else if (engine.name.includes('github')) { + const page_url = await Network.req(dataUserJS.page_url, 'GET', 'json', { + headers: { + Accept: 'application/vnd.github+json', + Authorization: `Bearer ${engine.token}`, + 'X-GitHub-Api-Version': '2022-11-28' + } + }).catch(() => { + return {}; }); - elem.append(el); + if (!page_url.download_url) { + return; + } + const page = await Network.req(page_url.download_url, 'GET', 'text'); + if (container.supported) { + const shadow = pageArea.attachShadow({ mode: 'closed' }); + const div = make('div', { + innerHTML: page + }); + shadow.append(div); + } return; + } else { + pageURL = dataUserJS.url; } - dom.prop(elem, 'innerHTML', ''); - dom.cl.remove(root, 'hidden'); - for (const c of n) { - if (typeof c === 'string' && c.startsWith('http')) { - const el = make('mujs-a', { - textContent: c, - dataset: { - command: 'open-tab', - webpage: c - } - }); - elem.append(el); - } else if (isObj(c)) { - if (name === 'resource') { - for (const [k, v] of Object.entries(c)) { - const el = make('mujs-a', { - textContent: k ?? 'ERROR' - }); - if (v.startsWith('http')) { - el.dataset.command = 'open-tab'; - el.dataset.webpage = v; - } - elem.append(el); - } - } else { - const el = make('mujs-a', { - textContent: c.text - }); - if (c.domain) { - el.dataset.command = 'open-tab'; - el.dataset.webpage = `https://${c.text}`; - } - elem.append(el); + if (!pageURL) { + return; + } + const page = await Network.req(pageURL, 'GET', 'document'); + const getContent = () => { + let content = 'An error occured'; + const h = new URL(dataUserJS.url); + const root = qs('.user-content', page.documentElement); + for (const e of qsA('[href]', root)) { + e.target = '_blank'; + e.style = 'pointer-events: auto;'; + if (e.href.startsWith('/')) { + e.href = `${h.origin}${e.href}`; } + } + for (const e of qsA('img[src]', root)) { + e.style = + 'max-width: 25em; max-height: 25em; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;'; + } + if (root) { + content = root.innerHTML; } else { - const el = make('mujs-a', { - textContent: c - }); - elem.append(el); + content = 'No additional info available'; } + return content; + }; + if (container.supported) { + const shadow = pageArea.attachShadow({ mode: 'closed' }); + const div = make('div', { + style: 'pointer-events: none;', + innerHTML: getContent() + }); + shadow.append(div); } - }; - for (const e of qsA( - 'mujs-column[data-el="matches"]', - target.parentElement.parentElement - )) { - apTo(e.dataset.type, qs('.mujs-grants', e), e); + return; + } + if (!dom.cl.has(pageArea, 'hidden')) { + dom.cl.add(pageArea, 'hidden'); + return; } + dom.cl.remove(pageArea, 'hidden'); } else if (/export-/.test(cmd)) { const str = JSON.stringify(cmd === 'export-cfg' ? cfg : cfg.theme, null, ' '); const bytes = new TextEncoder().encode(str); @@ -2193,9 +2293,50 @@ function primaryFN() { }); } } + ael(main, 'updateditem', (evt) => { + /** + * @type {import("../typings/types.d.ts").GSForkQuery} + */ + const ujs = evt.detail; + if (!ujs._mujs) return; + for (const elem of qsA('[data-name]', ujs._mujs.root)) { + const name = elem.dataset.name; + if (name === 'code') { + if (ujs._mujs.code.data_code_block) { + if (cfg.preview.code && !cfg.preview.metadata) { + elem.value = ujs._mujs.code.data_code_block; + } else if (cfg.preview.metadata && !cfg.preview.code) { + elem.value = ujs._mujs.code.data_meta_block; + } else { + elem.value = `${ujs._mujs.code.META_START_COMMENT}${ujs._mujs.code.data_meta_block}${ujs._mujs.code.META_END_COMMENT}${ujs._mujs.code.data_code_block}`; + } + } + continue; + } + if (!ujs[name]) continue; + if (name === 'license') { + dom.attr(elem, 'title', ujs.license ?? i18n$('no_license')); + dom.text(elem, `${i18n$('license')}: ${ujs.license ?? i18n$('no_license')}`); + } else if (name === 'code_updated_at') { + dom.text(elem, language.toDate(ujs.code_updated_at)); + elem.dataset.value = new Date(ujs.code_updated_at).toISOString(); + } else if (name === 'created_date') { + dom.text(elem, `${i18n$('created_date')}: ${language.toDate(ujs.created_at)}`); + elem.dataset.value = new Date(ujs.created_at).toISOString(); + } else if (name === 'total_installs') { + dom.text(elem, `${i18n$('total_installs')}: ${language.toNumber(ujs.total_installs)}`); + } else { + dom.text(elem, ujs[name]); + } + } + if (ujs._mujs.code.data_code_block) { + for (const e of qsA('mujs-column[data-el="matches"]', ujs._mujs.root)) { + applyTo(ujs, e.dataset.type, qs('.mujs-grants', e), e); + } + } + if (container.userjsCache.has(ujs.id)) container.userjsCache.set(ujs.id, ujs); + }); // #endregion - const META_START_COMMENT = '// ==UserScript=='; - const META_END_COMMENT = '// ==/UserScript=='; const TLD_EXPANSION = ['com', 'net', 'org', 'de', 'co.uk']; const APPLIES_TO_ALL_PATTERNS = [ 'http://*', @@ -2223,15 +2364,17 @@ function primaryFN() { */ data_code_block; /** - * @type { { [meta: string]: any } } + * @type { { [meta: string]: string | string[] | { [resource: string]: string } } } */ data_meta; /** - * @type { string[] } + * @type { {text: string;domain: boolean;tld_extra: boolean}[] } */ data_names; - constructor(code) { + constructor(code, isUserCSS) { this.code = code; + this.META_START_COMMENT = isUserCSS ? '/* ==UserStyle==' : '// ==UserScript=='; + this.META_END_COMMENT = isUserCSS ? '==/UserStyle== */' : '// ==/UserScript=='; this.get_meta_block(); this.get_code_block(); this.parse_meta(); @@ -2244,17 +2387,20 @@ function primaryFN() { if (this.data_meta_block) { return this.data_meta_block; } - const start_block = this.code.indexOf(META_START_COMMENT); + const start_block = this.code.indexOf(this.META_START_COMMENT); if (isNull(start_block)) { return null; } - const end_block = this.code.indexOf(META_END_COMMENT, start_block); + const end_block = this.code.indexOf(this.META_END_COMMENT, start_block); if (isNull(end_block)) { return null; } - const meta_block = this.code.substring(start_block + META_START_COMMENT.length, end_block); + const meta_block = this.code.substring( + start_block + this.META_START_COMMENT.length, + end_block + ); this.data_meta_block = meta_block; - return meta_block; + return this.data_meta_block; } get_code_block() { if (isEmpty(this.code)) { @@ -2263,28 +2409,23 @@ function primaryFN() { if (this.data_code_block) { return this.data_code_block; } - const start_block = this.code.indexOf(META_START_COMMENT); + const start_block = this.code.indexOf(this.META_START_COMMENT); if (isNull(start_block)) { return null; } - const end_block = this.code.indexOf(META_END_COMMENT, start_block); + const end_block = this.code.indexOf(this.META_END_COMMENT, start_block); if (isNull(end_block)) { return null; } const code_block = this.code.substring( - end_block + META_END_COMMENT.length, + end_block + this.META_END_COMMENT.length, this.code.length ); - const lines = []; - for (const l of code_block.split('\n')) { - if (isEmpty(l)) { - continue; - } - lines.push(l); - } - const clean_code = lines.join('\n'); - this.data_code_block = clean_code; - return clean_code; + this.data_code_block = code_block + .split('\n') + .filter((l) => !isEmpty(l)) + .join('\n'); + return this.data_code_block; } parse_meta() { if (isEmpty(this.code)) { @@ -2294,11 +2435,10 @@ function primaryFN() { return this.data_meta; } const meta = {}; - const meta_block = this.get_meta_block(); const meta_block_map = new Map(); - for (const meta_line of meta_block.split('\n')) { - const meta_match = meta_line.match(/\/\/\s+@([a-zA-Z:-]+)\s+(.*)/); - if (isNull(meta_match)) { + for (const meta_line of this.get_meta_block().split('\n')) { + const meta_match = /\/\/\s+@([a-zA-Z:-]+)\s+(.*)/.exec(meta_line); + if (!meta_match) { continue; } const key = meta_match[1].trim(); @@ -2320,9 +2460,6 @@ function primaryFN() { this.data_meta = meta; return this.data_meta; } - /** - * @returns { string[] } - */ calculate_applies_to_names() { if (isEmpty(this.code)) { return null; @@ -2330,10 +2467,9 @@ function primaryFN() { if (this.data_names) { return this.data_names; } - const meta = this.parse_meta(); let patterns = []; - for (const [k, v] of Object.entries(meta)) { - if (/include|match/.test(k)) { + for (const [k, v] of Object.entries(this.parse_meta())) { + if (/include|match/i.test(k)) { if (Array.isArray(v)) { patterns = patterns.concat(v); } else { @@ -2345,14 +2481,21 @@ function primaryFN() { return []; } if (this.intersect(patterns, APPLIES_TO_ALL_PATTERNS)) { - return []; + this.data_names = [ + { + domain: false, + text: 'All sites', + tld_extra: false + } + ]; + return this.data_names; } - const name_set = new Set(); + const name_map = new Map(); const addObj = (obj) => { - if (name_set.has(obj)) { + if (name_map.has(obj.text)) { return; } - name_set.add(obj); + name_map.set(obj.text, obj); }; for (let p of patterns) { try { @@ -2361,8 +2504,8 @@ function primaryFN() { if (p.match(/^\/(.*)\/$/)) { pre_wildcards = [p]; } else { - let m = p.match(/^\*(https?:.*)/i); - if (!isNull(m)) { + let m = /^\*(https?:.*)/i.exec(p); + if (m) { p = m[1]; } p = p @@ -2370,20 +2513,20 @@ function primaryFN() { .replace(/^\*\/\//i, 'http://') .replace(/^http\*:/i, 'http:') .replace(/^(https?):([^/])/i, '$1://$2'); - m = p.match(/^([a-z]+:\/\/)\*\.?([a-z0-9-]+(?:.[a-z0-9-]+)+.*)/i); - if (!isNull(m)) { + m = /^([a-z]+:\/\/)\*\.?([a-z0-9-]+(?:.[a-z0-9-]+)+.*)/i.exec(p); + if (m) { p = m[1] + m[2]; } - m = p.match(/^\*\.?([a-z0-9-]+\.[a-z0-9-]+.*)/i); - if (!isNull(m)) { + m = /^\*\.?([a-z0-9-]+\.[a-z0-9-]+.*)/i.exec(p); + if (m) { p = `http://${m[1]}`; } - m = p.match(/^http\*(?:\/\/)?\.?((?:[a-z0-9-]+)(?:\.[a-z0-9-]+)+.*)/i); - if (!isNull(m)) { + m = /^http\*(?:\/\/)?\.?((?:[a-z0-9-]+)(?:\.[a-z0-9-]+)+.*)/i.exec(p); + if (m) { p = `http://${m[1]}`; } - m = p.match(/^([a-z]+:\/\/([a-z0-9-]+(?:\.[a-z0-9-]+)*\.))\*(.*)/); - if (!isNull(m)) { + m = /^([a-z]+:\/\/([a-z0-9-]+(?:\.[a-z0-9-]+)*\.))\*(.*)/.exec(p); + if (m) { if (m[2].match(/A([0-9]+\.){2,}z/)) { p = `${m[1]}tld${m[3]}`; pre_wildcards = [p.split('*')[0]]; @@ -2433,26 +2576,12 @@ function primaryFN() { err(ex); } } - const arr = [...name_set]; - this.data_names = arr; + this.data_names = [...name_map.values()]; return this.data_names; } - intersect(a = [], b = []) { - for (const v of a) { - if (b.includes(v)) { - return true; - } - } - for (const v of b) { - if (a.includes(v)) { - return true; - } - } - return false; + intersect(a, ...arr) { + return !isBlank([...new Set(a)].filter((v) => arr.every((b) => b.includes(v)))); } - // intersect(a, ...arr) { - // return [...new Set(a)].filter((v) => arr.every((b) => b.includes(v))); - // } } const template = { id: 0, @@ -2573,11 +2702,15 @@ function primaryFN() { const eframe = make('td', 'install-btn'); const uframe = make('td', 'mujs-uframe'); const fdaily = make('td', 'mujs-list', { - textContent: ujs.daily_installs + textContent: ujs.daily_installs, + dataset: { + name: 'daily_installs' + } }); const fupdated = make('td', 'mujs-list', { textContent: language.toDate(ujs.code_updated_at), dataset: { + name: 'code_updated_at', value: new Date(ujs.code_updated_at).toISOString() } }); @@ -2605,17 +2738,22 @@ function primaryFN() { const fcreated = make('mu-js', 'mujs-list', { textContent: `${i18n$('created_date')}: ${language.toDate(ujs.created_at)}`, dataset: { + name: 'created_at', value: new Date(ujs.created_at).toISOString() } }); const flicense = make('mu-js', 'mujs-list', { title: ujs.license ?? i18n$('no_license'), textContent: `${i18n$('license')}: ${ujs.license ?? i18n$('no_license')}`, - style: - 'text-overflow: ellipsis; overflow: hidden; white-space: nowrap; width: fit-content; max-width: 20em;' + dataset: { + name: 'license' + } }); const ftotal = make('mu-js', 'mujs-list', { - textContent: `${i18n$('total_installs')}: ${language.toNumber(ujs.total_installs)}` + textContent: `${i18n$('total_installs')}: ${language.toNumber(ujs.total_installs)}`, + dataset: { + name: 'total_installs' + } }); const fratings = make('mu-js', 'mujs-list', { title: i18n$('ratings'), @@ -2625,6 +2763,7 @@ function primaryFN() { title: i18n$('good'), textContent: ujs.good_ratings, dataset: { + name: 'good_ratings', el: 'good' } }); @@ -2632,6 +2771,7 @@ function primaryFN() { title: i18n$('ok'), textContent: ujs.ok_ratings, dataset: { + name: 'ok_ratings', el: 'ok' } }); @@ -2639,6 +2779,7 @@ function primaryFN() { title: i18n$('bad'), textContent: ujs.bad_ratings, dataset: { + name: 'bad_ratings', el: 'bad' } }); @@ -2658,7 +2799,7 @@ function primaryFN() { } }); const scriptDownload = make('mu-jsbtn', { - innerHTML: `${iconSVG.load('install')} ${i18n$('saveFile')}`, + innerHTML: `${iconSVG.load('download')} ${i18n$('saveFile')}`, dataset: { command: 'download-userjs', userjs: ujs.id, @@ -2680,23 +2821,22 @@ function primaryFN() { wrap: 'soft' }); const loadCode = make('mu-jsbtn', { - innerHTML: `${iconSVG.load('search')} ${i18n$('preview_code')}`, + innerHTML: `${iconSVG.load('code')} ${i18n$('preview_code')}`, dataset: { command: 'load-userjs', userjs: ujs.id } }); - if (engine) { - tr.dataset.engine = engine; - // if (engine.includes('fork')) { - // fdaily.dataset.command = 'open-tab'; - // fdaily.dataset.webpage = `${ujs.url}/stats`; - // fupdated.dataset.command = 'open-tab'; - // fupdated.dataset.webpage = `${ujs.url}/versions`; - // } - if (!engine.includes('fork') && cfg.recommend.others && goodUserJS.includes(ujs.url)) { - tr.dataset.good = 'upsell'; + const loadMetadata = make('mu-jsbtn', { + innerHTML: `${iconSVG.load('code')} Metadata`, + dataset: { + command: 'load-header', + userjs: ujs.id } + }); + tr.dataset.engine = engine; + if (!engine.includes('fork') && cfg.recommend.others && goodUserJS.includes(ujs.url)) { + tr.dataset.good = 'upsell'; } for (const u of ujs.users) { const user = make('mujs-a', { @@ -2713,7 +2853,7 @@ function primaryFN() { } uframe.append(user); } - if (engine.includes('fork') && cfg.recommend.others && goodUserJS.includes(ujs.id)) { + if (cfg.recommend.others && goodUserJS.includes(ujs.id)) { tr.dataset.good = 'upsell'; } eframe.append(scriptInstall); @@ -2721,53 +2861,55 @@ function primaryFN() { jsInfo.append(ftotal, ratings, fver, fcreated); mkList(i18n$('code_size'), { list: ujs._mujs.code.code_size, - type: 'size', + type: 'code_size', root: jsInfo }); jsInfoB.append(flicense); + const data_meta = ujs._mujs.code?.data_meta ?? {}; mkList(i18n$('antifeatures'), { - list: ujs._mujs.code.antifeatures, + list: data_meta.antifeatures ?? [], type: 'antifeatures', root: jsInfoB }); mkList(i18n$('applies_to'), { - list: ujs._mujs.code.match, - type: 'match', + list: ujs._mujs.code?.data_names ?? [], + type: 'data_names', root: jsInfoB }); mkList('@grant', { - list: ujs._mujs.code.grant, + list: data_meta.grant ?? [], type: 'grant', root: jsInfoB }); mkList('@require', { - list: ujs._mujs.code.meta?.require, + list: data_meta.require, type: 'require', root: jsInfoB }); - const script_resources = ujs._mujs.code.meta?.resource; mkList('@resource', { - list: isNull(script_resources) ? [] : [script_resources], + list: isNull(data_meta.resource) ? [] : [data_meta.resource], type: 'resource', root: jsInfoB }); fmore.append(jsInfo, jsInfoB); - fBtns.append(scriptDownload, loadCode); + fBtns.append(scriptDownload, loadCode, loadMetadata); fname.append(ftitle, fdesc, fmore, fBtns, codeArea); - const code_data = ujs._mujs.code.data; - if (code_data) { - const code_obj = new ParseUserJS(code_data); - codeArea.value = code_obj.get_code_block(); - } + const loadPage = make('mu-jsbtn', { + innerHTML: `${iconSVG.load('pager')} Page`, + dataset: { + command: 'load-page', + userjs: ujs.id + } + }); + fBtns.append(loadPage); if (ujs._mujs.code?.translated) tr.classList.add('translated'); for (const e of [fname, uframe, fdaily, fupdated, eframe]) tr.append(e); ujs._mujs.root = tr; - - return tr; + return ujs._mujs.root; }; // #endregion const loadFilters = () => { @@ -2825,12 +2967,19 @@ function primaryFN() { this.build = this.build.bind(this); this.toArr = this.toArr.bind(this); this.groupBy = this.groupBy.bind(this); + this.dispatch = this.dispatch.bind(this); this.sortRecords = this.sortRecords.bind(this); if (isEmpty(hostname)) hostname = container.host; this.engines = cfg.engines; this.host = hostname; } + dispatch(ujs) { + const { CustomEvent } = safeSelf(); + const customEvent = new CustomEvent('updateditem', { detail: ujs }); + main.dispatchEvent(customEvent); + } + set host(hostname) { this.intHost = hostname; @@ -2869,7 +3018,7 @@ function primaryFN() { build() { try { container.refresh(); - const { blacklisted, engines, host, toArr } = this; + const { blacklisted, engines, host, toArr, dispatch } = this; if (blacklisted || isEmpty(engines)) { container.opacityMin = '0'; mainframe.style.opacity = container.opacityMin; @@ -2903,92 +3052,59 @@ function primaryFN() { host }, code: { - antifeatures: [], - grant: [], - match: [], meta: {}, request: async function (translate = false, code_url) { - if (this.data) { + if (this.data_code_block) { return this; } - this.data = ''; + code_url = code_url ?? d.code_url; /** @type { string } */ - const code = await Network.req(code_url ?? d.code_url, 'GET', 'text').catch( - showError - ); + const code = await Network.req(code_url, 'GET', 'text').catch(showError); if (typeof code !== 'string') { return this; } - Object.assign(this, { - data: code, - code_size: [Network.format(code.length)] - }); - const grantSet = new Set(); - const afSet = new Set(); - const code_obj = new ParseUserJS(code); - const meta = code_obj.parse_meta(); - const applies_to_names = code_obj.calculate_applies_to_names(); - + const code_obj = new ParseUserJS(code, /\.user\.css/.test(code_url)); + const { data_meta } = code_obj; if (translate) { for (const k of userjs.pool.keys()) { - if (meta[`name:${k}`]) { + if (data_meta[`name:${k}`]) { Object.assign(obj, { - name: meta[`name:${k}`] + name: data_meta[`name:${k}`] }); this.translated = true; } - if (meta[`description:${k}`]) { + if (data_meta[`description:${k}`]) { Object.assign(obj, { - description: meta[`description:${k}`] + description: data_meta[`description:${k}`] }); this.translated = true; } } } - - for (const [key, value] of Object.entries(meta)) { - if (/grant/.test(key)) { - for (const v of normalizeTarget(value, false)) { - if (grantSet.has(v)) { - continue; - } - grantSet.add(v); - } - } else if (/antifeature/.test(key)) { - for (const v of normalizeTarget(value, false)) { - if (afSet.has(v)) { - continue; - } - afSet.add(v); - } - } - } - if (typeof meta.require === 'string') { - const s = meta.require; - meta.require = [s]; + if (Array.isArray(data_meta.grant)) { + data_meta.grant = union(data_meta.grant); } - if (meta.resource) { + if (data_meta.resource) { const obj = {}; - if (typeof meta.resource === 'string') { - const reg = /(.+)\s+(.+)/.exec(meta.resource); + if (typeof data_meta.resource === 'string') { + const reg = /(.+)\s+(.+)/.exec(data_meta.resource); if (reg) { obj[reg[1].trim()] = reg[2]; } } else { - for (const r of meta.resource) { + for (const r of data_meta.resource) { const reg = /(.+)\s+(http.+)/.exec(r); if (reg) { obj[reg[1].trim()] = reg[2]; } } } - meta.resource = obj; + data_meta.resource = obj; } Object.assign(this, { - meta, - match: applies_to_names, - grant: [...grantSet], - antifeatures: [...afSet] + code_size: [Network.format(code.length)], + meta: data_meta, + ...code_obj }); return this; @@ -3063,8 +3179,13 @@ function primaryFN() { finalList = union(hds, filterLang); for (const ujs of finalList) { - if (cfg.codePreview && !ujs._mujs.code.data) { - await ujs._mujs.code.request(); + if ( + !ujs._mujs.code.data_code_block && + (cfg.preview.code || cfg.preview.metadata) + ) { + ujs._mujs.code.request().then(() => { + dispatch(ujs); + }); } createjs(ujs, engine.name); } @@ -3080,7 +3201,8 @@ function primaryFN() { } const selected = htmlDocument.documentElement; if (/openuserjs/gi.test(engine.name)) { - for (const i of qsA('.col-sm-8 .tr-link', selected)) { + const col = qsA('.col-sm-8 .tr-link', selected) ?? []; + for (const i of col) { while (isNull(qs('.script-version', i))) { await new Promise((resolve) => requestAnimationFrame(resolve)); } @@ -3109,8 +3231,13 @@ function primaryFN() { if (bsFilter.match(ujs)) { continue; } - if (cfg.codePreview && !ujs._mujs.code.data) { - await ujs._mujs.code.request(); + if ( + !ujs._mujs.code.data_code_block && + (cfg.preview.code || cfg.preview.metadata) + ) { + ujs._mujs.code.request().then(() => { + dispatch(ujs); + }); } createjs(ujs, engine.name); } @@ -3119,7 +3246,7 @@ function primaryFN() { showError(ex); } }; - const gitFN = async (data) => { + const gitFN = (data) => { try { if (isBlank(data.items)) { showError('Invalid data received from the server, TODO fix this'); @@ -3127,14 +3254,14 @@ function primaryFN() { } for (const r of data.items) { const ujs = _mujs({ - name: r.name, + id: r.repository.id ?? r.id ?? 0, + name: r.repository.name ?? r.name, description: isEmpty(r.repository.description) ? i18n$('no_license') : r.repository.description, - url: r.html_url, + url: r.repository.html_url, code_url: r.html_url.replace(/\/blob\//g, '/raw/'), - code_updated_at: r.commit || Date.now(), - total_installs: r.score, + page_url: `${r.repository.url}/contents/README.md`, users: [ { name: r.repository.owner.login, @@ -3142,11 +3269,30 @@ function primaryFN() { } ] }); - if (bsFilter.match(ujs)) { - continue; - } - if (cfg.codePreview && !ujs._mujs.code.data) { - await ujs._mujs.code.request(); + // if (bsFilter.match(ujs)) { + // continue; + // } + Network.req(r.repository.url, 'GET', 'json', { + headers: { + Accept: 'application/vnd.github+json', + Authorization: `Bearer ${engine.token}`, + 'X-GitHub-Api-Version': '2022-11-28' + } + }).then((repository) => { + ujs.code_updated_at = r.commit || repository.updated_at || Date.now(); + ujs.created_at = repository.created_at; + ujs.daily_installs = repository.watchers_count ?? 0; + ujs.good_ratings = repository.stargazers_count ?? 0; + if (repository.license?.name) ujs.license = repository.license.name; + dispatch(ujs); + }); + if ( + !ujs._mujs.code.data_code_block && + (cfg.preview.code || cfg.preview.metadata) + ) { + ujs._mujs.code.request().then(() => { + dispatch(ujs); + }); } createjs(ujs, engine.name); } @@ -3273,6 +3419,8 @@ function primaryFN() { command: 'reset' } }); + cbtn.append(resetbtn, savebtn); + const makesection = (name, tag) => { tag = tag ?? i18n$('no_license'); name = name ?? i18n$('no_license'); @@ -3297,7 +3445,7 @@ function primaryFN() { } const cmd = target.dataset.command; if (cmd === tag) { - const a = qsA(`label[data-${tag}]`, sec); + const a = qsA(`[data-${tag}]`, sec); if (dom.cl.has(a, 'hidden')) { dom.cl.remove(a, 'hidden'); } else { @@ -3311,133 +3459,24 @@ function primaryFN() { cfgpage.append(sec); return sec; }; - const sections = { general: makesection('General', 'general'), load: makesection('Automation', 'load'), list: makesection('List', 'list'), filters: makesection('List Filters', 'filters'), blacklist: makesection('Blacklist (WIP)', 'blacklist'), - // engine: makesection('Search Engine', 'engine'), - theme: makesection('Theme Colors', 'theme') - }; - - const makerow = (desc, type = null, nm, attrs = {}) => { - desc = desc ?? i18n$('no_license'); - nm = nm ?? i18n$('no_license'); - const sec = make('mujs-section', { - dataset: { - name: nm - } - }); - const lb = make('label'); - const divDesc = make('mu-js', { - textContent: desc - }); - lb.append(divDesc); - sec.append(lb); - cfgpage.append(sec); - if (isNull(type)) { - return lb; - } - const inp = make('input', { - type, - dataset: { - name: nm - }, - ...attrs - }); - if (!cfgMap.has(nm)) { - cfgMap.set(nm, inp); - } - if (type === 'checkbox') { - const inlab = make('mu-js', 'mujs-inlab'); - const la = make('label', { - onclick() { - inp.dispatchEvent(new MouseEvent('click')); - } - }); - inlab.append(inp, la); - lb.append(inlab); - if (nm.includes('-')) { - return inp; - } - if (/(greasy|sleazy)fork|openuserjs|gi(thub|st)/gi.test(nm)) { - const engine = cfg.engines.find((engine) => engine.name === nm); - if (engine) { - inp.checked = engine.enabled; - inp.dataset.engine = engine.name; - ael(inp, 'change', (evt) => { - container.unsaved = true; - container.rebuild = true; - engine.enabled = evt.target.checked; - }); - - if (engine.query) { - const d = DEFAULT_CONFIG.engines.find((e) => e.name === engine.name); - const urlInp = make('input', { - type: 'text', - defaultValue: '', - value: decodeURIComponent(engine.query) ?? '', - placeholder: decodeURIComponent(d.query) ?? '', - dataset: { - name: nm, - engine: engine.name - }, - onchange(evt) { - container.unsaved = true; - container.rebuild = true; - try { - engine.query = encodeURIComponent(new URL(evt.target.value).toString()); - } catch (ex) { - err(ex); - } - } - }); - sec.append(urlInp); - } - if (engine.name === 'github') { - const ghToken = make('input', { - type: 'text', - defaultValue: '', - value: engine.token ?? '', - placeholder: 'Paste Access Token', - dataset: { - engine: 'github-token' - }, - onchange(evt) { - container.unsaved = true; - container.rebuild = true; - engine.token = evt.target.value; - } - }); - sec.append(ghToken); - cfgMap.set('github-token', ghToken); - } - } - } else { - inp.checked = cfg[nm]; - ael(inp, 'change', (evt) => { - container.unsaved = true; - if (/filterlang/i.test(nm)) { - container.rebuild = true; - } - cfg[nm] = evt.target.checked; - }); - } - } else { - lb.append(inp); - } - return inp; + engine: makesection('Search Engines', 'engine'), + theme: makesection('Theme Colors', 'theme'), + exp: makesection('Import / Export', 'exp') }; - const mkSection = (text, value, type = 'checkbox', tag = 'general', attrs = {}) => { - cfgMap.set(text, value); + const makeRow = (text, value, type = 'checkbox', tag = 'general', attrs = {}) => { const lb = make('label', 'sub-section hidden', { textContent: text, dataset: { [tag]: text } }); + cfgMap.set(text, value); if (type === 'select') { const inp = make('select', { dataset: { @@ -3468,6 +3507,10 @@ function primaryFN() { ...attrs }); + if (tag === 'engine') { + inp.dataset.name = value; + } + if (sections[tag]) { sections[tag].append(lb); } @@ -3507,6 +3550,61 @@ function primaryFN() { cfg[value] = evt.target.checked; } }); + + if (tag === 'engine') { + const engine = cfg.engines.find((engine) => engine.name === value); + if (engine) { + inp.checked = engine.enabled; + inp.dataset.engine = engine.name; + ael(inp, 'change', (evt) => { + container.unsaved = true; + container.rebuild = true; + engine.enabled = evt.target.checked; + }); + + if (engine.query) { + const d = DEFAULT_CONFIG.engines.find((e) => e.name === engine.name); + const urlInp = make('input', { + type: 'text', + defaultValue: '', + value: decodeURIComponent(engine.query) ?? '', + placeholder: decodeURIComponent(d.query) ?? '', + dataset: { + name: nm, + engine: engine.name + }, + onchange(evt) { + container.unsaved = true; + container.rebuild = true; + try { + engine.query = encodeURIComponent(new URL(evt.target.value).toString()); + } catch (ex) { + err(ex); + } + } + }); + lb.append(urlInp); + } + if (engine.name === 'github') { + const ghToken = make('input', { + type: 'text', + defaultValue: '', + value: engine.token ?? '', + placeholder: 'Paste Access Token', + dataset: { + engine: 'github-token' + }, + onchange(evt) { + container.unsaved = true; + container.rebuild = true; + engine.token = evt.target.value; + } + }); + lb.append(ghToken); + cfgMap.set('github-token', ghToken); + } + } + } } else { if (type === 'text') { inp.defaultValue = ''; @@ -3520,11 +3618,11 @@ function primaryFN() { return lb; }; if (isGM) { - mkSection(i18n$('userjs_sync'), 'cache'); - mkSection(i18n$('userjs_autoinject'), 'autoinject', 'checkbox', 'load'); + makeRow(i18n$('userjs_sync'), 'cache'); + makeRow(i18n$('userjs_autoinject'), 'autoinject', 'checkbox', 'load'); } - mkSection(i18n$('redirect'), 'sleazyredirect'); - mkSection(`${i18n$('dtime')} (ms)`, 'time', 'number', 'general', { + makeRow(i18n$('redirect'), 'sleazyredirect'); + makeRow(`${i18n$('dtime')} (ms)`, 'time', 'number', 'general', { defaultValue: 10000, value: cfg.time, min: 0, @@ -3552,34 +3650,35 @@ function primaryFN() { } }); - mkSection(i18n$('auto_fetch'), 'autofetch', 'checkbox', 'load'); - mkSection(i18n$('userjs_fullscreen'), 'autoexpand', 'checkbox', 'load', { + makeRow(i18n$('auto_fetch'), 'autofetch', 'checkbox', 'load'); + makeRow(i18n$('userjs_fullscreen'), 'autoexpand', 'checkbox', 'load', { onchange(e) { if (e.target.checked) { dom.cl.add([btnfullscreen, main], 'expanded'); - dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('fsClose')); + dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('collapse')); } else { dom.cl.remove([btnfullscreen, main], 'expanded'); - dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('fsOpen')); + dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('expand')); } } }); - mkSection('Clear on Tab close', 'clearTabCache', 'checkbox', 'load'); + makeRow('Clear on Tab close', 'clearTabCache', 'checkbox', 'load'); - mkSection('Default Sort', 'autoSort', 'select', 'list'); - mkSection(i18n$('filter'), 'filterlang', 'checkbox', 'list'); - mkSection(i18n$('preview_code'), 'codePreview', 'checkbox', 'list'); - mkSection('Recommend author', 'recommend-author', 'checkbox', 'list'); - mkSection('Recommend scripts', 'recommend-others', 'checkbox', 'list'); + makeRow('Default Sort', 'autoSort', 'select', 'list'); + makeRow(i18n$('filter'), 'filterlang', 'checkbox', 'list'); + makeRow(i18n$('preview_code'), 'preview-code', 'checkbox', 'list'); + makeRow('Preview Metadata', 'preview-metadata', 'checkbox', 'list'); + makeRow('Recommend author', 'recommend-author', 'checkbox', 'list'); + makeRow('Recommend scripts', 'recommend-others', 'checkbox', 'list'); for (const [k, v] of Object.entries(cfg.filters)) { - mkSection(v.name, `filters-${k}`, 'checkbox', 'filters'); + makeRow(v.name, `filters-${k}`, 'checkbox', 'filters'); } - makerow('Greasy Fork', 'checkbox', 'greasyfork'); - makerow('Sleazy Fork', 'checkbox', 'sleazyfork'); - makerow('Open UserJS', 'checkbox', 'openuserjs'); - makerow('GitHub API', 'checkbox', 'github'); + makeRow('Greasy Fork', 'greasyfork', 'checkbox', 'engine'); + makeRow('Sleazy Fork', 'sleazyfork', 'checkbox', 'engine'); + makeRow('Open UserJS', 'openuserjs', 'checkbox', 'engine'); + makeRow('GitHub API', 'github', 'checkbox', 'engine'); for (const [k, v] of Object.entries(cfg.theme)) { const lb = make('label', 'hidden', { @@ -3633,6 +3732,66 @@ function primaryFN() { sections.theme.append(lb); } + // const blacklist = make('textarea', { + // dataset: { + // name: 'blacklist' + // }, + // rows: '10', + // autocomplete: false, + // spellcheck: false, + // wrap: 'soft', + // value: JSON.stringify(cfg.blacklist, null, ' '), + // oninput(evt) { + // let isvalid = true; + // try { + // cfg.blacklist = JSON.parse(evt.target.value); + // isvalid = true; + // } catch (ex) { + // err(ex); + // isvalid = false; + // } finally { + // if (isvalid) { + // dom.cl.remove(evt.target, 'mujs-invalid'); + // dom.prop(savebtn, 'disabled', false); + // } else { + // dom.cl.add(evt.target, 'mujs-invalid'); + // dom.prop(savebtn, 'disabled', true); + // } + // } + // } + // }); + // cfgMap.set('blacklist', blacklist); + // const addList = make('mujs-add', { + // textContent: '+', + // dataset: { + // command: 'new-list' + // } + // }); + // const n = make('input', { + // type: 'text', + // defaultValue: '', + // value: '', + // placeholder: 'Name', + // }); + // const inpValue = make('input', { + // type: 'text', + // defaultValue: '', + // value: '', + // placeholder: 'Value', + // }); + // const label = make('label', 'new-list hidden', { + // dataset: { + // blacklist: 'new-list' + // } + // }); + // label.append(n, inpValue, addList); + // listSec.append(label); + // ael(addList, 'click', () => { + // if (isEmpty(n.value) || isEmpty(inpValue.value)) { + // return + // }; + // createList(n.value, n.value, inpValue.value); + // }); const createList = (key, v = '', disabled = false, type = 'String') => { let txt = key; if (typeof key === 'string') { @@ -3718,72 +3877,50 @@ function primaryFN() { lb.append(inp, selType); sections.blacklist.append(lb); }; - // const blacklist = make('textarea', { - // dataset: { - // name: 'blacklist' - // }, - // rows: '10', - // autocomplete: false, - // spellcheck: false, - // wrap: 'soft', - // value: JSON.stringify(cfg.blacklist, null, ' '), - // oninput(evt) { - // let isvalid = true; - // try { - // cfg.blacklist = JSON.parse(evt.target.value); - // isvalid = true; - // } catch (ex) { - // err(ex); - // isvalid = false; - // } finally { - // if (isvalid) { - // dom.cl.remove(evt.target, 'mujs-invalid'); - // dom.prop(savebtn, 'disabled', false); - // } else { - // dom.cl.add(evt.target, 'mujs-invalid'); - // dom.prop(savebtn, 'disabled', true); - // } - // } - // } - // }); - // cfgMap.set('blacklist', blacklist); - // const addList = make('mujs-add', { - // textContent: '+', - // dataset: { - // command: 'new-list' - // } - // }); - // const n = make('input', { - // type: 'text', - // defaultValue: '', - // value: '', - // placeholder: 'Name', - // }); - // const inpValue = make('input', { - // type: 'text', - // defaultValue: '', - // value: '', - // placeholder: 'Value', - // }); - // const label = make('label', 'new-list hidden', { - // dataset: { - // blacklist: 'new-list' - // } - // }); - // label.append(n, inpValue, addList); - // listSec.append(label); - // ael(addList, 'click', () => { - // if (isEmpty(n.value) || isEmpty(inpValue.value)) { - // return - // }; - // createList(n.value, n.value, inpValue.value); - // }); - for (const key of cfg.blacklist) { createList(key); } - cbtn.append(resetbtn, savebtn); + const transfers = { + export: { + cfg: make('mujs-btn', 'mujs-export sub-section hidden', { + textContent: i18n$('export_config'), + dataset: { + command: 'export-cfg', + exp: 'export-cfg' + } + }), + theme: make('mujs-btn', 'mujs-export sub-section hidden', { + textContent: i18n$('export_theme'), + dataset: { + command: 'export-theme', + exp: 'export-theme' + } + }) + }, + import: { + cfg: make('mujs-btn', 'mujs-import sub-section hidden', { + textContent: i18n$('import_config'), + dataset: { + command: 'import-cfg', + exp: 'import-cfg' + } + }), + theme: make('mujs-btn', 'mujs-import sub-section hidden', { + textContent: i18n$('import_theme'), + dataset: { + command: 'import-theme', + exp: 'import-theme' + } + }) + } + }; + for (const value of Object.values(transfers)) { + for (const v of Object.values(value)) { + sections.exp.append(v); + } + } + cfgpage.append(cbtn); }; // #endregion @@ -3810,7 +3947,7 @@ function primaryFN() { dom.cl.add(mainframe, 'hidden'); if (cfg.autoexpand) { dom.cl.add([btnfullscreen, main], 'expanded'); - dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('fsClose')); + dom.prop(btnfullscreen, 'innerHTML', iconSVG.load('collapse')); } if (dom.cl.has(mainframe, 'error')) { tab.create('mujs:settings'); @@ -3938,11 +4075,8 @@ function primaryFN() { for (const v of cacheValues) { if (v.name && v.name.match(reg)) finds.add(v._mujs.root); if (v.description && v.description.match(reg)) finds.add(v._mujs.root); - const code_data = v._mujs.code.data; - if (code_data) { - const code_obj = new ParseUserJS(code_data); - const meta = code_obj.parse_meta(code_data); - for (const key of Object.keys(meta)) { + if (v._mujs.code.data_meta) { + for (const key of Object.keys(v._mujs.code.data_meta)) { if (/name|desc/i.test(key) && key.match(reg)) finds.add(v._mujs.root); } } diff --git a/src/UserJS/svg/bug-svgrepo-com.svg b/src/UserJS/svg/bug-svgrepo-com.svg deleted file mode 100644 index 32b7852..0000000 --- a/src/UserJS/svg/bug-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/UserJS/svg/close-svgrepo-com.svg b/src/UserJS/svg/close-svgrepo-com.svg deleted file mode 100644 index a4a1e54..0000000 --- a/src/UserJS/svg/close-svgrepo-com.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - diff --git a/src/UserJS/svg/download-svgrepo-com.svg b/src/UserJS/svg/download-svgrepo-com.svg deleted file mode 100644 index 9b8cf09..0000000 --- a/src/UserJS/svg/download-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/UserJS/svg/expand-full-fullscreen-svgrepo-com.svg b/src/UserJS/svg/expand-full-fullscreen-svgrepo-com.svg deleted file mode 100644 index 53218ff..0000000 --- a/src/UserJS/svg/expand-full-fullscreen-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/UserJS/svg/filter-svgrepo-com.svg b/src/UserJS/svg/filter-svgrepo-com.svg deleted file mode 100644 index 8a5d29e..0000000 --- a/src/UserJS/svg/filter-svgrepo-com.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/UserJS/svg/fork-svgrepo-com.svg b/src/UserJS/svg/fork-svgrepo-com.svg deleted file mode 100644 index 8087aa8..0000000 --- a/src/UserJS/svg/fork-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/UserJS/svg/fullscreen-svgrepo-com.svg b/src/UserJS/svg/fullscreen-svgrepo-com.svg deleted file mode 100644 index 15379af..0000000 --- a/src/UserJS/svg/fullscreen-svgrepo-com.svg +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/UserJS/svg/github-svgrepo-com.svg b/src/UserJS/svg/github-svgrepo-com.svg deleted file mode 100644 index eaac757..0000000 --- a/src/UserJS/svg/github-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/UserJS/svg/minus-svgrepo-com.svg b/src/UserJS/svg/minus-svgrepo-com.svg deleted file mode 100644 index 4f655c0..0000000 --- a/src/UserJS/svg/minus-svgrepo-com.svg +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/src/UserJS/svg/navigation-svgrepo-com.svg b/src/UserJS/svg/navigation-svgrepo-com.svg deleted file mode 100644 index 3b865b1..0000000 --- a/src/UserJS/svg/navigation-svgrepo-com.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - ic_fluent_navigation_24_filled - Created with Sketch. - - - - - - \ No newline at end of file diff --git a/src/UserJS/svg/plus-svgrepo-com.svg b/src/UserJS/svg/plus-svgrepo-com.svg deleted file mode 100644 index 66a5b01..0000000 --- a/src/UserJS/svg/plus-svgrepo-com.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/UserJS/svg/search-svgrepo-com.svg b/src/UserJS/svg/search-svgrepo-com.svg deleted file mode 100644 index eb7f58d..0000000 --- a/src/UserJS/svg/search-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/UserJS/svg/settings-svgrepo-com.svg b/src/UserJS/svg/settings-svgrepo-com.svg deleted file mode 100644 index eaeef67..0000000 --- a/src/UserJS/svg/settings-svgrepo-com.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 87d600a..470b48c 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -93,7 +93,7 @@ "message": "Preview Code" }, "saveFile": { - "message": "Save File" + "message": "Download" }, "newTab": { "message": "New Tab" @@ -141,7 +141,7 @@ "message": "Close Userscript+" }, "userjs_sync": { - "message": "Sync with UserScript Manager" + "message": "Sync" }, "userjs_autoinject": { "message": "Inject on load" diff --git a/src/sass/_main.scss b/src/sass/_main.scss index b4d429d..257468a 100644 --- a/src/sass/_main.scss +++ b/src/sass/_main.scss @@ -30,6 +30,12 @@ mujs-root { } mujs-root * { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + scrollbar-color: var(--mujs-txt-color, hsl(0, 0%, 100%)) hsl(224, 14%, 21%); + scrollbar-width: thin; + @supports not (scrollbar-width: thin) { ::-webkit-scrollbar { width: 1.4vw; @@ -61,9 +67,6 @@ mujs-root * { background: var(--mujs-txt-color, hsl(0, 0%, 100%)); } } - - scrollbar-color: var(--mujs-txt-color, hsl(0, 0%, 100%)) hsl(224, 14%, 21%); - scrollbar-width: thin; } @at-root mu-js { @@ -87,10 +90,6 @@ td.mujs-list { font-weight: 500; } -.mujs-sty-flex>mujs-btn { - margin: auto; -} - .mujs-invalid { border-radius: 8px !important; border-width: 2px !important; @@ -111,10 +110,6 @@ mujs-row { } mujs-column { - @media screen and (max-width: 800px) { - flex-flow: row wrap; - } - count-frame { &[data-counter="greasyfork"] { background: var(--mujs-gf-color, hsl(204, 100%, 40%)); @@ -132,6 +127,10 @@ mujs-column { background: hsla(12, 86%, 50%, 0.568); } } + + @media screen and (max-width: 800px) { + flex-flow: row wrap; + } } mujs-row { @@ -148,6 +147,13 @@ mu-js { } mujs-main { + width: 100%; + width: -moz-available; + width: -webkit-fill-available; + background: var(--mujs-background-color, hsl(222, 14%, 33%)) !important; + border: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); + border-radius: 16px; + @media screen and (max-height: 720px) { &:not(.webext-page) { height: 100% !important; @@ -157,13 +163,6 @@ mujs-main { } } - width: 100%; - width: -moz-available; - width: -webkit-fill-available; - background: var(--mujs-background-color, hsl(222, 14%, 33%)) !important; - border: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); - border-radius: 16px; - &.expanded { height: 100% !important; bottom: 0rem !important; @@ -240,6 +239,10 @@ mujs-main { border-radius: 4px; background: transparent; + @media screen and (max-width: 800px) { + min-width: 6em !important; + } + &.active { background: var(--mujs-even-row, hsl(222, 14%, 18%)); } @@ -289,25 +292,33 @@ mujs-main { // background: var(--mujs-background-color, hsl(222, 14%, 33%)); background: hsla(0, 0%, 0%, 0); color: var(--mujs-txt-color, hsl(0, 0%, 100%)); - } - input:not([type='checkbox']) { - border: transparent; - outline: none !important; + &:not([type='checkbox']) { + border: transparent; + outline: none !important; + } } + mujs-page, textarea { background: inherit; overflow-y: auto; - color: var(--mujs-placeholder, hsl(81, 56%, 54%)); - // background: var(--mujs-even-row, hsl(222, 14%, 18%)); - // border: 1px solid transparent; border: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); - border-radius: 10px; - resize: vertical; + border-radius: 5px; outline: none; font-family: monospace; font-size: 14px; + } + + mujs-page { + padding: 0.5em; + margin: 0.5em; + } + + textarea { + overflow-y: auto; + color: var(--mujs-placeholder, hsl(81, 56%, 54%)); + resize: vertical; &:focus { outline: none; @@ -347,8 +358,7 @@ mujs-main { align-items: center; justify-content: center; - svg, - img { + svg { width: 14px; height: 14px; background: transparent; @@ -450,9 +460,6 @@ mujs-header { order: 1; display: flex; border-bottom: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); - // border-top-left-radius: 10px; - // border-top-right-radius: 10px; - // padding: .5em; padding-left: .5em; padding-right: .5em; padding-bottom: .5em; @@ -486,10 +493,6 @@ mujs-header { order: 1; } - .mujs-sty-flex { - order: 2; - } - .btn-frame { order: 999999999999; } @@ -500,7 +503,6 @@ mujs-body { overflow-x: hidden; padding: 0px; height: 100%; - border: 1px solid var(--mujs-border-b-color, hsla(0, 0%, 0%, 0)); border-bottom-left-radius: 16px; border-bottom-right-radius: 16px; @@ -528,6 +530,10 @@ mujs-body { } table { + width: 100%; + width: -moz-available; + width: -webkit-fill-available; + @media screen and (max-width: 1180px) { thead>tr { display: table-column; @@ -538,13 +544,11 @@ mujs-body { display: flex; flex-flow: row wrap; align-items: center; - border-bottom: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); padding-top: .5em; padding-bottom: .5em; td { margin: auto; - border-bottom: 1px solid transparent; >mujs-a, >mu-js, @@ -553,9 +557,33 @@ mujs-body { justify-content: center; } + >mujs-a { + width: 100%; + } + + >mujs-column { + @media screen and (max-width: 800px) { + flex-flow: column wrap; + + >mujs-row { + align-content: center; + } + + mujs-column { + justify-content: center; + } + } + } + &:not(.mujs-name, .install-btn) { width: 25%; } + + &.install-btn { + @media screen and (max-width: 800px) { + width: 100%; + } + } } .mujs-name { @@ -576,37 +604,37 @@ mujs-body { } } - width: 100%; - width: -moz-available; - width: -webkit-fill-available; - - th, - td { - border-bottom: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); - } - th { position: -webkit-sticky; position: sticky; top: 0; background: hsla(222, 14%, 33%, 0.75); + border-bottom: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); &.mujs-header-name { + width: 50%; + @media screen and (max-width: 800px) { width: auto !important; } - - width: 50%; } } .frame { &:nth-child(even) { background: var(--mujs-even-row, hsl(222, 14%, 18%)) !important; + + textarea { + background: var(--mujs-odd-row, hsl(222, 14%, 33%)) !important; + } } &:nth-child(odd) { background: var(--mujs-odd-row, hsl(222, 14%, 33%)) !important; + + textarea { + background: var(--mujs-even-row, hsl(222, 14%, 18%)) !important; + } } &:not([data-engine="sleazyfork"], [data-engine="greasyfork"]) { @@ -714,13 +742,9 @@ mujs-body { } svg { + width: 12px; + height: 12px; fill: currentColor; - } - - svg, - img { - width: 14px; - height: 14px; background: transparent; } @@ -749,6 +773,10 @@ mujs-body { >mujs-column { >mu-jsbtn { padding: 0px 7px; + + @media screen and (max-width: 800px) { + width: 100%; + } } } } @@ -803,6 +831,26 @@ mujs-body { } } } + + @media screen and (max-width: 800px) { + width: 30em !important; + } + } + + [data-name="license"] { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; + // max-width: 20em; + + @media screen and (max-width: 800px) { + width: 100% !important; + width: -moz-available !important; + width: -webkit-fill-available !important; + } } } } @@ -815,36 +863,46 @@ mujs-body { } .mujs-cfg { - @media screen and (max-height: 720px) { - &:not(.webext-page) { - height: 100%; - height: -moz-available; - height: -webkit-fill-available; - width: 100%; - width: -moz-available; - width: -webkit-fill-available; - overflow-x: auto; - padding: .5em; - } - } - - height: fit-content; - height: -moz-fit-content; - height: -webkit-fit-content; - mujs-section { border-radius: 16px; padding: .5em; &:nth-child(even) { background: var(--mujs-even-row, hsl(222, 14%, 18%)) !important; + + input, + select { + background: var(--mujs-odd-row, hsl(222, 14%, 33%)); + } + + select option { + background: var(--mujs-odd-row, hsl(222, 14%, 33%)); + + &:hover { + background: var(--mujs-even-row, hsl(222, 14%, 18%)) !important; + } + } } &:nth-child(odd) { background: var(--mujs-odd-row, hsl(222, 14%, 33%)) !important; + + input, + select { + background: var(--mujs-even-row, hsl(222, 14%, 18%)); + } + + select option { + background: var(--mujs-even-row, hsl(222, 14%, 18%)); + + &:hover { + background: var(--mujs-odd-row, hsl(222, 14%, 33%)) !important; + } + } } &[data-name='theme'], + &[data-name='exp'], &[data-name='blacklist'] { display: flex; justify-content: space-between; @@ -855,6 +913,15 @@ mujs-body { // order: 999999999999; // font-size: 20px; // } + >mujs-btn { + &:hover { + background: var(--mujs-even-row, hsl(222, 14%, 18%)) !important; + } + + width: 100%; + width: -moz-available; + width: -webkit-fill-available; + } } input[type='text']::-webkit-input-placeholder { @@ -903,48 +970,44 @@ mujs-body { } } - &.sub-section { - padding: 0.20em; - } - - // display: flex; - // justify-content: space-between; - input:not([type='checkbox']) { font-size: 14px; position: relative; border-radius: 4px; border: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); } + } - // input[type='text']::-webkit-input-placeholder { - // color: var(--mujs-placeholder, hsl(81, 56%, 54%)); - // } + select, + select option { + color: var(--mujs-txt-color, hsl(0, 0%, 100%)); + border: 1px solid transparent; + list-style: none; + outline-style: none; + pointer-events: auto; + } - // input[type='text']::-moz-placeholder { - // color: var(--mujs-placeholder, hsl(81, 56%, 54%)); - // } + select { + text-align: center; + border-radius: 4px; + } - // input[type='text']:-ms-input-placeholder { - // color: var(--mujs-placeholder, hsl(81, 56%, 54%)); - // } + >*.sub-section { + padding: 0.20em; - // input[type='text']::-ms-input-placeholder { - // color: var(--mujs-placeholder, hsl(81, 56%, 54%)); - // } + &[data-engine] { + flex-wrap: wrap; - // input[type='text']::placeholder { - // color: var(--mujs-placeholder, hsl(81, 56%, 54%)); - // } - } + input { + width: 100%; + width: -moz-available; + width: -webkit-fill-available; + } + } - >input { - width: 100%; - width: -moz-available; - width: -webkit-fill-available; - margin-top: 5px; - border-radius: 4px; - border: 1px solid var(--mujs-txt-color, hsl(0, 0%, 100%)); + input[type='text'] { + margin: 0.2em 0px; + } } } @@ -964,9 +1027,12 @@ mujs-body { } } - &[data-name='greasyfork']:checked+label, + &[data-name='greasyfork']:checked+label { + background: var(--mujs-gf-color, hsl(204, 100%, 40%)); + } + &[data-name='sleazyfork']:checked+label { - background: var(--mujs-chck-gf, hsla(197, 100%, 50%, 0.568)); + background: var(--mujs-sf-color, hsl(12, 86%, 50%)); } &[data-name='openuserjs']:checked+label { @@ -1003,6 +1069,8 @@ mujs-body { .mujs-sty-flex { mujs-btn { + margin: auto; + &[data-command="reset"] { background: var(--mujs-sf-btn-color, hsl(12, 86%, 50%)); border-color: var(--mujs-sf-btn-color, hsl(12, 86%, 50%)); @@ -1028,6 +1096,23 @@ mujs-body { &:not(.webext-page) { margin: 1rem 25rem; } + + height: fit-content; + height: -moz-fit-content; + height: -webkit-fit-content; + + @media screen and (max-height: 720px) { + &:not(.webext-page) { + height: 100%; + height: -moz-available; + height: -webkit-fill-available; + width: 100%; + width: -moz-available; + width: -webkit-fill-available; + overflow-x: auto; + padding: .5em; + } + } } mujs-a { @@ -1058,13 +1143,9 @@ mujs-btn { padding: 6px 15px; svg { - fill: var(--mujs-txt-color, hsl(0, 0%, 100%)); - } - - svg, - img { width: 14px; height: 14px; + fill: var(--mujs-txt-color, hsl(0, 0%, 100%)); } } @@ -1083,25 +1164,9 @@ mu-jsbtn { mujs-a, mu-jsbtn, .mujs-pointer, -.mujs-cfg mujs-section *:not(input[type='password'], input[type='text'], input[type='number'], [data-theme], [data-blacklist]), +.mujs-cfg mujs-section *:not(input[type='text'], input[type='number'], [data-theme], [data-blacklist]), .mainbtn, .mainframe, mujs-btn { cursor: pointer !important; } - -// .install-link { -// transition: box-shadow .2s; -// display: inline-block; -// background-color: hsl(120, 100%, 16%); -// padding: .5em 1em; -// color: hsl(0, 0%, 100%); -// text-decoration: none; -// border-radius: .25rem 0 0 .25rem; -// } - -// .install-help { -// background-color: hsl(120, 67%, 35%); -// color: hsl(0, 0%, 100%); -// border-radius: 0 .25rem .25rem 0; -// } diff --git a/src/sass/magicuserjs.scss b/src/sass/magicuserjs.scss index 326e3de..ec6651f 100644 --- a/src/sass/magicuserjs.scss +++ b/src/sass/magicuserjs.scss @@ -1,3 +1,3 @@ @charset 'UTF-8'; -@import 'main'; +@use 'main'; diff --git a/src/typings/UserJS.d.ts b/src/typings/UserJS.d.ts index db953c1..03fbe6e 100644 --- a/src/typings/UserJS.d.ts +++ b/src/typings/UserJS.d.ts @@ -9,6 +9,7 @@ export interface safeHandles { // createPolicy(): void; // }; XMLHttpRequest: typeof XMLHttpRequest; + CustomEvent: typeof CustomEvent; createElement: typeof document.createElement; createElementNS: typeof document.createElementNS; createTextNode: typeof document.createTextNode; diff --git a/src/typings/types.d.ts b/src/typings/types.d.ts index 3dda759..2d5c78c 100644 --- a/src/typings/types.d.ts +++ b/src/typings/types.d.ts @@ -58,14 +58,22 @@ export type GSForkQuery = { host?: string; }; code: { - antifeatures: string[]; - data?: string; - code_size?: string[]; - translated?: boolean; - grant: string[]; - match: string[]; meta: UserJSMeta | null; request(): Promise; + + code_size?: string[]; + translated?: boolean; + code?: string; + data_meta_block?: string; + data_code_block?: string; + data_meta?: { + [meta: string]: string | string[] | { [resource: string]: string }; + }; + data_names?: { + text: string; + domain: boolean; + tld_extra: boolean; + }[]; }; root?: HTMLTableRowElement; }; @@ -94,9 +102,9 @@ export type GSFork = { export type UserJSEngine = { enabled: boolean; name: string; - url: string; + url?: string; token?: string; - query?: string; + query: string; }; export interface FilterLayout { @@ -136,7 +144,10 @@ export type config = { /** * Fetch all UserScript code on load */ - codePreview: boolean; + preview: { + code: boolean; + metadata: boolean; + }; /** * `UserScript:` Fullscreen list on load */ @@ -362,9 +373,11 @@ export declare function make< A extends keyof HTMLElementTagNameMap[K] >( tagName: K, - cname?: string | { - [key in A]: Record; - }, + cname?: + | string + | { + [key in A]: Record; + }, attrs?: { [key in A]: Record; } From d96c8e1775a0835911539e7b0780b4736c987af7 Mon Sep 17 00:00:00 2001 From: Magic Date: Wed, 5 Mar 2025 15:44:26 -0800 Subject: [PATCH 11/28] Update Signed-off-by: Magic --- .github/ISSUE_TEMPLATE/01_bug_report.yml | 9 ++++++++- .github/ISSUE_TEMPLATE/02_feature_request.yml | 2 +- README.md | 4 +--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/01_bug_report.yml b/.github/ISSUE_TEMPLATE/01_bug_report.yml index 43b0b0f..ebbcfd9 100644 --- a/.github/ISSUE_TEMPLATE/01_bug_report.yml +++ b/.github/ISSUE_TEMPLATE/01_bug_report.yml @@ -34,6 +34,13 @@ body: description: What browser are you seeing this bug on? validations: required: true + - type: input + id: userjs-manager + attributes: + label: User Script Manager + description: What user script manager are you using? - not required when using Web Extension + validations: + required: false - type: input id: url attributes: @@ -60,4 +67,4 @@ body: 1. Console error '...' 1. etc. validations: - required: false \ No newline at end of file + required: false diff --git a/.github/ISSUE_TEMPLATE/02_feature_request.yml b/.github/ISSUE_TEMPLATE/02_feature_request.yml index 389a6b1..990c982 100644 --- a/.github/ISSUE_TEMPLATE/02_feature_request.yml +++ b/.github/ISSUE_TEMPLATE/02_feature_request.yml @@ -11,4 +11,4 @@ body: label: Feature description description: A clear and concise description, please include if your feature request is related to a problem. validations: - required: true \ No newline at end of file + required: true diff --git a/README.md b/README.md index 58acd8e..d1d7abd 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,12 @@ --- -
-

+

Magic Userscript+

-
*A complete rewrite of [Userscript+ : Show Site All UserJS](https://github.com/jae-jae/Userscript-Plus)* From 869ca4b45b210c9d9f174cdcd5d714b89492178c Mon Sep 17 00:00:00 2001 From: Magic Date: Wed, 5 Mar 2025 15:46:44 -0800 Subject: [PATCH 12/28] Updated CHANGELOG.user.md Signed-off-by: Magic --- CHANGELOG.user.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.user.md b/CHANGELOG.user.md index 4094647..0666047 100644 --- a/CHANGELOG.user.md +++ b/CHANGELOG.user.md @@ -3,6 +3,7 @@ ## v7.6.0 * New feature, `Preview Metadata` - same as `Preview Code` but loads userscripts metadata head +* New feature, `Page` - loads additonal information from userscripts homepage * Config changes, moved `codePreview` value to `preview: code`, recommended resetting your config to clear any old/unused settings. * If you had `Preview Code` enabled, you will need to re-enable it * When `Preview Metadata` and `Preview Code` are both enabled, it will display the entire userscript From 9b02edc5b554833ec8702dc4b5a6130f3914ff72 Mon Sep 17 00:00:00 2001 From: Magic Date: Wed, 5 Mar 2025 21:47:05 -0800 Subject: [PATCH 13/28] UserJS v7.6.1 Signed-off-by: Magic --- CHANGELOG.user.md | 4 ++++ UserJS.json | 2 +- dist/magic-userjs.meta.js | 2 +- dist/magic-userjs.user.js | 4 ++-- src/UserJS/main.js | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.user.md b/CHANGELOG.user.md index 0666047..05a730f 100644 --- a/CHANGELOG.user.md +++ b/CHANGELOG.user.md @@ -1,5 +1,9 @@ # Changelog +## v7.6.1 + +* Fixed sorting + ## v7.6.0 * New feature, `Preview Metadata` - same as `Preview Code` but loads userscripts metadata head diff --git a/UserJS.json b/UserJS.json index 24fd9a8..90189d0 100644 --- a/UserJS.json +++ b/UserJS.json @@ -1,5 +1,5 @@ { - "version": "7.6.0", + "version": "7.6.1", "name": "Magic Userscript+ : Show Site All UserJS", "description": "Finds available userscripts for the current webpage.", "author": "Magic ", diff --git a/dist/magic-userjs.meta.js b/dist/magic-userjs.meta.js index 091b951..02219d3 100644 --- a/dist/magic-userjs.meta.js +++ b/dist/magic-userjs.meta.js @@ -1,5 +1,5 @@ // ==UserScript== -// @version 7.6.0 +// @version 7.6.1 // @name Magic Userscript+ : Show Site All UserJS // @name:ar Magic Userscript+: عرض جميع ملفات UserJS // @name:de Magic Userscript+ : Website anzeigen Alle UserJS diff --git a/dist/magic-userjs.user.js b/dist/magic-userjs.user.js index 4a35efc..764d5f7 100644 --- a/dist/magic-userjs.user.js +++ b/dist/magic-userjs.user.js @@ -1,5 +1,5 @@ // ==UserScript== -// @version 7.6.0 +// @version 7.6.1 // @name Magic Userscript+ : Show Site All UserJS // @name:ar Magic Userscript+: عرض جميع ملفات UserJS // @name:de Magic Userscript+ : Website anzeigen Alle UserJS @@ -3026,7 +3026,7 @@ class Container { this.tab.create(host); const tabbody = this.tabbody; - const getCellValue = (tr, idx) => tr.children[idx].dataset.value; + const getCellValue = (tr, idx) => tr.children[idx].dataset.value || tr.children[idx].textContent; const comparer = (idx, asc) => (a, b) => ((v1, v2) => v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) diff --git a/src/UserJS/main.js b/src/UserJS/main.js index 941cb25..037c9f7 100644 --- a/src/UserJS/main.js +++ b/src/UserJS/main.js @@ -1352,7 +1352,7 @@ class Container { this.tab.create(host); const tabbody = this.tabbody; - const getCellValue = (tr, idx) => tr.children[idx].dataset.value; + const getCellValue = (tr, idx) => tr.children[idx].dataset.value || tr.children[idx].textContent; const comparer = (idx, asc) => (a, b) => ((v1, v2) => v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) From 066972197394ae37a2acd9c444e9dee5a389ede1 Mon Sep 17 00:00:00 2001 From: Magic Date: Mon, 10 Mar 2025 15:28:35 -0700 Subject: [PATCH 14/28] Added FUNDING.yml Signed-off-by: Magic --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..8bcae8b --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: magicoflolis From 0823856511647fddeca9e74668388b9af70d2f2c Mon Sep 17 00:00:00 2001 From: Magic Date: Mon, 10 Mar 2025 16:15:34 -0700 Subject: [PATCH 15/28] Web Extension v6.0.0 Signed-off-by: Magic --- README.md | 24 +- dist/userscript_plus-5.0.0.xpi | Bin 162736 -> 0 bytes package.json | 2 +- src/_locales/en_GB/messages.json | 8 +- src/_locales/zh/messages.json | 2 +- src/html/background.html | 14 - src/html/form.html | 68 - src/html/popup.html | 115 +- src/html/settings.html | 26 - src/img/icon_16.png | Bin 846 -> 730 bytes src/img/icon_32.png | Bin 1144 -> 1547 bytes src/img/icon_48.png | Bin 0 -> 2376 bytes src/img/icon_64.png | Bin 0 -> 5714 bytes src/img/verified-svgrepo-com.svg | 1 + src/js/background.js | 983 ++-- src/js/config.js | 210 - src/js/constants.js | 88 + src/js/container.js | 119 + src/js/ext.js | 34 + src/js/i18n.js | 29 +- src/js/language.js | 26 - src/js/logger.js | 5 - src/js/messager.js | 124 + src/js/mu-common.js | 385 -- src/js/mu-hermes.js | 126 - src/js/network.js | 80 +- src/js/popup.js | 2393 +++++--- src/js/punycode.js | 493 ++ src/js/querySelector.js | 10 +- src/js/request-code.js | 476 +- src/js/settings.js | 294 - src/js/storage.js | 118 +- src/js/util.js | 192 +- src/manifest/chrome.json | 31 +- src/manifest/firefox.json | 58 +- src/sass/_main.scss | 2 +- src/sass/fontawesome/_animated.scss | 152 + src/sass/fontawesome/_bordered-pulled.scss | 20 + src/sass/fontawesome/_core.scss | 49 + src/sass/fontawesome/_fixed-width.scss | 7 + src/sass/fontawesome/_functions.scss | 57 + src/sass/fontawesome/_icons.scss | 12 + src/sass/fontawesome/_list.scss | 18 + src/sass/fontawesome/_mixins.scss | 65 + src/sass/fontawesome/_rotated-flipped.scss | 31 + src/sass/fontawesome/_screen-reader.scss | 14 + src/sass/fontawesome/_shims.scss | 1578 ++++++ src/sass/fontawesome/_sizing.scss | 16 + src/sass/fontawesome/_stacked.scss | 32 + src/sass/fontawesome/_variables.scss | 5044 +++++++++++++++++ src/sass/fontawesome/brands.scss | 30 + src/sass/fontawesome/fontawesome.scss | 21 + src/sass/fontawesome/regular.scss | 27 + src/sass/fontawesome/solid.scss | 27 + src/sass/fontawesome/v4-shims.scss | 11 + src/sass/fonts/Inter-Regular.woff2 | Bin 98868 -> 0 bytes src/sass/fonts/Inter-SemiBold.woff2 | Bin 105804 -> 0 bytes src/sass/web-ext.scss | 25 +- src/svg/bug-svgrepo-com.svg | 1 - src/svg/checkmark-seal-svgrepo-com.svg | 1 - src/svg/close-svgrepo-com.svg | 8 - src/svg/download-svgrepo-com.svg | 1 - .../expand-full-fullscreen-svgrepo-com.svg | 1 - src/svg/filter-svgrepo-com.svg | 1 - src/svg/fork-svgrepo-com.svg | 1 - src/svg/fullscreen-svgrepo-com.svg | 63 - src/svg/github-svgrepo-com.svg | 1 - src/svg/minus-svgrepo-com.svg | 2 - src/svg/navigation-svgrepo-com.svg | 8 - src/svg/plus-svgrepo-com.svg | 1 - src/svg/search-svgrepo-com.svg | 1 - src/svg/settings-svgrepo-com.svg | 4 - src/webfonts/fa-brands-400.ttf | Bin 0 -> 210792 bytes src/webfonts/fa-brands-400.woff2 | Bin 0 -> 118684 bytes src/webfonts/fa-regular-400.ttf | Bin 0 -> 68064 bytes src/webfonts/fa-regular-400.woff2 | Bin 0 -> 25472 bytes src/webfonts/fa-solid-900.ttf | Bin 0 -> 426112 bytes src/webfonts/fa-solid-900.woff2 | Bin 0 -> 158220 bytes src/webfonts/fa-v4compatibility.ttf | Bin 0 -> 10836 bytes src/webfonts/fa-v4compatibility.woff2 | Bin 0 -> 4796 bytes tools/webpack.config.js | 6 +- 81 files changed, 10681 insertions(+), 3191 deletions(-) delete mode 100644 dist/userscript_plus-5.0.0.xpi delete mode 100644 src/html/background.html delete mode 100644 src/html/form.html delete mode 100644 src/html/settings.html create mode 100644 src/img/icon_48.png create mode 100644 src/img/icon_64.png create mode 100644 src/img/verified-svgrepo-com.svg delete mode 100644 src/js/config.js create mode 100644 src/js/constants.js create mode 100644 src/js/container.js create mode 100644 src/js/ext.js delete mode 100644 src/js/language.js create mode 100644 src/js/messager.js delete mode 100644 src/js/mu-common.js delete mode 100644 src/js/mu-hermes.js create mode 100644 src/js/punycode.js delete mode 100644 src/js/settings.js create mode 100644 src/sass/fontawesome/_animated.scss create mode 100644 src/sass/fontawesome/_bordered-pulled.scss create mode 100644 src/sass/fontawesome/_core.scss create mode 100644 src/sass/fontawesome/_fixed-width.scss create mode 100644 src/sass/fontawesome/_functions.scss create mode 100644 src/sass/fontawesome/_icons.scss create mode 100644 src/sass/fontawesome/_list.scss create mode 100644 src/sass/fontawesome/_mixins.scss create mode 100644 src/sass/fontawesome/_rotated-flipped.scss create mode 100644 src/sass/fontawesome/_screen-reader.scss create mode 100644 src/sass/fontawesome/_shims.scss create mode 100644 src/sass/fontawesome/_sizing.scss create mode 100644 src/sass/fontawesome/_stacked.scss create mode 100644 src/sass/fontawesome/_variables.scss create mode 100644 src/sass/fontawesome/brands.scss create mode 100644 src/sass/fontawesome/fontawesome.scss create mode 100644 src/sass/fontawesome/regular.scss create mode 100644 src/sass/fontawesome/solid.scss create mode 100644 src/sass/fontawesome/v4-shims.scss delete mode 100644 src/sass/fonts/Inter-Regular.woff2 delete mode 100644 src/sass/fonts/Inter-SemiBold.woff2 delete mode 100644 src/svg/bug-svgrepo-com.svg delete mode 100644 src/svg/checkmark-seal-svgrepo-com.svg delete mode 100644 src/svg/close-svgrepo-com.svg delete mode 100644 src/svg/download-svgrepo-com.svg delete mode 100644 src/svg/expand-full-fullscreen-svgrepo-com.svg delete mode 100644 src/svg/filter-svgrepo-com.svg delete mode 100644 src/svg/fork-svgrepo-com.svg delete mode 100644 src/svg/fullscreen-svgrepo-com.svg delete mode 100644 src/svg/github-svgrepo-com.svg delete mode 100644 src/svg/minus-svgrepo-com.svg delete mode 100644 src/svg/navigation-svgrepo-com.svg delete mode 100644 src/svg/plus-svgrepo-com.svg delete mode 100644 src/svg/search-svgrepo-com.svg delete mode 100644 src/svg/settings-svgrepo-com.svg create mode 100644 src/webfonts/fa-brands-400.ttf create mode 100644 src/webfonts/fa-brands-400.woff2 create mode 100644 src/webfonts/fa-regular-400.ttf create mode 100644 src/webfonts/fa-regular-400.woff2 create mode 100644 src/webfonts/fa-solid-900.ttf create mode 100644 src/webfonts/fa-solid-900.woff2 create mode 100644 src/webfonts/fa-v4compatibility.ttf create mode 100644 src/webfonts/fa-v4compatibility.woff2 diff --git a/README.md b/README.md index d1d7abd..fc8b98f 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ Finds available UserScripts and UserStyles for the current webpage, the power of [UserScript Changelog](https://github.com/magicoflolis/Userscript-Plus/blob/master/CHANGELOG.user.md) +[Web Extension Changelog](https://github.com/magicoflolis/Userscript-Plus/releases) + [List of known issues by Web Browser](https://github.com/magicoflolis/Userscript-Plus/blob/master/browser-issues.md) ## **Download** @@ -31,17 +33,23 @@ Finds available UserScripts and UserStyles for the current webpage, the power of * [Open UserJS](https://openuserjs.org/scripts/Magic/Magic_Userscript+_Show_Site_All_UserJS) - outdated * [GitHub Repo](https://github.com/magicoflolis/Userscript-Plus/blob/master/dist/magic-userjs.user.js?raw=1) -**Web Extension (under construction):** +**Web Extension:** + +*General:* + +* [GitHub Repo](https://github.com/magicoflolis/Userscript-Plus/releases) *Firefox:* * [Firefox Add-ons](https://addons.mozilla.org/firefox/addon/userscript-plus/) -* [GitHub Repo](https://github.com/magicoflolis/Userscript-Plus/releases/tag/webext/latest) *Chromium:* -* ~~[Chrome Web Store](https://github.com/magicoflolis/Userscript-Plus/releases/tag/webext/latest)~~ -* [GitHub Repo](https://github.com/magicoflolis/Userscript-Plus/releases/tag/webext/latest) +* ~~[Chrome Web Store](https://chromewebstore.google.com/detail/kbelpalpbddhjhoakbjkfookjeiennbo)~~ - Under review + +*Microsoft Edge:* + +* ~~[Edge Add-ons](https://microsoftedge.microsoft.com/addons/detail/golkolijobdaldjgefapmcknlmkjlhdh)~~ - Under review **Bookmarklet (not recommended):** @@ -61,7 +69,6 @@ javascript:(function(){['https://cdn.jsdelivr.net/gh/magicoflolis/Userscript-Plu * Query UserScripts and UserStyles from: * [Greasy Fork](https://greasyfork.org) - enabled by default * [Sleazy Fork](https://sleazyfork.org) - disabled by default - * [Open UserJS](https://openuserjs.org) ( limited availability, will read `Too many requests...` if limit is reached ) - disabled by default * [GitHub](https://github.com/search?l=JavaScript&o=desc&q="==UserScript==") ( requires [Personal Access Token](https://github.com/settings/tokens), no permissions are required ) - disabled by default * Built-in UserScripts: * [GreasyFork Bullshit Filter](https://greasyfork.org/scripts/12179) - disabled by default @@ -88,6 +95,8 @@ javascript:(function(){['https://cdn.jsdelivr.net/gh/magicoflolis/Userscript-Plu * Maximize, minimize, or close menu * Sync config with UserScript manager or per host * Customize timeout window - can be re-injected using your managers User Script Commands menu +* Query UserScripts and UserStyles from: + * [Open UserJS](https://openuserjs.org) ( limited availability, will read `Too many requests...` if limit is reached ) - disabled by default * Automation: * Inject on load - injects menu on page load * Automatic fullscreen - maximizes menu when opened @@ -95,6 +104,11 @@ javascript:(function(){['https://cdn.jsdelivr.net/gh/magicoflolis/Userscript-Plu * Inject Userscript+ - injects menu into the page * Close Userscript+ - removes menu from the page +**Web Extension Features:** + +* General: + * You can fullscreen the list and it will open it to a new tab + ## Previews

diff --git a/dist/userscript_plus-5.0.0.xpi b/dist/userscript_plus-5.0.0.xpi deleted file mode 100644 index eec2c4a42c9dfb7b68998ff84b5c4ee85268463f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162736 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%0AIe{Ozau%skD5ecr z_@ndP8d-f!+HF}ZZzI=1%RZS2-&DhwV(GyYPQdu00$l7n5HVC$lR3hCra}-pr3s{7@ z2|DB*-MiAKR5Ry4eJK;sC~$!obW#GBzq=XPv+5`p9y0GBP1`#fz{MM{(?di|fpZWw zgDY38k`QN8(+Y*pY7%08eWabuTdZU2R@ahBG|1{58EdbH?OGgV18;c{>RU*h$dJ@x za&g3-MT;h@dQ`XIMaILBM~)x4uTSU;8>(vA(>&*1%5tgibnKo2mB!>5%NKi_->bzX z%NKVBkLD=aG@IQI8gz{%op$nB^W48=7v9rjIU44p^j1Ii5&q%CE+`@uWbVy zidl-9{Z+JjgoSj{&~jv{FQ)We2igEQFXXFci~=QbO+~uve7=#UIqz?c3BreEBoIh1 zhn4g`ItZ}N2a}Clklr<%FFMx*%U7c>lXB~{`uHx_ki9R5C+z!SunIUq@M8~ptjWN1 zXC;mSd!;iS@@h+y!2Rl40KHqToy84X`4~NiwX);jKf@9@67dI&Lomih;tBKO?SFm& zl2DI1{4^J33Y1_n;zjZn(L5Wq@3~(ym52M>-m!0L52XET9LRgMNqj19u6J&ud)5%ln)~XcLGg#?f}3H>|rrt@BDq*rh59% zY6#1Dz>om+5_{7l#-|E_0{{zB;$I-H2*I%kLJ&9-0T2LeL2#ndvu4lY{XaGA_s>)^ z@g^|{fo9=?g6TXXJdTu1$#Vq;dgU^i!H={Ho<6!gHT0_!AHTC?{Q1xdM`^DJ#D7KW z|4L?r1%z;Qgn*4Nm#5+BB=W7&$Dmnw*yLr(_AKT?`gq6DX{$F+(i>ZJQGi|sJp%Qp z^@6B^=|OlPzt4iC0-yqG*h`^}MAbw`#gW7w&jHPWA5CsIwuQ4e}B@_zy^$43@7Gb#+Y(n~Pw~?Cjlb zm?)!4W=msc$DrT<5k#_ut7sRmezM7GR7?CM@NtD#>!XXF70nM%s~0nb3VmBEDw*k8 zgL(pk`98zGJ>x&a<6O*8wUeO>fBy3<9ANDTW2WS-uc#=bpY zZ{Nc$p`v-?&6a9iSr)Xa0>#G0cKuFFOvK&TFpK40Irxk_~_V@eId2YKdVt| z4hSr27AJ$m?qTAvct`@*y{7-x-N09M$K96mL-wjFF8)Oz{$39KJTVe7+17SNSw&^if_HOsf6%2NJX`?T7@WZ% zC7E%+FoQaW?VpHbv6crU{A=<@0-2(!3Q8WO&Q3unlq+hjdaY;MVSD!Tj*x-@u=gT% z^$QZ;$cd#CMOphQ(&1h^eRg+lZuXM;B?tlnLJ%Fq*FX`8w($h6*uQZY5!;9!OZKY@ zK1T%8d{v_;Y-_bS+C&h$K#VYcC_$J99H%FouF<5e%~h`D8d@qKl!!j4PdH`ly_|o9 zz9(;eA&q5~`SKI;1o?Ou4A$mGK~$8KlH%g*pALLcdpRerY7@^p-@I3bP5vLfHu2zF z?U0Izq2T#~_A?)lVRtsxoTDQnmY!Y$<4$U0;lF-~mJ}q&)TzsTTcN9c%TJ1K0Vr*y(|2Krx#Q6zD zNn=9S10po@gxj?h!kladJdE07{)!2_uc##5i&|b;^}e|0+q>&z1s?FZR!8w6_Pvt6 z5ROpZh{i2Lp54-=gleiwzEUet`eFv%t}V;K!FGBLTlSlGPpDufd0`>DkoaMJef@0? zUr_TEft#oJl)x7sRQ&_mh26;E)8j*=Xe!3g%L^+nozv1^-^Aal;+B2;+*J?ug!bbI z1z&=K44&fR>;m*xXy~gh{Alx(hdkldGR+^kDG1Vj4<9c&cGOub1S0?06+q24Y@kjy zrL9S~o3E}>PX-;jrAHe_AIxP`DRPXQlu)>E0apLk!Q|xRCkY8(Kq>ToVv-0A55A5) z5n9s4L9fkt#;Y@m+bPe0=dOS9lt$p?P}*-g2>+z|>O1S?wSWI+#-yK4G=z8A*x1Ms zCc(fS#IqUDn8AY2&ssJ3SeThFexrL)zTyQpZ9O>f;L@}0A%zvBr>E}}6+JvZdxY&M z?w}wCSFzP){VfU!R&3(&EeH64fGF0reyi?M47a`Zr2G`4H-Af?iZ-R;jBN=%J_d${ zq9S5!{tkk+zA)d8P`$fRW-3Qb31pV^PAtpHw!`AR=m@zYGYda|cYxbpy=7&EC^kg6 zW3RA>Aw`y7nDO5oX&D&~b=5&@i}MWz&JZUI3z)}M%vlN;RHHic6}J!gLq4X@-2T_b z;rm6`e7d!lg;Aqp#`LtbkW@fr78YC;x}}}#5N8)hWQ**7y!pwg+kK8QTCEJoF;I4V zb{@ZZ^BF`e>F5wus=t7T zILsB?Dly_;B%p?9Jah#cV}|@?E9BdhtSYRU%nR~X@@BG2A;gp;Nf!Dni%!;^aOj785@(isXmaTD+UwGBeAlHyOG*hJs~T5!Gv*oQE>ld?65#`a5T>ZkF9q-9$;J=WNIBr%+qxTJZY`=#1X)|mT$B$js zT*#z)TCchu1Cx#$6$y~W#6)D^zDqxk*UzqN8Uw06fj-+#H{B%%Mrmmoglt2lgoIZ_ zO8aW?s#xy)*{h*|rlngt&@^kO%;$z(9Um1pb0+k$^%jRRm?mtwrn;QZ#?YW=J%avu z&P=HjEpyZegTw@?-0EgHTKeXb5wMT9$8pdD3&DS*qfjbJO1lR?M7J~N@?s(tYyb5( zKJC=#fQW*q=z{%J>A#|R$)~_`4R!Tq4uelLe2T7RG|0mzzlSl`rZ?(J2dlOwAr&

4H_PHQ{)`L_uV9?Z2U$=NwxCs>%Jsabe*IOjId%A&%qQ`;xa zrH(oKDCK@%yk3f{_12+zL9kg7fdU3t;lUb8YAKq0*QI<$;p^FG~7%~1(oHLQG%cl5Du5u4A`@A z2ykMA3Aa#CM=ogGHwQ%I-fufUCEU;**8*FN;oBXjuL0K}oked`9Tp|pdIuXZ#(@wmMIuaZm z4-ZdHR!*<3pI~Z7AwDHZhJj)~w9pf1q@2=Q^N%Ry)#{0~*4&UG^7vgGcHr$~)@6A8 z_GSUp*wAb4^6-%m7jL=XctAl{R~MFBKq@v3AG6LYlS|+f3M(tCGqtrp#LLrDb7NKv zF<4z=W23G?wX!Gu#$<(Z^_ig_4B@~4N2gD~Cp0w`Rf4&ER9v)5C75wi5{z0@>}e72 z5#MmbFH>l4#yR$g=X&mAbaZ`swzVtsPTX-+*iRNU%hd@vA)#BhMvk$|a{no)OBXcY zzT>8F0z}08@(QiOhbdnWr-%>?ZGHRAus{E@Sq*HWG$NO0S57h|sPZy0RyXqU@(>Ij zo3!kKOZ-J)m@sP>P$H2nF~CJ*V^2}cP6M#kmfhocI5{~(V@S!!m%i3>8KpLzi%eK6D0(w5td3b&MV5~txU?>Tu8 zBY}P*6~^c5VIA6lxpZKT#$F{JLoB*!=l0L(0!KeeA#=(9?=;3W@(^Wo4b} zoT1OI#Ki0dfEo6@dE@KUPpxNz1XE_ieLXPHzgpe^0q-au7Zwtr+D7?E7`rhAvSb7t(yp_By92)IDn$#>dC!t`@t!eO6A+cdf>LQQCxCK-cl& z^71`AOjXxI|7?nHRXf~_*+)gRc=S8Za1d1Z z9Y@|iBikeNC?Iv^mdqe;9eB^+z~-@X}B|le^j}2it*oEk>Lx+X5{~~^6wGOs(HaMwuttPF7O@(&9K4^asPs$o%vpg zfr-RK%YdPdu|xI}5Bm3O)|_Z_t#sMl*e?Yt-n?t;aeK54@Hh zr^AuodZrgiEfbSCT4EI;aNVzjS}hr3!bxjc3x z>2_we6bpZLt@|3jFOzg_Zz``_(}E>`W?$U?pLaiz5gC}OouO!q>AQnL3Y4rwVm?Mj z$3fl^Ns;}u+6hs?8(j0t@84hpMTN~e^Gm*8c%ch+#z30dUYn?$>a2Aex3^BZM3wD| z1GNSnMMqB-(q5^@goqKczY7cNnYw0%7?;)j{8H8|0)GIunwFMs8)yB{qv>Odiy+9l z)HxVEP>_7M!jbNmq)gHE&`3v>bn-QH27V7Z#yl=A-nZ^oMkNb2;eqeFd*P5@&1T2c z^Jq9CUg-M%oNVu9^1qc8O(}8k{ii4QBlXILN8F^q{Ic3<<@Lo?FL9CrB|L&4!G#oQ zhX~%S11ix@bX_+-{aj3k-!U;423oUPeGY`q8(68YK3*B$1CN77&%p8u4p(}%C2vYf zNCCYONg1)1?}sJxJ2#GBtLEDq{nuaqR+tx8<}6`l{g2b8jvR`N_vh)pB(nAOV{**<-;w|O-E`BR1lC5Uwcc-k=}mb`}5`6N^6#GF+a_V znjAWC-rXPY?C!JA1xyiuZjHss#bpIKu=M;qAeMWj2CrXVS7&Qy=l1kmS+7lxnemLb3h~$-J`Euq;kG-?K@$+8j^!D`?B|P)R z=PiUMv|L%$(b2(o2+mDN))pn&{p)M5g=LfF8hAYrgwN|05sdarhORUFyO@whXU_8S z?9BRpmdX=>Ml(AjCkF`p{_&B|essL3QQv0Tl`H!?QO`*j#q6Hv4}(W(Qp`nX2REnB zhlep0Ttq~KX{Sf+DfOF=KmDI-SxNLg1A}Q4e5Ahl(wFg>k&$v2LaV4{}lm zR;2#^{+bZ7AIYG~ktq_;N0UQ)-D7~->l5wrVich++#{@3HzXRqn5Lan{%tPNx4Njc z5v16O2SkID6%`F^EW1!#Op4#F&60z#Z8-tY{`B@_qRz&85$GmdZ$O>peRH08 zR$g8XIA_o;>ObgtV*Gqxv25IPCnlkwFtUWi!N)&x! z!a;!r&->#6mN`=N=fm+52gNJO_x*30Pfy0$b8cW>o=@MuFQ(I8J^zp^UT)mFo!JLyt}4Biaa=j_Hk5P8k1Q*MTU| zJIFL2->PlFU=g*bh&JquMEGpr~jsHMOa)Pl)0O z&}+M|fyq_8=^0^~5)LQB1xuu_r>A%9UAVsI4vw?pj(GDi{&w?nT|DKaK~#Ae0|XIz z@;L0aB>E`589cAjf!?ugSW3G3QebCny!SzKf$0qoOrNw{8oO@-Hn9`{nz-t6w)_sQf8Z2iDRV(Os1^YAtx{;9N!Hf~;IoypgphK<~MS2SA z-K`ik z#Z%iD>Wp&SF9pmkkd~SvjVHkg8pq9z8ix%Yek}74 zIdR!sapq;?mH1J=plDYEc(rQGIMZwt*?5x^ceRNz6^0O&5%3Bel1KBQ1ro5r{vdZ$ zae`x4%UZsC6<0%p*c*Vje_rqCC@>O*Wi;B=SX^AB3jSmJ6F)))1%;m#Wicl~oNx{l zJPl!CF|UhHmq3kyVq$1Gv7ABSo67rn?PF19Nt!|kRoDF&&DD+3B2u|?V=sn{{BD8U zJDkE7WM^+L@m4!wSNRU84sO=z(o_N&wU!=S>9vW+jqe)6OPMKgd6-7p+PW{*1r7X% zm&(yg95kP9d8Fx`HeX_1TwLI;1i86wsM}nso~5+&ML(v3o12f2qPvAJI3bp-X<;kv z9K}o#N8Gx%=^og}O_ds#%%-lPVR=}5i&ynUu@ClMJo)0}@{$guX6KJ}ZesWTnNKw6 z>EflDdF|k7(t2qNF@)bOTk!Bx&!i0jo-al53*NJPL)_Az94q() zV$hZ4adCC^k)x&uGJn2ycSqvx?gE;V9`(bC2F+mhEXMy9|H#Z|)##kh7UNX?-muft zQ_lXaxroTJzm(r6Sb$AYQK9B;Mj2*RgSTN6txYwu@H}!rlgnUs*fa?Eear8^j)U)i zo#6=%j70qEGyIg1IbGr81Q7@TKWTU9F*G*|g@}$063jnrW}iOK8SNVG2pOx%!IQep z){Hwh@k)4C8HvVVxBxPfEPHICg@TXyh}Mlv1E(?^e4X2zzb`a?jy8`~S~(8iRi*bY zy*R1iG1PSufngIFZ1Gc-Tfo8G{6V*p=fY+!ZJ$fvoz3l(}9?4tLa&;_j z7ZX`gQSmu2VD@`z^@49-Pmd51n|)@oKp`wFD$3fzf#K=lMNkHF=>XF$iE@62hlOQe zWXfK8IYQ%1{Vn*yf&}XiG|H1P?%2E0!tgACx3x8&z?vL9y5#e$8XGICY>{8rDx|fI zO#lJDI5HFE%*|b543wVATM1fMUw^-`$_GyZ#iF&GurzgF>W5oJUnaOZqW%gt#nIwY zknp|b7NqbKra5;baV;Zoxu3ltG&HnnFn#rp(p>PA)zyQ5VQm5tlUmaKPI*G`mx6-A zp>)0ZJ)DA~Bd9?wL*c1XvNQUSal2=AZ3Q4BDOuf2c__7Ze%Lf0?d8?Ay|Q9SjO^m* zS}d0c2876Z;dWjS1QbI+FR|C&t~JKz-2OMTFlO)_*rM!}Oy2jl0gRQAnYlqF)I)>i zuQ)q98Z{pFBf3qo54 z35yytvI&12G6n`l5C|S#4v1G|^ra~ujJJZT>_nd2Q-eV9Ucz48_YC_hUGN=c>f&uefciC6A17W+ncmAk4sPG^+2M4CM zzP`O*-Cz*zhV{}!vZBA%wzjq|Js2xC2Xb86h8JOYfwld=(iFaza#7LHJ}t?FxtEv9 z>pLFHy2m-Z^w*P9_vHoZdkuHA=j*pljnROqD=8sSJ^U<4H>ZZkitBInAmPE*qEY%? z`>NRqot&(wgnrhp>;ct)Tj;iFIxKinN-Dm?6tjO(gTv{(Jy%08PXEW)*PG|z-9rng zPH19$cFdF-*5cc=VfCr@yu$A6Y~!c(^gp$?Hs86vnGZ=2AyLt$m9r@^ZstUEvWG9e zc1x$$a~!8s+=<=O%OiXEi@IDmAnI;|utiej7PQ4BUdJbgIY-UE;#xJip7PaZq9uwQ z;Vg=eH?#;!3&dK9N(W%D&e`zB@UF8dvg{AVQ-;y!Y6ayhdNdVimj zXf+7M4k)z%43ZZE5UTz_LHFJ{g>bLRV!fBR4dVeh2Kq8ksluXHGBI&iHVQTU#kY)4pcm8B2Sy!Dj?Ja$um4` zlA@;il7}zb0J?iLbb$x<;7{ksOzVf#vzf4Klu5eU@-JkNqoqYpARzb$A^GHj?cB{( zeC(PM1{t{!D@08n#$WtIm9S@DzWI9Iq?$E*+AEKfgJYS>W~+AsR!>y);B)>nG$$vg zyq<|KOW(&-3CV;jBe|-IhCKyvt6QRPpa6P$EfCNz`Pd2hgV-=L(g&-nHC^uSHiidb zM`v>XUf)e82i07zEV{*v?7z)!d|nRSBRoIrS7WQK8pF=|tcD4;5YOHX-U`OU!=`C- zf}o%@(%+HM(b2u;MshG__Axls^EC6k+NrB`iI*i_p4g z;_K_{K48YV0%*BBdsmVntvu20;OOy^Z;8w0PC{D}3%%)BnN@c8i1jd&_DVbow5&fX zCV<=n-~4i#lZP0WlOi%fiEX*c%9L*PhYAt|4-Y$07I+G)NCdpEh3^+h`qiF z#b<0FAW4#vz{r4BV7a$!qVl5~+So+%Y|cgf2;KFvQH97RKsAl8m%*KmV&5{-(Ede> zJK+b8Jd1IK%@v&{_why59Xm@s= zw%lrEzt_9Nv6A~TP7HTBd;8wMH;YMBmYrM5e9|wfqeCSH&!mKaAMrd=wD$!RRGPZQ z;W_=&`zqUgf;Nb{Od|)EaU%TEv`dZtheS~#X1~AbCns?B2HK|Z5uK&=jT=<`R*2iu zKL&x-;CY_J*Fc8~KCB|n$ZS5O3lCS<;o%XWAct%hxjjm3zOVCg-4>woYvY;>2apwW zYqG9QNbzI7HA>N*3CX}MZAQvcvksO$9>=NU@@sS{U6Y5N;gL2{sJ#IUp{&fsU?W+zT0s-MI*G71{?^+qyBLY`&t&W2fYH4H|} z3yWBjdhV#T)UgOF)gQnkj8>4Jh%tk=1qCzV@6k-2*{mcKWp~R0r=}%2U!Wv`ImB;#_k`pn~a(#E2_=A_GjmKq}ENYs?|2{a_rwU?=`t*!Mgu(A>YvR@N1;Id$EFdmCM zElkv>%+1XH`n#g4Dfio&nyQkO(bFreWI=qW5=)zM3vFADynn~ymrV9P2B&HvbCR+r z>VmduvCfRT65_Qo*275L@7E(vCxDLh<{&D$5vjl1?cf&E5p5^BDiy{E|Gkk1uwF4g z2B8K5(h~1RxQPN$U*PL1%``mzP&rMb8lg4>q4llq$afX8tbfztf{D&gC`|2UrFU-JXY5tk8Odj8u@mjlBJjz|Fj;QzG$*_HVpBkO;=>DXESW2OTrqt~29 zD#}a1L1X{t)EbE8uWA+7XvD#g zM(~9bv?Li?6a5~(nIAo_7tWvp7A>KwSob2bwfoj^S!Q(*` za=rMMg!8Cjhin;o7+w}z^ZENhBjbvNA!&@ph6*GF6bV(iGGC(O`Z2HQM)jJ;C%#vh z5HLTo0k_N|Nkb^9VnQJyJTz4!66q@Ws8H6+VZRTOKLTR(p}J^{&b0a9a1G}W-yz$Z z+Cvpm3{;p9-UhhGCa@>#VA^oQul(-WOHhRTAR6Ao1~$NrdBq&u+6R!3b|4tbcyg;C z^d5n`6e8?q8pu}AL&P`!;@im(VfH~mY_%;<{PF~Wv~GWWL2z+__sPcepS?T+JRH7r zt)8DjirSsqW9gnHf6@YOEF&Qb`2Nq8-&L0M(*xxwspax>G7;rJ4G55#jrr3F;VLC3 z25|xciwGdIO$++*Q=%$Ji3+KDu1)IrsV zzkcpccwk{7CO7#^@!d?^Pu%-n=e+Yycjfu?0Q>VL0y%>0KoJ501p=7>!hjbbM+nA2 z-exF4yud2J6c8ue4s_r+z}|MfxrU3MUmp~Z$P7RP?PJA6p!$FgrU8h8yr2X!Htx^^ zZ~=xFEA{cCrsXv?VuprgwQth{(vk3YD^%nHd0pTR~wu>+$h1?a=uZt7x`$ zz>pCa$gtNT{s0gh5*(aLtJQGuvG&(Sj>r9iFc3dGD{K5mghxk1n>A&wFD(sABA45% zAxQJR8>J|zFQjB9Cl5p5dqDhtYU#-UpaMrgAlmBRf2mknmOF@wijK{d$kbYxn`i#U zb748vyiy^Q-g^8LT}VPb+F{L?NxwM6@MfDx~Z;ZFdXHkR=~6Wj+lkQHBEi z$TBBxw*?~M+Fy9^gkZhP0P>B~AT~s05KUspegX5zOtSa)?eE{QI2^|JN0TFCW5SAx z@uV@YgZMKCYHDifd_L@VcXxHhLs3Dz^QeFffI9FCy5M_0jbMc;cXVMZxL`0LBy){= zG!lvUPEj0x@DJ$a|F{uRRaM>CIxuCXA#<~HSZjhB9UYB`i<9v7e*6AYNuRpl);ViA z*km;ypOpmz*aCbZ^ojzm0hU;uB>MEvs#S|RlNyLXjwdq(KhsBm0|!}OTl?9_kt|X6 zT4y07CJz45*xA>AOg!1FR>&sC#wP~{gIFx)Gn<<^_V)JKOeSHAFXiQwx%_^aKO}Z@ z84>7X{lWqk+6#!&LL~Af}&BYzbPX4qXhbYJ}#4v{`)6RZ_xdbtJQC($vU3jjRH0ZWCKw(;_Y8s#-D}DJh2E&cPv|XGq1x<$*1Niz z@e@(f(bQD*?ytA=v6ciL6ZQt^8T3cHiD|W1{z5P)z z7!0XcXjm9C4NY_~AtK->*pkZD+jL0>52y1!=K>o9aY}%jSCTm1{`=!;mY-2SyWr|5 zZLO`2o9%9-qen;PS?`zJM%fq<7?2<+G& zIfdQ%YNKtzl2ukt?l70nCp{sduda^qYP%;dm{1WBl>htVexuuur{`r4ru(KJCQ{R?3^uD{VW0lZLt_VE)tTE{oyzY067`i?Er$n!9)g2o5?WzR3_UvGLPpI+T54T zR5sVoO+LmAzJzn+B|`dov$Ju%y}h;Rj?T`;9?zF$D0*r>|14U2eSLT(9{dzkt6?8- zdwaX{Vx<}_Ep2jhpmfRqVeGAfB5R^9QQWO@_r~4b9U6CccXw~x-Q8)Raks`AcWB(* z-C@o*H{!nh6B83r4@42CPE}^^wbx#IWgcT0891OzsHLp@XLr|lv&$>l%F0TWCY5}Y zDBwL&@avtGQLkeVfF&qM$dz?4%mY&ki^kg8xSv0N^0}R&^YZeZTwN)+pj)w~AVDeG zuZ+mc%llq+KmA)>l>tU1O5miHJ=}&k}x`bLONlD3`x696j zvxg={KRk4cUP#?G$DscHepe@_9R;L8-xXW^_-Z;?2b}t7yws)1~c}2u9Nseib zt!IU2=jU?3uK^m}Nh!KUI(^a(aDS(#(_b4J8#9xWO>Pi(?I6W}ruE13KVrM_5P&LH zs$%(nUs|)G}Xj%)<%9*8OH8uZK(Qqu`P1rdB?8|AOxCU3GhW zap18S#D4q$n)n@9zlUzU42+)MU+!v5-Ju=3-uzY<;hS_-tedl>rKN$D0KC?lZLq=- za70R#M?E&Z!g+FQ4KRtLNROuT6{554v?M8#l?oLV3l%jtsNjD7IgPv8Y31b`B}GLL z4-bzRJWeE<)T*ycY~j8NrDDf}F^n93A9XOvEASOiE*j|HD1Bt$A1(cceY3@qg|n6@ zI5<{r+w1OTyu5s`$Hf)Z)uK*LH-Y{0!X>gGj>qzoR8&+Ez%YEhOb0-@LTOe2VFHK) z98MvvTmIQsK%mrhBO-wct>pT0v$3TBXxP-)2xMATz#yeiJZtGP{UqM|eha_1x92nX zEt|s*2<))}7+eB^Ni<6N-|g+0o$eP!fH|$S4&m_Ec_2l~sHvQSLhJL=+{JZ2G|}&_ zt{i}>{Hm!r7)_>pnUiI_sjllOqKfLKDFha*%hA+_8cIoDpAdkTEd2br04~!pG9Gzs z`AGs^A+U-8;A`4cRacv6YiE_yhXh;GD1%>F-YBaBJX-Na(9>TD%%j+(NR{fWun;ZMx-5s~`ni@uOQW7>6 z*0RZ5IFY}mvk|D{#cH#9PR@KqL10qW* z$rp%4Z*fh!+3W*`d?q6>9c^tc?|VzI?FO@Pz`G|YjB*TM&i1w;5Ro@Q(1hE-LVRlq zwOOv64VES+C%@O!VMv$VH1@cRQvx$IH!oX^CxZc#)<#z>XQDMc1}3IZy}D3+OC%xS z^W{jtjxwYl1bC&&KmzMhT|I1WP8s+V!-KI@&3a?VrC(bA`TcEI8Xy(;ZXkfp#WyUh zaI^6=;o@1t;TW8Rai3jOfQv{;OZVSR3&z{6wLBaL?8S02xu0uhPpbhR__P(Ub=nvf z2IcAP{byOJfcLDkgP=bPjpceqWJU7P5u$*u<>bZL*+d{$>9*Kr-mfH(h1>Zc@8udJ+a)XBpy0^9(AkgjU-Xn;fldF;P538b{fo}N6Q z*ObQ1Y1|(Sd3AJj1l)8hh4>Pf0QnrQ`sv7Y2E8#L8&~_Kr=$!5@4{xKjUVWCxKhUx z@D2lMDg{VPd@hFwpiEp`82~+*`1|+xPOi=ML^)qj0_Z$m@4W9uGis`;4zk-UNjZ-l z+ZZQ z(0n`lqsi1!q@Ya1#DN20h>fSqmTXDsFoDIA@ns<)qIDO5vPsD8T%sUL#mLwiJPZAo z-_XgDE$ipO!9iK?=R+NM-b~VN!}F=0-gGTf=KZ8y#6d_C^3fK|u*L8VKv3oCNlf#RQfg)#MZbMsA51Y)}UWhiv_vSIYFp%fBH!|RFfF;8qAc&cnegAwv65In8&iSGV0t}20 zfMxr*o4Mad?Ai&l30Q8cywx$8LPdRP( z1%VDU0|m_77aE0}kc|y(p3fzB4xd-U@|9(?_J3d~Q;Iq?G<1D?3w&v;Yrq6nTv}Q> zL$_uZU5W?tYiw-H`gD_7^V&^P5*iE)%-asUZ=A6g!N9=4)5nL5ni@7TG7_+F^(B3m zRn*pAwV5IzB?YVNe#CWlc1FR&ix!W@+{t$6X-6_l)oSrqi_Qmd?x;E(ndtJIo@7PG zc~0Hn=`jc#`nS;ll&h;NF$YJBBp!(UW>+MzF+){dos^Ca;qB>a@hsp27owN4W14-j-CxnfN(#OYi;UqTQgBOyKFa@yxKrl+UVF*AQF zEG*;#B123mRH9f|R~LVGZ;#pQ)-<9hVmzHuw0e=0n;Qqn`F%iHaRV&;-Sd@3ASZ?Z z3cJ@>T28M~zQ6oD$`s%7G&zD=XC7@>oBy;6TTXl6z;60$W8k@}KR4G+< z0@B#8s;b@o5a^dN+PWDaMO7$L#lZ((uX($*q}yRsD_1H5ac+Q$f$=a75V}>PpjB0x z|ESS_xg{e5`}DzkDw{LjxjhG9o4URJ{QP`;&m)4L^&9i^cO5TS^2{clQT_g!h3Ow< zfZ8Pwg8qkIQlEIm^6^9us2c;EoSlofg`C+(UjNXy8d!n^K0kYUd3rua0M%rCRu=9T zzzeooT3S%L_3PL(T0bx4$e+tvnsfoNm_a8g7mpqE}8@x({rf#8n*>#Yn47#`?46{fP=BAz;y0b-F z^gm6wmf)Z9!xcYcn_Dnjf{C9&>RWy*H+|#&>V|<8fxt@p$k@Pfw;<6R%TCkbL`c(f zMcrejPt9Az&4c|`_EVp2!xdg--bC6uE?x)Bx;wIp?vpc%HM$lS^oQp^Ixg`Y$esRX zW8s@x$3fjW)<5Nc_~UdHpY=~9G7Zp=e37aqB9i4|U?fAEbusYNY#F%It^*w{h8w;M zX3)4u+;kYz_F8|gt8_DUSx(E*>X}3D$uWuJBZjD@jjE8-RMSTRl+T3y{h~*Zfk9Mv zJYyHz3=)3hsrYl-qt(8pw=M@gPWU7FsM}3=fWz0$YxAh^$d5qy_#4A{R6r?&=v9$} zTGJG`$;D{XPWzJJ)U(rqOA65LgNtrE_0NL2>Y0^(b%6=Fq3E^ z4_2Hg)8gEg5YQm~kR_I~eQ~7DDQ{S(SQq!@jT(!@0Y%s!q-D+P+=rWISN^zqDok}M&_le|9j zZy}_KFtH;htM;uNXu0x~bZ8Z3Xk`Z&cnsN-QNsEZB3ZCGNNdX56M!~RuwgGbWUPeX zYl2om9g0MmCC7$adg6L&Q>0%vf8gx30AXF!^7tcw_?mV0!d=`*^tn@&Ci4bV*zRKV zR%qMISRnt*>>^8!qU9N+pyhG=wr|i1Y~J3_r5eydX!XA>xN{PM4-ESEKG7iom7rA@ z;DmZJG0A8vJ#YqeL>b&GaO<~#3*-8KI+-X?eCd5~=0(eAv&QuWE4C7o=E+FmA^M+H zymArW6YNDWXi}pV#CUSk;?jvZ3eT{igw2h+^;Ia66XQIH;|goOZGg++$4hpp z0$la_0DN31mC39uM^pW^HE>bvp{KySLyPnEb z%7r!|>E9C{dQOP+LVD;B-5!Ta^d;ErgT(nD&HZa#7mR-HDcc0|pY;(perJFVs5}1& z`Y$0Jj?t0kzgE}(gs+3IvzB1sgbL69>nRmTz@`87)!banoUL6LT-+^uJ1yb?(dzr7 zpZ`#?WFT=+R-s4Z-6iQsck4s!CVDiTH)cThjGo5`jJ95Z(=7R$Dg`UcZceh&*P~$V z^7XP3y$xsV*E8M+*8Wv*Rei>oz3u0X2e#DL#QVo`hnYzx;=Ja^-j&nqTfqBMz-#N* zMgG?dqkm;X4b2x%XU&H!LB365cXjXQwENoT7u>*+*Qe~$(QdDtEcll}z{j277jRX1 zfKL2jJ|Gth22i{{P5-QYAK5ya^$pY}Q`qa0ruC;3YdRi>5mbdTt zyy3jXx?S$wdOhnEaP1Cr`dGF(9zGKM{8S+0yV+!XB@>O@l1R=crVEKu5 z=*{-ktMCcj@~kd^w%YsSCHaajz+d$16aKS%@qOe0>cj7~uJ^OX$Lz;L_f4-SR=@}2 z*2r}4lXA_Xv#Oz=#?Yae4(A8mhUUi`T5s~lvU}xez`LHg&SPCK5p3_sVei3;w$k9& zhIr0JZUh4-&;rx+{}*Kh4ip@qG~2>(ASelAa8w{5%VQziMLCD0<|@T9l*0IAE*xT^fXPU%y(jN3f?j4kl|5n^v9Tk5qwD^b!^`VyngK89u|fvV z!(f;KX&7u_&7k{^7Vm_TyT9Jzvq=RX{na&j`d9?%LFF z@9w=_z_7hO9vf9;Y&N=$&)Bl2=W^N^rV)l{9AM^NiAq@Lq9( zK^JnB)RFedX!p_Z?lS|#*6$OdyhT1R_$ubB-GBBM7w;_&Z~A{2y^f$I($fS>5l_Kb=y-o7(C?TK&+=>0y3;a&V;sGM&dt8Fy)byH0 z!`~<|8V!WHZRJFc58nmyYal?bx?~!5sJGcsjUsWbAy4_5hciOKkNv@8A->?P+4Mi| zbk{UPNx_a@X8l1;R2N~VAQq@G4N)e7-n=;B+~oV^L>j@iDZ&ZQF2whqi``bY{ zUBc2ej>X8`N0s$iDGU|+HI)G+jR#1BQiIikK*uwp?HWjbKObqx_paHnQf`42m>RT{ zc4Z3o=rNQRW!JYy^2M}JBXR4RrzrbxGW5n)-(RmUsZwINFYx~5GLhwg&$a)Q-M^k9 zWuw+}<4Ps7(oX2cYG(jP_Qt6H@ltC$6Qu7Wl1eh^xk*Ct)Z`uIy8v_hd^n&1r`zgh zBXnSu0O_0k4R+XGH(Omsvhc-S{#f?k^#KZsx<|ichs~9-)})r=sft+|-)ja-@5~Tw z0O$?i^67eJX8k!AY(>I?aaF_Y7%kRQwsPKIzF3yNRO-;1()YNK66!2TRTga)9b5acYplApAJO3bR5a(d-pvn=} zA4gOv^6N86q<6BMZJ0ix5Ken~$H08RTXr88HHI9C@{aCK5NW=UM)5BQ7vGYWzfRu% zW15iC(2}e1gj<|CCo*f};#8sS$K$>j#GctVlAGdOlRN!uIB*Jcle-UsErcXc0i#O3 zrv8XiK(Ilz-0T8^T!9+l)1xZR`hLnpA(jk zGpWLp284K<9gFpiq9~`AG^)*xee}3+SM`e409~l5=(Rwj*khR-Q4{ey`7q-)F8kR% zZivSj7*c1FP?y}3F^8z&=!iE<^Tj-WvzP)bJ@WhcsawGCg^i zBz+mgv}4WYuZ#uz4$S6-SP$s^cQtP{+fR{pC6c(Ln0go} zezJMr!L!7)W+n)X$0ch!bLcs`2I-h(?SE`Jciq-dYru9qQDVzjB?VH$=M?xwrC-`U zd|J7BEC|^6@*O}W!sFFlj4<=WnPlnq7wba(zGh$3xBRud8rmDEa4lr`0XsIF(Xc#R zb3PtQ9ECY!n^;6Joqv-^r|In}tF~+wnRc=il|$5nc$RqbAtnf}u9~zw-sKMpZ2;ay zj>iEKb*jnxUUkYdHmmUyv-FH(Nspo-YD~#3r^1w5(;a?4>Y$~X^W!@>9EiwfSF0x<&?IW+_oYAG{}hGJ%Xo^aw%panwWE$})A-K!ep zUWKqwi6bA2?l#HQ*ySjk!Hk|u5YA(x1#r~$%FkwW2GbtF^nnP0C@_ugi-KSCsYG;ed1EvBV~KrS;g~aZ@UFF;V8{E|_E1+2hGeAWr%g9J zke#r$`UtV91=xL@U74@&e*&=M=6=D!P^X`~%;%e|>|R%~h%~StwRkFxzRf@r*KA`k zfvm5Xnyqv8mC~lZWsZv?pS;o>FC@zv6KxS~eII@ri#3jgs;tk-hw|*GGz~(~e(Wjg z?1B*aS~B~4&6?9g>m{Q*_Jdq|zby_LD_O}OCN0rV@SfXra-0|HO}y9v?vmbY}c&-ei$Pej0k`%>fv29#hn z)k2WxCNY_sGpNBO$`AQW<8gv%-WEEW6BQnlGsJkVPlzj@t}Q91;uVV87E;4fR5rM8 zo11uEuS8`1N^Dj4In;E~{Ml~xR|Y~G2OgRK(%v3W#qCkHIahBgjs#_G8 zwl$H3mzk=6ER%2TD&YuRDIVg0zWS-9t(#<`gM>SZp5FZUJ$)>YF{ad&VWYgEb;~<;oeG)KDxPbgaA^*RF}MTa1PA%9!SdNRc^M-q!{-`rZQ9SSadI zrED*fHg?py*7kz1_@oxs(t5fPctRGg4hVQVx*CY*x6rGE)u6GEMIB6BFXr$YwR`&V z_5vG_u>~)A)-{B}p~9xTz4fC}%UG)xHCTchWnlDK&n);6;JQa#;9~Qi9CCamd#3l- zCma@Oca!EMn^tzoU=Izn(-@SNWU}C&QzaA6y)#Pi`2;x-Ek3X1CGkgAw72t!6ksXD z&=X_)G6b97uo5cb#4Rl7o-_<>5ffYVpVZ8CVvMk%xMc$D1xckGAVhLPp_^N5MC)Ro z-7_@?B4YWWl4hrRaUO$al(?toL@QK^=F)lD8x*-1Ah=5Zra{_(ik2<;08>DY^IR|L%j6!{FeC?u# zt2lK-PMBxp;nNNHB`zJrTM#JslV9;O6b|qxlY2}(eXv6CY%WoRHX&qH&nQ{qc|>;BU79O zVGqxUD3B(En$`X&ZFP$~35;6jWj^E~Ms>Z{Q(=e2A||agKA}j*bLn}3j3G_d;|^I3aYFnz7>4O zCWOE}2~^q7L;m$iZLIWDf2;2?p+oY4L=*GWFCTYy&!^rc3xO+akV>F+-=aK*3zcFl z=2kSNQTPa4pLi_JP%CMQpXPehRa^%84e}TC6;g+k>EE#G2N^IqZmn&^WiFT0Mc#Wn z{R|dbJ+nC8s0JTk502L7+o&>j%9YlQ*4i?D&-aVCUe`F!yt->Nuxk{;l5>8t1FGA! zAk^H+5$B!|4Z5s0N&&AQ))~7`;Dpzq^s~7K`(GQLzQ=)IM+ki;U^(VGG$R#uE@zqVvQTf-`k8h8dhXGmU2WY9Pr&6f;;z1 zV_$*JDSX?ah(e1z>HUDZtT7sj#5|jq!9IQM=ITbSqBukHM@)*RoJPxw3cIjnn8+5X z_*kWfXo|Isb{>}|Yx^bjnHbCN(@4NJT$$i6ET0BUz1$ngRy8HQHZ&Yu6`u6p?7pXM zB=$Ti#JpDkAS&n*Mwn`PP5C1cZ`!drZfr4`4LQmN#0soB>8G;E{~uzL*!MZ6ip zp_BVr-3jT>xWci8LY091TyZwt<-|bjJM3s)ACX6zF~VZQtdRV}STuTU6<1lKyP~^!Be~lysdK zau6wb3{_Sd`lM^U86RU)XZY(4v+Y4AX^0?i&He9(_k zcG5aULuLPIfSzI(TC3WSajyLBNpj`fgiFFM5dl$6oS}XKWL#40j@lF7b#{GZPfNL&F{Me@EnP|V$Iz@6|p1R-L!8=_0ANW$zCYUJ_K+y<*wm`s1`#?t=ol8JujgZ&-*q*FQUm3zQy`Vb+5M1+Q{OHxI?K z1hF~fV)B;zQshCaI+!!^#Sh1ED8H}Vx_CQiUaB=t?Ktf zmn1BS-awv!+8Xums3zAI@FLQ#&9H5?yuPOJaA>jra{K3n8!z|s*dkb~S`i|rvLc^n6p?Ey}2MNwa zM{EU+OjcNK|4x}R`p&g)L}&mGhb)`GWbG2`w{A`h#ICv5*FzAZe!FvJqZNlqW`=jo zt_f!|+~JT#+WW1j{Qxx9u~2hMpH!LF2bsgSK~*Lg&C0Pso>$Molg1~QtRQ5}t2#X+ z55DCSXtw$Wnt+K~rZYrDoUHXT;hLmjzlHce(_jK?J%r~XrlXFjb#EWD0_N2cL$?wv zD$){JzHMNEai*EkdcIjJ;U)vy{-NorGvEc+x)<0#l~fgz|NhKG-p5kxC_wu&;8zUI zUn=Ibj6LffSB_j_u2$dLpqd_2-tx__g&mBKp|%Sta8yB8{!_%I-SjFEA{3tjU=R4Nxpo}G}3~#13Rp0IyG|f)aY?-O$ zHByf&l0h<*YM>!x95F!UQ6Cr-sXb9S{0qyIx<-?B;CbtpUJKlEjrDHBYjREIqD?`_ z>th!1Ueqn=*yiz9M#*HivgU<~%24(p=UQ_?X^jYo)@znoBZzKERV*0OPBM`Zm zDF+T$DlReQIH=vV0LnQOc+!HAA44ke2gxUaaw>1n3IDmA zJgBkD4K_9UAI*v+P?jQaL&)@x*V}>WLxI|mZwrKAJ)m}sSmezSiHd4U09Z+&XhR=LRiRaVz z%XX?wF#l5MZJ3uEqb<^chMG|(nVwbeLH$0y`sT8a-}GtRu7J#wGlI^M@q5m9Gm%Di zCEi9Xe$IWdCD;N(;=A;}vVtTgw>;b8GTBVTRt&msDJ|6b#IR0GpWL9ml-*4up^~oB zR8@X!0yJi=(GRC4M&y~=AeA#eI+aw5>%1sc*)~xpf8irleGPWmA5R63Q&{e7XY{I0oQaWs$ovjxnyM??6jOX>#u+T1p&^SUbwj-FjhX+6JbzIF z62yT(F_%U;jLs2O{&O^*rHx0`p*PI5qgxjC({f?9m|=q1>#awfnfFAfC}1^FL2;I`)a;}d{$}ERPBH)T|%Vl7HTAnF$9(9~X<9_h&E?2#k2?24e5lh4-iJ^ryCbsg{^TH-Dk?S!I{) zAivCn9F0U_Ra(`Z__hg({XIsJw`VUn`xqP?0aamT^GYK^T4md1dn-vFXX{bBGEMS~ zY=IePZ3u+p7t##RhlubKxDX37kXFwn5fseH3yerDI2kXMjer@Y!3lNtM<#0V=j>0( zjCc5#VhV%V3N5Lp!E?LxF?yv@sWtzQoW6x33OXO?2GhVME83b(cNtnFuCP4fMQ|WU|HFU!36Q!%RqU1D{MPGlS&)^vHMA!Kd z(r*?fE7&qENGOh~Xia$96j6wf=*bRdJR`#gZ|XdMBK{S62hDc1Yw&#Oo!K z?N*?XH^L7jGg921B5|^m<99fi^XY3`vb8%?dki+?98j?>=k*qyv}RRV0v(CTAo)@x z`TzDhHF!T_C=Rq8R`|EvyH3Wd<6?vv8`aD zXtTtB32d=^t)G&2$hYZVo__v{o*JzGM$l`Yhh^=1clxz(!0FHO8^_W?w$ZdrMoi&$ zu8==cuG%PL_y(c-7Y@3&ZY%gvTYwr>gk+37gx(B2*51Yn@Rqc9~1;(e>Be?*H8h`4(3&(TZpjk*jl=E{fG z;eMnHm}aWzR)m+-W)}Z;Y;;Gy8**u487+;)(kxRc*f=5cBuhzky^lY>*?r=h<}?}d z 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", - "version": "5.0.2", + "version": "6.0.0", "license": "MIT", "homepage": "https://github.com/magicoflolis/Userscript-Plus", "bugs": { diff --git a/src/_locales/en_GB/messages.json b/src/_locales/en_GB/messages.json index 9ac0ef7..470b48c 100644 --- a/src/_locales/en_GB/messages.json +++ b/src/_locales/en_GB/messages.json @@ -42,7 +42,7 @@ "message": "Search" }, "search_placeholder": { - "message": "Search scripts" + "message": "Search for userscripts" }, "install": { "message": "Install" @@ -66,7 +66,7 @@ "message": "Good" }, "ok": { - "message": "Ok" + "message": "Okay" }, "bad": { "message": "Bad" @@ -93,7 +93,7 @@ "message": "Preview Code" }, "saveFile": { - "message": "Save File" + "message": "Download" }, "newTab": { "message": "New Tab" @@ -141,7 +141,7 @@ "message": "Close Userscript+" }, "userjs_sync": { - "message": "Sync with UserScript Manager" + "message": "Sync" }, "userjs_autoinject": { "message": "Inject on load" diff --git a/src/_locales/zh/messages.json b/src/_locales/zh/messages.json index 6304bae..ba2ca67 100644 --- a/src/_locales/zh/messages.json +++ b/src/_locales/zh/messages.json @@ -4,7 +4,7 @@ "description": "Must not exceed 45 characters" }, "extDesc": { - "message": "The power of Greasy Fork on the go! Finds available UserJS for the current webpage.", + "message": "为当前网页查找可用的 UserJS,随时随地发挥 Greasy Fork 的威力!", "description": "Must not exceed 132 characters" }, "extShortDesc": { diff --git a/src/html/background.html b/src/html/background.html deleted file mode 100644 index b268206..0000000 --- a/src/html/background.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - Magic UserJS+ Background Page - - - - - - - diff --git a/src/html/form.html b/src/html/form.html deleted file mode 100644 index 4d9e1b8..0000000 --- a/src/html/form.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - Reset - Save - diff --git a/src/html/popup.html b/src/html/popup.html index 111813b..2357f06 100644 --- a/src/html/popup.html +++ b/src/html/popup.html @@ -2,56 +2,17 @@ - - - + + - + - - - - + - - - - - + >
-

+ - - - diff --git a/src/html/settings.html b/src/html/settings.html deleted file mode 100644 index 335a789..0000000 --- a/src/html/settings.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - UserJS - Settings - - - - -

Settings

- - -
- -
-
-
- - - - - - diff --git a/src/img/icon_16.png b/src/img/icon_16.png index 03a9c49aece0c9849f911d1166897fc2546cdb12..950710b607a93809021bf747dc5ea319b521b729 100644 GIT binary patch delta 707 zcmV;!0zCcB2HFLXBYyw^b5ch_0Itp)=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGq zB>(^xB>_oNB=7(L0&ht~K~y+TbyG`AqG1&N67hzHhFw&c)O1mHB`;BumWi39V2WYIJny-E(tqIacsv(@ zK;SJNk9VC;XLn*^;x&`Wl*OIBNBIKF%ga}xPzV-_1?%hU2nK`L+}uPim&4iF8HR?2 zAZR~&>`$1VpZ_U7Xti3f*=$7o$4n-ZynYh)2h-EjSN;9{Xf~TnczAe#-|t5_9A>AH zkr8;kUMLg_xPM$OjE#*^G?zVZNpc<@9^&Ta20ERNMf&>s@c#aeL?VG?G6_)&tgWqa zIx8zHSY2Jk-rgSEZa3HDVt9BMKA(?8tX3;z+~42x-r;b-Y&L^<^rfii%xE+gN#IQw zhaQba`DGdPdY#V)2M6Wc*$f5)78e(3{UV95x;r~Ne1Ab9(z@Ml6M(xlu9KRP~MX@8VweyR;wS*f7`PpDq1FG%3rh-#bOb5yB*ip*El#h zz|_6m5R^gNRE$>seo1X{0mQ1D79J*jYdN~W+xFQ@5QKN zZf=fK+}_^)ILb1_bY152dF=1+CdfGCWFUcXyYkP|&{j*k5B*%z8;Uy@(e( p;>YTU|KeGUH5Kezk0L{oegTg&YWtBPfJ6WQ002ovPDHLkV1i1zNK*g+ delta 824 zcmV-81IPT@1EX>4Tx04UFukvT{MK^TRzWh%jx$2!H6NTb!I8O;LAz-Vspi zZB%9PztNh`xF!TN;ka3JO2SLRgKMRt;$7j0xvZy!&xHFNxuEca(v32|D$e;FRGASc zl^hn12y3|-Hfq>hb}Zom;qJ6$OMY;+%xT5zimm*rS-GcrVK`&YOe?i8@JAMC@xD0WvV2Wde0v5XONBzO?ZryButeg~1K;yILz4t)V zHhgb+-q(@meIG;U2`=rbziy{D4^000McNliru=mQK7G7dT+ z$ZP-r0ZvIoK~y+Tm6NfGgFq05#qQdG5Q7K?grG$rR^lrOzJ^WOKsuWg_F4*;%3cUu z6G;Mjh<|H#ZvQ#ssWFoK;RBtW`PrG>RYtUy>?B{3?*@D$hP9XaknDZm7n-J#{2oI{ z_7ddwguthSHk%C{k4Ks?0m$u{>{V5zEX!yPx#1ZP1_K>z@;j|==^1poj532;bRa{vGq zB>(^xB>_oNB=7(L1)xbpK~z{rtyk$wmRS^kT}sr-U9*gIOiiscBF&P*!gbscj3Tix z2^Z8N6|KldEy@M=9W^vj6cPNGAA$)A`U8e>>&rj`;+HYzWq%gVoZsoWPp_}9j%Ejb z-20rno#))MUBeE@hLO(bc6WDwf8xZ6PtMNH#(n$t8EtKCKkePS_noV&YZs5FF{~Ni zjXVPb0|&~>%m3v*0n^jd6cG_Y6B84Znwm->At4kN7DlnLvDDVqMky&N|M0v%h6iI; z)adBwNDm)Aq<_-VQaK!GXlRhOv9Xa76B8*YD2Ps;JV}=?UzRcO)m+9i#*WF8u{1n9 zOr4#brke?r0BHB`-%n#>W7N^nLDA9C^!)jAdhz0gj8|4xsx=D?cgD8p2gYXxxwyE{ z%E}7$_xG!fwhbR2A3A>gxG8Uq;mg>PaA$vxkB`&Qqkl(b;ckSm0Q{IMV^dmWP;qfF z8I49da^#3CG#3I!hc+)SPi?#5zA3xIT*RS=3N(diqGbbk}T3ubG z-ripMZhvlWrl_bW%F4>3GiT1w_3PJZc6L_AdU|^Fed_A!XmoVcobSTWX`r>Wm27Nm zXnA?rvJh-knVFfSsIRY2{sxCfMn;mGn;Vstl~GeuldMxMP+MCo!lDlsg*G^lb@R7Q z`hD8j*=-P_u&|KU*4DJ6zfydByo_UW{DA2`rhoQvf)dw{WOytjtz?CjqY5)$a<&6~stM|U4(t;dcX6HRPJN{IaY ze1Ekmd3box;lqao2M-?9`3UW3hlYlTGbpb1H~uylM@B~U_^vQGIJmBbB8 z^YioC@m~l+KwD}pToWDwK$D7(gVCxz`I-?K4aUjINvf}}*CzsSGqeaY>Mvo**4EbK z@9$3w3k%xuU&!=2a&mI0qM||o4^sSBuYX=ii!_e*(4j-0aRr~CrVAG?=o0}f^z`(U zzPhuxxH$23%tg%DN(f8ff<-imJcB(rhR7AXGo54#EU?5^fT!$K2nFrRer6at71I(B z;VkhLb|VC%jbTWK5t=Y{z*4KKs`NVp1_lP`?%li6zjyDRv{qJD-zr2hLx}F*zkg2; z9z2l4aKOyWjHn5&`SRsUN>5K0z!ToQc|+H(U8A|VIWai!HnRyfGi5*7?uJ6os^hr_~=GQGUKB*}z_hl>F4UweCdL3elex|$Fz3Q@Gs#Ny(jcKjED zhvAywf?Zu*GVkiutFSLbV4YlRYJY0vFOcWq6_|uPjw?XT$8!X@0wkaF=g*4(@OcOb ze^{&5LKR-WlEw~xfkHfB9xgrJ(cf*=Tj~>b4 z8c+#uS&myIeiPQg8&D5I3v(z&@n$F}C=hE_FCcgW1VSJ8oRN_s?uu{5rUtiN!jq~e zIXU@nTnAEVb#=9r-*|@cn6!u;$aWAWG&J-t4r1_g*wl9;D+WR*%BZ&tWHJ~mfIbon gV*8JbZIZ$8AIz+%9Clj0Qvd(}07*qoM6N<$f_S6RnE(I) delta 1124 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 JRHa}U^* \ No newline at end of file diff --git a/src/js/background.js b/src/js/background.js index e8c2464..8ca0098 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -1,133 +1,312 @@ 'use strict'; + +import { webext, runtime } from './ext.js'; +import { hermes } from './messager.js'; import { log, err, info } from './logger.js'; -import { i18n$ } from './i18n.js'; -// import Config from './config.js'; import Network from './network.js'; -import { reqCode } from './request-code.js'; -import { language } from './language.js'; -import { isBlank, isNull, isEmpty, normalizeTarget, template } from './util.js'; -import { XMap } from './XMap.js'; -import storage, { storageByPrefix } from './storage.js'; - -const MUJS = { - cache: new XMap() -}; - -window.MUJS = MUJS; -window.Config = storage; -window.storageByPrefix = storageByPrefix; +import { isBlank, isNull, isEmpty, union, loadFilters, isRegExp, isObj, formatURL } from './util.js'; +import { BLANK_PAGE, template, builtinList } from './constants.js'; +import storage, { DEFAULT_CONFIG } from './storage.js'; +import { BaseContainer, BaseList } from './container.js'; /** * @type { import("../typings/types").config } */ -const cfg = {}; -/** - * @type { import("../typings/types").config } - */ -const DEFAULT_CONFIG = { - // cache: true, - codePreview: false, - // autoexpand: false, - filterlang: false, - sleazyredirect: false, - // time: 10000, - blacklist: [ - { - enabled: true, - regex: true, - flags: '', - name: 'Blacklist 1', - url: '(gov|cart|checkout|login|join|signin|signup|sign-up|password|reset|password_reset)' - }, - { - enabled: true, - regex: true, - flags: '', - name: 'Blacklist 2', - url: '(pay|bank|money|localhost|authorize|checkout|bill|wallet|router)' - }, - { - enabled: true, - regex: false, - flags: '', - name: 'Blacklist 3', - url: 'https://home.bluesnap.com' - }, - { - enabled: true, - regex: false, - flags: '', - name: 'Blacklist 4', - url: ['zalo.me', 'skrill.com'] - } - ], - engines: [ - { - enabled: true, - name: 'greasyfork', - url: 'https://greasyfork.org' - }, - { - enabled: false, - name: 'sleazyfork', - url: 'https://sleazyfork.org' - }, - { - enabled: false, - name: 'openuserjs', - url: 'https://openuserjs.org/?q=' - }, - { - enabled: false, - name: 'github', - url: 'https://api.github.com/search/code?q=', - token: '' - } - ], - theme: { - 'even-row': '', - 'odd-row': '', - 'even-err': '', - 'odd-err': '', - 'background-color': '', - 'gf-color': '', - 'sf-color': '', - 'border-b-color': '', - 'gf-btn-color': '', - 'sf-btn-color': '', - 'sf-txt-color': '', - 'txt-color': '', - 'chck-color': '', - 'chck-gf': '', - 'chck-git': '', - 'chck-open': '', - placeholder: '', - 'position-top': '', - 'position-bottom': '', - 'position-left': '', - 'position-right': '', - 'font-family': '' - }, - recommend: { - author: true, - others: true - } -}; - +let cfg = {}; const initCfg = async () => { const c = await storage.config.getMulti(); if (!c) { await storage.config.set(DEFAULT_CONFIG); } - Object.assign(cfg, c); + cfg = { + ...DEFAULT_CONFIG, + ...c + }; return cfg; }; initCfg(); -const { hermes } = userjs; +class Container extends BaseContainer { + constructor(url) { + super(url); + } + + checkBlacklist(str) { + str = str || this.host; + let blacklisted = false; + if (/accounts*\.google\./.test(str)) { + blacklisted = true; + } + const blacklist = cfg.blacklist ?? []; + for (const b of blacklist) { + if (typeof b === 'string') { + if (b.startsWith('userjs-')) { + const r = /userjs-(\w+)/.exec(b)[1]; + const biList = builtinList[r]; + if (isRegExp(biList)) { + if (!biList.test(str)) continue; + blacklisted = true; + } else if (isObj(biList) && biList.host === this.host) { + blacklisted = true; + } + } + } else if (isObj(b)) { + if (!b.enabled) { + continue; + } + if (b.regex === true) { + const reg = new RegExp(b.url, b.flags); + if (!reg.test(str)) continue; + blacklisted = true; + } + if (Array.isArray(b.url)) { + for (const c of b.url) { + if (!str.includes(c)) continue; + blacklisted = true; + } + } + if (!str.includes(b.url)) continue; + blacklisted = true; + } + } + this.isBlacklisted = blacklisted; + return this.isBlacklisted; + } +} +const container = new Container(); +// #region List +class List extends BaseList { + constructor(hostname = undefined, tabId = -2) { + super(hostname, container, cfg); + this.build = this.build.bind(this); + if (isEmpty(hostname)) hostname = BLANK_PAGE; + this.engines = cfg.engines; + this.host = hostname; + this.tabId = tabId; + } + + // #region Builder + async build() { + await initCfg(); + this.engines = cfg.engines; + const { container, blacklisted, engines, host, tabId } = this; + if (blacklisted || isEmpty(engines) || host === BLANK_PAGE) { + return []; + } + const records = []; + const fetchRecords = []; + const bsFilter = loadFilters(cfg); + const hostCache = Array.from(this); + info('Building list', { hostCache, engines, container, list: this }); + try { + const g = this.groupBy(); + if (isEmpty(g)) { + const toFetch = engines.filter((engine) => !g[engine.name]); + for (const engine of toFetch) { + info(`Fetching from "${engine.name}" for "${host}"`); + const respError = (error) => { + if (!error.cause) error.cause = engine.name; + if (error.message.startsWith('429')) { + err(`Engine: "${engine.name}" Too many requests...`); + return; + } + err(`Engine: "${engine.name}"`, error.message); + }; + const _mujs = (d) => { + const obj = { + ...template, + ...d, + _mujs: { + root: {}, + info: { + tabId, + engine, + host + }, + code: { + meta: {} + } + } + }; + // obj._mujs.code.request = (translate = false, code_url) => { + // requestUserJS.call(obj._mujs.code, translate, code_url ?? obj.code_url, obj); + // }; + return obj; + }; + /** + * Prior to UserScript v7.0.0 + * @template {string} F + * @param {F} fallback + * @returns {F} + */ + const toQuery = (fallback) => { + if (engine.query) { + return decodeURIComponent(engine.query).replace(/\{host\}/g, host); + } + return fallback; + }; + /** + * @param { import("../typings/types.d.ts").GSFork } dataQ + */ + const forkFN = async (dataQ) => { + if (!dataQ) { + err('Invalid data received from the server, check internet connection'); + return; + } + /** + * @type { import("../typings/types.d.ts").GSForkQuery[] } + */ + const dq = Array.isArray(dataQ) ? dataQ : Array.isArray(dataQ.query) ? dataQ.query : []; + const dataA = dq + .filter(Boolean) + .filter((d) => !d.deleted) + .filter(bsFilter.match); + if (isBlank(dataA)) { + // records.push(_mujs({})); + return; + } + const data = dataA.map(_mujs); + const otherLng = []; + /** + * @param {import("../typings/types.d.ts").GSForkQuery} d + * @returns {boolean} + */ + const inUserLanguage = (d) => { + if (userjs.pool.has(d.locale.split('-')[0] ?? d.locale)) { + return true; + } + otherLng.push(d); + return false; + }; + const filterLang = data.filter((d) => { + if (cfg.filterlang && !inUserLanguage(d)) { + return false; + } + return true; + }); + let finalList = filterLang; + const hds = []; + for (const ujs of otherLng) { + const c = await ujs._mujs.code.request(true); + if (c.translated) { + hds.push(ujs); + } + } + finalList = union(hds, filterLang); + + for (const ujs of finalList) { + // if (!ujs._mujs.code.data_code_block && (cfg.preview.code || cfg.preview.metadata)) { + // ujs._mujs.code.request().then(() => { + // dispatch(ujs); + // }); + // } + if (!container.userjsCache.has(ujs.id)) container.userjsCache.set(ujs.id, ujs); + } + records.push(...finalList); + }; + const gitFN = async (data) => { + try { + if (isBlank(data.items)) { + err('Invalid data received from the server, TODO fix this'); + return; + } + for (const r of data.items) { + const ujs = _mujs({ + id: r.repository.id ?? r.id ?? 0, + name: r.repository.name ?? r.name, + description: isEmpty(r.repository.description) + ? 'N/A' + : r.repository.description, + url: r.repository.html_url, + code_url: r.html_url.replace(/\/blob\//g, '/raw/'), + page_url: `${r.repository.url}/contents/README.md`, + users: [ + { + name: r.repository.owner.login, + url: r.repository.owner.html_url + } + ] + }); + Network.req(r.repository.url, 'GET', 'json', { + headers: { + Accept: 'application/vnd.github+json', + Authorization: `Bearer ${engine.token}`, + 'X-GitHub-Api-Version': '2022-11-28' + } + }).then((repository) => { + ujs.code_updated_at = r.commit || repository.updated_at || Date.now(); + ujs.created_at = repository.created_at; + ujs.daily_installs = repository.watchers_count ?? 0; + ujs.good_ratings = repository.stargazers_count ?? 0; + if (repository.license?.name) ujs.license = repository.license.name; + // dispatch(ujs); + }); + // if (!ujs._mujs.code.data_code_block && (cfg.preview.code || cfg.preview.metadata)) { + // ujs._mujs.code.request().then(() => { + // dispatch(ujs); + // }); + // } + if (!container.userjsCache.has(ujs.id)) container.userjsCache.set(ujs.id, ujs); + records.push(ujs); + } + } catch (ex) { + err(ex); + } + }; + let netFN; + if (/github/gi.test(engine.name)) { + if (isEmpty(engine.token)) { + err(`"${engine.name}" requires a token to use`); + continue; + } + netFN = Network.req( + toQuery( + `${engine.url}"// ==UserScript=="+${host}+ "// ==/UserScript=="+in:file+language:js&per_page=30` + ), + 'GET', + 'json', + { + headers: { + Accept: 'application/vnd.github+json', + Authorization: `Bearer ${engine.token}`, + 'X-GitHub-Api-Version': '2022-11-28' + } + } + ) + .then(gitFN) + .then(() => { + Network.req('https://api.github.com/rate_limit', 'GET', 'json', { + headers: { + Accept: 'application/vnd.github+json', + Authorization: `Bearer ${engine.token}`, + 'X-GitHub-Api-Version': '2022-11-28' + } + }).catch(respError); + }); + } else { + netFN = Network.req( + toQuery(`${engine.url}/scripts/by-site/${host}.json?language=all`) + ).then(forkFN); + } + if (netFN) { + fetchRecords.push(netFN.catch(respError)); + } + } + } + if (!isBlank(fetchRecords)) { + await Promise.allSettled(fetchRecords); + } + } catch (ex) { + err(ex); + } + return Array.from(this); + } + // #endregion +} +// #endregion const msgCache = {}; -webext.runtime.onConnect.addListener((p) => { +runtime.onConnect.addListener((p) => { hermes.port = p; /** * Default post message to send to all connected scripts @@ -138,532 +317,148 @@ webext.runtime.onConnect.addListener((p) => { log('Background Script: received message from content script', root); const r = root.msg; if (root.channel === 'Save') { - const v = isNull(r.value) ? cfg[r.prop] : r.value; - storage.config.setOne(r.prop, v); - } - if (root.channel === 'Reset') { + if (r.cfg) { + storage.config.set(r.cfg).then(initCfg); + } else { + const v = isNull(r.value) ? cfg[r.prop] : r.value; + storage.config.setOne(r.prop, v).then(initCfg); + } + } else if (root.channel === 'Reset') { storage.config.set(DEFAULT_CONFIG); + } else if (root.channel === 'Clear') { + const cache = Array.from(container).filter(({ _mujs }) => _mujs.info.host === r.host); + for (const ujs of cache) container.userjsCache.delete(ujs.id); + } else if (root.channel === 'Engine' && cfg.engines) { + const engine = cfg.engines.find((engine) => engine.name === r.engine.name); + for (const [k, v] of Object.entries(r.engine)) { + engine[k] = v; + } + storage.config.set(cfg).then(initCfg); } }); }); -// Unsupport webpages for each engine -const unsupported = { - greasyfork: ['pornhub.com'], - sleazyfork: ['pornhub.com'], - openuserjs: [], - github: [] -}; - -const formatURL = (txt) => - txt - .split('.') - .splice(-2) - .join('.') - .replace(/\/|https:/g, ''); - +const MUList = new List(); /** * @param {chrome.tabs.Tab} tab - * @returns {string} */ -const getTabUrl = (tab) => tab.pendingUrl || tab.url || ''; -// const queryOptions = { active: true, lastFocusedWindow: true }; -const queryOptions = { active: true, currentWindow: true }; - -// class Website { -// constructor(e) { -// this.engine = e.engine ?? {}; -// this.data = e.data ?? []; -// this.host = e.host ?? 'about:blank'; -// this.link = e.link ?? 'about:blank'; -// } - -// setData(v) { -// this.data = v ?? []; -// } -// } - -// class Engine { -// constructor(host, engine) { -// this.host = host ?? 'about:blank'; -// this.engine = engine ?? {}; -// this.data = []; -// } - -// setEngine(engine) { -// this.engine = engine; -// return this; -// } - -// setHost(host) { -// if (host !== this.host) { -// this.host = host; -// } -// return this; -// } - -// async getData() { -// if (isEmpty(this.host) || this.host === 'about:blank') { -// return [] -// } -// const engine = this.engine; -// /** -// * @param { import("../typings/types").GSFork } dataQ -// */ -// const forkFN = async (dataQ) => { -// if (!dataQ) { -// err('Invalid data received from the server, check internet connection'); -// return []; -// } -// /** -// * @type { import("../typings/types").GSForkQuery[] } -// */ -// const dq = Array.isArray(dataQ) ? dataQ : Array.isArray(dataQ.query) ? dataQ.query : []; -// const data = dq.filter((d) => !d.deleted); -// if (isBlank(data)) { -// return []; -// } -// const hideData = []; -// const inUserLanguage = (d) => { -// const dlocal = d.locale.split('-')[0] ?? d.locale; -// if (language.cache.includes(dlocal)) { -// return true; -// } -// hideData.push(d); -// return false; -// }; -// const filterLang = data.filter((d) => { -// if (cfg.filterlang && !inUserLanguage(d)) { -// return false; -// } -// return true; -// }); - -// let finalList = filterLang; -// const hds = []; -// for (const ujs of hideData) { -// await reqCode(ujs, true); -// if (ujs.translated) { -// hds.push(ujs); -// } -// } -// finalList = [...new Set([...hds, ...filterLang])]; - -// this.data.push(...finalList); -// return finalList; -// }; -// const gitFN = async (data) => { -// const records = []; -// try { -// if (isBlank(data.items)) { -// err('Invalid data received from the server, TODO fix this'); -// return; -// } -// for (const r of data.items) { -// const ujs = template.merge({ -// name: r.name, -// description: isEmpty(r.repository.description) -// ? i18n$('no_license') -// : r.repository.description, -// url: r.html_url, -// code_url: r.html_url.replace(/\/blob\//g, '/raw/'), -// code_updated_at: r.commit || Date.now(), -// total_installs: r.score, -// users: [ -// { -// name: r.repository.owner.login, -// url: r.repository.owner.html_url -// } -// ] -// }); -// if (cfg.codePreview && !ujs.code_data) { -// await reqCode(ujs); -// } -// records.push(ujs); -// } -// this.data.push(...records); -// } catch (ex) { -// err(ex); -// } -// return records; -// }; -// if (engine.name.includes('fork')) { -// await Network.req(`${engine.url}/scripts/by-site/${this.host}.json?language=all`) -// .then(forkFN) -// .catch(err); -// } else if (/github/gi.test(engine.name)) { -// if (isEmpty(engine.token)) { -// err(`"${engine.name}" requires a token to use`); -// return; -// } -// await Network.req( -// `${engine.url}"// ==UserScript=="+${this.host}+ "// ==/UserScript=="+in:file+language:js&per_page=30`, -// 'GET', -// 'json', -// { -// headers: { -// Accept: 'application/vnd.github+json', -// Authorization: `Bearer ${engine.token}`, -// 'X-GitHub-Api-Version': '2022-11-28' -// } -// } -// ) -// .then(gitFN) -// .catch(err); -// } -// return this.data; -// } -// } -// const eng = new Engine(); - -// const cac = new Map(); - -const webFetcher = async (loc, tabId = -2, link) => { - if (isBlank(loc)) { - return []; +const setCount = (tab, tabId) => { + let url; + try { + url = new URL(tab.url); + } catch (ex) { + err(ex); } - const host = formatURL(loc); - - let isBlacklisted = false; - for (const b of cfg.blacklist.filter((b) => b.enabled)) { - if (b.regex === true) { - const reg = new RegExp(b.url, b.flags); - if (!reg.test(host)) continue; - isBlacklisted = true; - } - if (Array.isArray(b.url)) { - for (const c of b.url) { - if (!host.includes(c)) continue; - isBlacklisted = true; - } - } - if (!host.includes(b.url)) continue; - isBlacklisted = true; - } - - // log('Blacklisted:', isBlacklisted, host); - if (isBlacklisted) { - return []; - } - - if (!MUJS.cache.has(host)) { - const engineTemplate = {}; - for (const engine of cfg.engines) { - engineTemplate[engine.name] = []; - } - MUJS.cache.set(host, engineTemplate); - } - - const isSupported = (name) => { - for (const [k, v] of Object.entries(unsupported)) { - if (k !== name) { - continue; - } - if (v.includes(host)) { - return false; - } - } - return true; - }; - const engines = cfg.engines.filter((e) => e.enabled && isSupported(e.name)); - if (isEmpty(engines)) { - return []; - } - const cache = MUJS.cache.get(host); - const sites = []; - - info('Building list', { cfg, cache, engines, allCache: MUJS.cache, sites }); - - - // for (const engine of engines) { - // if (!isEmpty(cache[`${engine.name}`])) { - // sites.push({ - // engine, - // data: normalizeTarget(cache[`${engine.name}`]), - // host, - // link - // // tab - // }); - // continue; - // } - // eng.setHost(host).setEngine(engine); - // await eng.getData(); - // } - // log(eng.data); - - for (const engine of engines) { - if (!isEmpty(cache[`${engine.name}`])) { - sites.push({ - engine, - data: normalizeTarget(cache[`${engine.name}`]), - host, - link - // tab - }); - continue; - } - const engineArr = cache[engine.name]; - /** - * @param { import("../typings/types").GSFork } dataQ - */ - const forkFN = async (dataQ) => { - if (!dataQ) { - err('Invalid data received from the server, check internet connection'); - return []; - } - /** - * @type { import("../typings/types").GSForkQuery[] } - */ - const dq = Array.isArray(dataQ) ? dataQ : Array.isArray(dataQ.query) ? dataQ.query : []; - const data = dq.filter((d) => !d.deleted); - if (isBlank(data)) { - return []; - } - const hideData = []; - const inUserLanguage = (d) => { - const dlocal = d.locale.split('-')[0] ?? d.locale; - if (language.cache.includes(dlocal)) { - return true; - } - hideData.push(d); - return false; - }; - const filterLang = data.filter((d) => { - if (cfg.filterlang && !inUserLanguage(d)) { - return false; - } - return true; - }); - - let finalList = filterLang; - const hds = []; - for (const ujs of hideData) { - await reqCode(ujs, true); - if (ujs.translated) { - hds.push(ujs); - } - } - finalList = [...new Set([...hds, ...filterLang])]; - - // for (const ujs of finalList) { - // if (!cac.has(ujs.id)) { - // cac.set(ujs.id, { - // ...ujs, - // mujs: { - // engine, - // host, - // timestamp: Date.now(), - // } - // }) - // } - // } - - engineArr.push(...finalList); - return finalList; - }; - const gitFN = async (data) => { - const records = []; - try { - if (isBlank(data.items)) { - err('Invalid data received from the server, TODO fix this'); - return; - } - for (const r of data.items) { - const ujs = template.merge({ - name: r.name, - description: isEmpty(r.repository.description) - ? i18n$('no_license') - : r.repository.description, - url: r.html_url, - code_url: r.html_url.replace(/\/blob\//g, '/raw/'), - code_updated_at: r.commit || Date.now(), - total_installs: r.score, - users: [ - { - name: r.repository.owner.login, - url: r.repository.owner.html_url - } - ] - }); - if (cfg.codePreview && !ujs.code_data) { - await reqCode(ujs); - } - // createjs(ujs, engine.name); - records.push(ujs); - } - engineArr.push(...records); - } catch (ex) { - err(ex); - } - return records; - }; - if (engine.name.includes('fork')) { - const data = await Network.req(`${engine.url}/scripts/by-site/${host}.json?language=all`) - .then(forkFN) - .catch(err); - sites.push({ - engine, - data, - host, - link - // tab - }); - } else if (/github/gi.test(engine.name)) { - if (isEmpty(engine.token)) { - err(`"${engine.name}" requires a token to use`); - continue; - } - const data = await Network.req( - `${engine.url}"// ==UserScript=="+${host}+ "// ==/UserScript=="+in:file+language:js&per_page=30`, - 'GET', - 'json', - { - headers: { - Accept: 'application/vnd.github+json', - Authorization: `Bearer ${engine.token}`, - 'X-GitHub-Api-Version': '2022-11-28' - } - } - ) - .then(gitFN) - .catch(err); - sites.push({ - engine, - data, - host, - link - // tab + if (url !== undefined) { + if (!Object.is(url.origin, 'null')) { + MUList.host = formatURL(url.host); + MUList.tabId = tabId ?? tab.id ?? -2; + webext.action.setBadgeText({ + text: `${Array.from(MUList).length ?? 0}` }); + return; } } - if (tabId > -1) { - webext.tabs.get(tabId, updateCount); - } - // log(cac); - return sites; + webext.action.setBadgeText({ + text: '0' + }); }; let requestId = -2; -// let isRedirect = false; webext.webRequest.onHeadersReceived.addListener( (e) => { if (Object.is(e.type, 'main_frame')) { - // log(e, isRedirect); - if (requestId !== e.requestId) { + if (cfg.autofetch && requestId !== e.requestId) { requestId = e.requestId; const loc = new URL(e.url); - webFetcher(loc.host, e.tabId, e.url); + MUList.host = formatURL(loc.host); + MUList.tabId = e.tabId ?? -2; + MUList.build().then(() => { + setCount(e, e.tabId) + }); } } }, { - urls: [ - // 'http://*/*', - 'https://*/*' - ] + urls: ['https://*/*'] } ); -// webext.webRequest.onBeforeRedirect.addListener( -// (e) => { -// if (Object.is(e.type, 'main_frame')) { -// log(e); -// if (requestId === e.requestId) { -// isRedirect = true; -// requestId = -2; -// } -// // if (requestId !== e.requestId) { -// // log(e); -// // requestId = e.requestId; -// // const loc = new URL(e.url); -// // webFetcher(loc.host, e.tabId); -// // } -// } -// }, -// { -// urls: [ -// // 'http://*/*', -// 'https://*/*' -// ] -// } -// ); /** * [onMessage description] - * @param {*} message - The message itself. This is a JSON-ifiable object. + * @param {object} message - The message itself. This is a JSON-ifiable object. * @param {chrome.runtime.MessageSender} sender * @param {(response: any) => void} sendResponse - A function to call, at most once, to send a response to the message. The function takes a single argument, which may be any JSON-ifiable object. This argument is passed back to the message sender. */ function onMessage(message, sender, sendResponse) { if (sender.url.includes('popup.html')) { - if (message.location) { - webFetcher(message.location).then((data) => sendResponse(data)); - } else { - webext.tabs.query(queryOptions, (tabs) => { - const tab = tabs[0]; - const loc = new URL(getTabUrl(tab)); - webFetcher(loc.host, tab.id, getTabUrl(tab)).then((data) => sendResponse(data)); - }); - } - } - - if (message.name) { - if (sender.url.includes('settings.html')) { - storage.config.setOne(message.name, message.value); - sendResponse({ - name: message.name, - value: message.value + if (message.type === 'getData') { + if (MUList.host !== message.hostname) { + MUList.host = message.hostname ?? BLANK_PAGE; + MUList.tabId = message.currentTab?.id ?? -2; + }; + MUList.build().then((data) => { + if (message.init) { + sendResponse({ cfg, data }) + } else { + sendResponse({ data }) + } }); + } else if (message.type === 'save') { + if (message.cfg) { + storage.config.set(message.cfg).then(initCfg); + } else { + const v = isNull(message.value) ? cfg[message.prop] : message.value; + storage.config.setOne(message.prop, v).then(initCfg); + } + } else if (message.type === 'reset') { + storage.config.set(DEFAULT_CONFIG); + } else if (message.type === 'clear') { + const cache = Array.from(container).filter(({ _mujs }) => _mujs.info.host === message.host); + for (const ujs of cache) container.userjsCache.delete(ujs.id); + } else if (message.type === 'engine') { + const engine = cfg.engines.find((engine) => engine.name === message.engine.name); + for (const [k, v] of Object.entries(message.engine)) { + engine[k] = v; + } + storage.config.set(cfg).then(initCfg); + } else if (message.location) { + MUList.host = formatURL(message.location); + MUList.build().then(sendResponse); } else { - sendResponse({ value: cfg[message.name] }); + sendResponse({ cfg }); } } return true; } -webext.runtime.onMessage.addListener(onMessage); +function start() { + runtime.onMessage.addListener(onMessage); -const tc = (tab) => { - const loc = new URL(tab.url); - const host = formatURL(loc.host); - return { - loc, - host, - cache: MUJS.cache.get(host) - }; -}; -const updateCount = (tab) => { - const { cache } = tc(tab); - let cnt = 0; - if (cache) { - for (const v of Object.values(cache)) { - cnt += v.length; - } - } - webext.browserAction.setBadgeText({ - text: `${cnt}` + webext.tabs.onRemoved.addListener((tabId) => { + const cache = Array.from(container.userjsCache.values()).filter(({ _mujs }) => { + return !isEmpty(_mujs) && _mujs.info.tabId === tabId; + }); + for (const ujs of cache) container.userjsCache.delete(ujs.id); }); -}; -// webext.tabs.onCreated.addListener((tab) => { -// updateCount(tab); -// }); + webext.tabs.onCreated.addListener(setCount); -webext.tabs.onActivated.addListener((activeInfo) => { - const { tabId } = activeInfo; - webext.tabs.get(tabId, updateCount); - // if (currentTab.tabId !== tabId) { - // currentTab.tabId = tabId; - // } - // log('onActivated', currentTab); -}); + webext.tabs.onActivated.addListener((activeInfo) => { + const { tabId } = activeInfo; + webext.tabs.get(tabId, setCount); + }); -webext.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { - updateCount(tab); - // if (changeInfo.status === 'complete') { - // if (currentTab.tabId !== tabId) { - // currentTab.tabId = tabId; - // currentTab.url = getTabUrl(tab); - // } - // } -}); + webext.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { + if (tab.status === 'complete') { + setCount(tab, tabId); + } + }); + + webext.action.setBadgeText({ + text: '0' + }); +} + +start(); diff --git a/src/js/config.js b/src/js/config.js deleted file mode 100644 index 65599d1..0000000 --- a/src/js/config.js +++ /dev/null @@ -1,210 +0,0 @@ -'use strict'; - -const storage = webext.storage; -const Config = { - configLocalListeners: [], - configSyncListeners: [], - syncDefaults: { - // cache: true, - codePreview: false, - // autoexpand: false, - filterlang: false, - sleazyredirect: false, - // time: 10000, - blacklist: [ - { - enabled: true, - regex: true, - flags: '', - name: 'Blacklist 1', - url: '(gov|cart|checkout|login|join|signin|signup|sign-up|password|reset|password_reset)' - }, - { - enabled: true, - regex: true, - flags: '', - name: 'Blacklist 2', - url: '(pay|bank|money|localhost|authorize|checkout|bill|wallet|router)' - }, - { - enabled: true, - regex: false, - flags: '', - name: 'Blacklist 3', - url: 'https://home.bluesnap.com' - }, - { - enabled: true, - regex: false, - flags: '', - name: 'Blacklist 4', - url: ['zalo.me', 'skrill.com'] - } - ], - engines: [ - { - enabled: true, - name: 'greasyfork', - url: 'https://greasyfork.org' - }, - { - enabled: false, - name: 'sleazyfork', - url: 'https://sleazyfork.org' - }, - { - enabled: false, - name: 'openuserjs', - url: 'https://openuserjs.org/?q=' - }, - { - enabled: false, - name: 'github', - url: 'https://api.github.com/search/code?q=', - token: '' - } - ], - theme: { - 'even-row': '', - 'odd-row': '', - 'even-err': '', - 'odd-err': '', - 'background-color': '', - 'gf-color': '', - 'sf-color': '', - 'border-b-color': '', - 'gf-btn-color': '', - 'sf-btn-color': '', - 'sf-txt-color': '', - 'txt-color': '', - 'chck-color': '', - 'chck-gf': '', - 'chck-git': '', - 'chck-open': '', - placeholder: '', - 'position-top': '', - 'position-bottom': '', - 'position-left': '', - 'position-right': '', - 'font-family': '' - }, - recommend: { - author: true, - others: true - } - }, - cachedSyncConfig: {}, - /** - * @type { import("../typings/types").config } - */ - cachedLocalStorage: {}, - resetToDefault -}; - -function configProxy() { - storage.onChanged.addListener((changes = storage.StorageChange, areaName) => { - if (areaName === 'sync') { - for (const key in changes) { - Config.cachedSyncConfig[key] = changes[key].newValue; - } - for (const callback of Config.configSyncListeners) { - callback(changes); - } - } else if (areaName === 'local') { - for (const key in changes) { - Config.cachedLocalStorage[key] = changes[key].newValue; - } - for (const callback of Config.configLocalListeners) { - callback(changes); - } - } - }); - - const syncHandler = { - set(prop, value) { - Config.cachedSyncConfig[prop] = value; - storage.sync.set({ - [prop]: value - }); - return true; - }, - get(obj, prop) { - const data = Config.cachedSyncConfig[prop]; - return obj[prop] || data; - }, - deleteProperty(prop) { - storage.sync.remove(prop); - return true; - } - }; - - const localHandler = { - set(prop, value) { - Config.cachedLocalStorage[prop] = value; - storage.local.set({ - [prop]: value - }); - return true; - }, - get(obj, prop) { - const data = Config.cachedLocalStorage[prop]; - return obj[prop] || data; - }, - deleteProperty(prop) { - storage.local.remove(prop); - return true; - } - }; - return { - sync: new Proxy({ handler: syncHandler }, syncHandler), - local: new Proxy({ handler: localHandler }, localHandler) - }; -} - -async function fetchConfig() { - await Promise.all([ - new Promise((resolve) => { - storage.sync.get(null, function (items) { - Config.cachedSyncConfig = items; - resolve(); - }); - }), - new Promise((resolve) => { - storage.local.get(null, function (items) { - Config.cachedLocalStorage = items; - resolve(); - }); - }) - ]); -} - -async function setupConfig() { - await fetchConfig(); - for (const key in Config.syncDefaults) { - if (!Object.hasOwn(Config.cachedSyncConfig, key)) { - Config.cachedSyncConfig[key] = Config.syncDefaults[key]; - } - if (!Object.hasOwn(Config.cachedLocalStorage, key)) { - Config.cachedLocalStorage[key] = Config.syncDefaults[key]; - } - } - const config = configProxy(); - Config.config = config.sync; - Config.local = config.local; -} - -function resetToDefault() { - Config.cachedLocalStorage = Config.syncDefaults; - Config.cachedSyncConfig = Config.syncDefaults; - storage.local.set({ - ...Config.syncDefaults - }); - storage.sync.set({ - ...Config.syncDefaults - }); - return Config; -} - -setupConfig(); - -export default Config; diff --git a/src/js/constants.js b/src/js/constants.js new file mode 100644 index 0000000..a479978 --- /dev/null +++ b/src/js/constants.js @@ -0,0 +1,88 @@ +'use strict'; + +const template = { + id: 0, + bad_ratings: 0, + good_ratings: 0, + ok_ratings: 0, + daily_installs: 0, + total_installs: 0, + name: 'NOT FOUND', + description: 'NOT FOUND', + version: '0.0.0', + url: 'about:blank', + code_url: 'about:blank', + created_at: Date.now(), + code_updated_at: Date.now(), + locale: 'NOT FOUND', + deleted: false, + users: [] +}; +/** Unsupport host for search engines */ +const engineUnsupported = { + greasyfork: ['pornhub.com'], + sleazyfork: ['pornhub.com'], + openuserjs: [], + github: [] +}; +const builtinList = { + local: /localhost|router|gov|(\d+\.){3}\d+/, + finance: + /school|pay|bank|money|cart|checkout|authorize|bill|wallet|venmo|zalo|skrill|bluesnap|coin|crypto|currancy|insurance|finance/, + social: /login|join|signin|signup|sign-up|password|reset|password_reset/, + unsupported: { + host: 'fakku.net', + pathname: '/hentai/.+/read/page/.+' + } +}; +const BLANK_PAGE = 'about:blank'; +/** Lets highlight me :) */ +const authorID = 166061; +/** + * Some UserJS I personally enjoy - `https://greasyfork.org/scripts/{id}` + */ +const goodUserJS = [ + 33005, + 394820, + 438684, + 4870, + 394420, + 25068, + 483444, + 1682, + 22587, + 789, + 28497, + 386908, + 24204, + 404443, + 4336, + 368183, + 393396, + 473830, + 12179, + 423001, + 376510, + 23840, + 40525, + 6456, + 'https://openuserjs.org/install/Patabugen/Always_Remember_Me.user.js', + 'https://openuserjs.org/install/nokeya/Direct_links_out.user.js', + 'https://github.com/jijirae/y2monkey/raw/main/y2monkey.user.js', + 'https://github.com/jijirae/r2monkey/raw/main/r2monkey.user.js', + 'https://github.com/TagoDR/MangaOnlineViewer/raw/master/Manga_OnlineViewer.user.js', + 'https://github.com/jesus2099/konami-command/raw/master/INSTALL-USER-SCRIPT.user.js', + 'https://github.com/TagoDR/MangaOnlineViewer/raw/master/dist/Manga_OnlineViewer_Adult.user.js' +]; +/** Remove UserJS from banned accounts */ +const badUserJS = [478597]; + +export { + authorID, + template, + engineUnsupported, + builtinList, + BLANK_PAGE, + goodUserJS, + badUserJS +} diff --git a/src/js/container.js b/src/js/container.js new file mode 100644 index 0000000..5f89410 --- /dev/null +++ b/src/js/container.js @@ -0,0 +1,119 @@ +'use strict'; + +import { isEmpty, isFN } from './util.js'; +import { BLANK_PAGE, engineUnsupported } from './constants.js'; +import { webext } from './ext.js'; + +const MUJS_ORIGIN = webext.runtime.getURL('').replace(/\/$/, ''); + +export class BaseContainer { + constructor() { + this.toElem = this.toElem.bind(this); + this.cache = new Map(); + /** + * @type { Map } + */ + this.userjsCache = new Map(); + } + + checkBlacklist() { + return true; + } + + toElem() { + return Array.from(this).map(({ _mujs }) => { + return _mujs.root; + }); + } + + *[Symbol.iterator]() { + const arr = Array.from(this.userjsCache.values()).filter(({ _mujs }) => { + return !isEmpty(_mujs) && _mujs.info.engine.enabled; + }); + for (const userjs of arr) { + yield userjs; + } + } +} + +export class BaseList { + intEngines; + intHost; + constructor(hostname = undefined, container = new BaseContainer(), cfg = {}) { + this.groupBy = this.groupBy.bind(this); + this.container = container; + this.intEngines = cfg.engines ?? []; + this.host = hostname; + } + + setEngines(engines = []) { + const { host } = this; + return engines.filter((e) => { + if (!e.enabled) { + return false; + } + const v = engineUnsupported[e.name] ?? []; + if (v.includes(host)) { + return false; + } + return true; + }); + } + + set engines(engines) { + this.intEngines = this.setEngines(engines); + } + + get engines() { + return this.intEngines; + } + + set host(hostname) { + if (!MUJS_ORIGIN.includes(hostname)) { + this.intHost = hostname ?? BLANK_PAGE; + } else if (isEmpty(this.intHost)) { + this.intHost = BLANK_PAGE + } + + if (!this.container.cache.has(hostname)) { + const engineTemplate = {}; + for (const engine of this.engines) { + engineTemplate[engine.name] = []; + } + this.container.cache.set(hostname, engineTemplate); + } + this.blacklisted = this.container.checkBlacklist(hostname); + this.intEngines = this.setEngines(this.engines); + } + + get host() { + return this.intHost; + } + + groupBy() { + const arr = Array.from(this); + const callback = ({ _mujs }) => _mujs.info.engine.name; + if (isFN(Object.groupBy)) { + return Object.groupBy(arr, callback); + } + /** [Object.groupBy polyfill](https://gist.github.com/gtrabanco/7c97bd41aa74af974fa935bfb5044b6e) */ + return arr.reduce((acc = {}, ...args) => { + const key = callback(...args); + acc[key] ??= []; + acc[key].push(args[0]); + return acc; + }, {}); + } + + *[Symbol.iterator]() { + const { intHost, engines } = this; + const arr = Array.from(this.container).filter( + ({ _mujs }) => + _mujs.info.host === intHost && + engines.find((engine) => engine.enabled && engine.name === _mujs.info.engine.name) + ); + for (const userjs of arr) { + yield userjs; + } + } +} diff --git a/src/js/ext.js b/src/js/ext.js new file mode 100644 index 0000000..ebd6ec7 --- /dev/null +++ b/src/js/ext.js @@ -0,0 +1,34 @@ +export const webext = + self.browser instanceof Object && self.browser instanceof Element === false + ? self.browser + : self.chrome; +export const runtime = webext.runtime; + +/******************************************************************************/ + +// The extension's service worker can be evicted at any time, so when we +// send a message, we try a few more times when the message fails to be sent. + +export function sendMessage(msg) { + return new Promise((resolve, reject) => { + let i = 5; + const send = () => { + runtime + .sendMessage(msg) + .then((response) => { + resolve(response); + }) + .catch((reason) => { + i -= 1; + if (i <= 0) { + reject(reason); + } else { + setTimeout(send, 200); + } + }); + }; + send(); + }); +} + +/******************************************************************************/ diff --git a/src/js/i18n.js b/src/js/i18n.js index 959a1f3..b929550 100644 --- a/src/js/i18n.js +++ b/src/js/i18n.js @@ -1,17 +1,31 @@ 'use strict'; -/******************************************************************************/ - +// #region i18n const i18n = self.browser instanceof Object && self.browser instanceof Element === false ? self.browser.i18n : self.chrome.i18n; -const i18n$ = (...args) => i18n.getMessage(...args); - -/******************************************************************************/ +const i18n$ = (...args) => { + return i18n.getMessage(...args); +}; +/** + * @param {string | Date | number} str + */ +const toDate = (str = '') => { + return new Intl.DateTimeFormat(navigator.language).format( + typeof str === 'string' ? new Date(str) : str + ); +}; +/** + * @param {number | bigint} number + */ +const toNumber = (number) => { + return new Intl.NumberFormat(navigator.language).format(number); +}; +// #endregion -const isBackgroundProcess = document.title === 'Magic UserJS+ Background Page'; +const isBackgroundProcess = document && document.title === 'Magic UserJS+ Background Page'; if (isBackgroundProcess !== true) { // Helper to deal with the i18n'ing of HTML files. @@ -35,5 +49,6 @@ if (isBackgroundProcess !== true) { }; i18n.render(); } +const language = { i18n$, toDate, toNumber }; -export { i18n, i18n$ }; +export { i18n, i18n$, toDate, toNumber, language }; diff --git a/src/js/language.js b/src/js/language.js deleted file mode 100644 index f1f817e..0000000 --- a/src/js/language.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict'; - -class LanguageHandler { - constructor() { - this.current = (navigator.language ?? 'en').split('-')[0] ?? 'en'; - this.cache = []; - - const languages = navigator.languages ?? []; - for (const nlang of languages) { - const lg = nlang.split('-')[0]; - if (this.cache.indexOf(lg) === -1) { - this.cache.push(lg); - } - } - - if (!this.cache.includes(this.current)) { - this.cache.push(this.current); - } - } -} - -const language = new LanguageHandler(); - -export { - language -}; \ No newline at end of file diff --git a/src/js/logger.js b/src/js/logger.js index 40c1863..cbf0e2f 100644 --- a/src/js/logger.js +++ b/src/js/logger.js @@ -20,11 +20,6 @@ const err = (...msg) => { 'color: rgb(249, 24, 128);', ...msg ); - for (const ex of msg) { - if (typeof ex === 'object' && 'cause' in ex && typeof alert !== 'undefined') { - alert(`[Magic Userscript+] (${ex.cause}) ${ex.message}`); - } - } }; const info = (...msg) => { console.info( diff --git a/src/js/messager.js b/src/js/messager.js new file mode 100644 index 0000000..934ab67 --- /dev/null +++ b/src/js/messager.js @@ -0,0 +1,124 @@ +'use strict'; + +import { webext } from './ext.js'; + +export const hermes = { + port: null, + portTimer: null, + portTimerDelay: 10000, + msgIdGenerator: 1, + pending: new Map(), + waitStartTime: 0, + shuttingDown: false, + shutdown: function () { + this.shuttingDown = true; + this.destroyPort(); + }, + disconnectListener: function () { + void webext.runtime.lastError; + this.port = null; + this.destroyPort(); + }, + disconnectListenerBound: null, + messageListener: function (details) { + if (typeof details !== 'object' || details === null) { + return; + } + // Response to specific message previously sent + if (details.msgId !== undefined) { + const resolver = this.pending.get(details.msgId); + if (resolver !== undefined) { + this.pending.delete(details.msgId); + resolver(details.msg); + return; + } + } + }, + messageListenerBound: null, + canDestroyPort: function () { + return this.pending.size === 0; + }, + portPoller: function () { + this.portTimer = null; + if (this.port !== null && this.canDestroyPort()) { + return this.destroyPort(); + } + this.portTimer = setTimeout(this.portPollerBound, this.portTimerDelay); + this.portTimerDelay = Math.min(this.portTimerDelay * 2, 60 * 60 * 1000); + }, + portPollerBound: null, + destroyPort: function () { + if (this.portTimer !== null) { + clearTimeout(this.portTimer); + this.portTimer = null; + } + const port = this.port; + if (port !== null) { + port.disconnect(); + port.onMessage.removeListener(this.messageListenerBound); + port.onDisconnect.removeListener(this.disconnectListenerBound); + this.port = null; + } + // service pending callbacks + if (this.pending.size !== 0) { + const pending = this.pending; + this.pending = new Map(); + for (const resolver of pending.values()) { + resolver(); + } + } + }, + createPort: function () { + if (this.shuttingDown) { + return null; + } + if (this.messageListenerBound === null) { + this.messageListenerBound = this.messageListener.bind(this); + this.disconnectListenerBound = this.disconnectListener.bind(this); + this.portPollerBound = this.portPoller.bind(this); + } + try { + this.port = webext.runtime.connect({ name: 'hermes' }) || null; + // eslint-disable-next-line no-unused-vars + } catch (ex) { + this.port = null; + } + if (this.port === null) { + return null; + } + this.port.onMessage.addListener(this.messageListenerBound); + this.port.onDisconnect.addListener(this.disconnectListenerBound); + this.portTimerDelay = 10000; + if (this.portTimer === null) { + this.portTimer = setTimeout(this.portPollerBound, this.portTimerDelay); + } + return this.port; + }, + getPort: function () { + return this.port ?? this.createPort(); + }, + send: function (channel, msg) { + // Too large a gap between the last request and the last response means + // the main process is no longer reachable: memory leaks and bad + // performance become a risk -- especially for long-lived, dynamic + // pages. Guard against this. + if (this.pending.size > 64) { + if (Date.now() - this.waitStartTime > 60000) { + this.shutdown(); + } + } + const port = this.getPort(); + if (port === null) { + return Promise.resolve(); + } + if (this.pending.size === 0) { + this.waitStartTime = Date.now(); + } + const msgId = this.msgIdGenerator++; + const promise = new Promise((resolve) => { + this.pending.set(msgId, resolve); + }); + port.postMessage({ channel, msgId, msg }); + return promise; + } +}; diff --git a/src/js/mu-common.js b/src/js/mu-common.js deleted file mode 100644 index a7d6863..0000000 --- a/src/js/mu-common.js +++ /dev/null @@ -1,385 +0,0 @@ -'use strict'; - -/** - * @typedef { object } userjs - */ - -// if (typeof userjs === 'undefined') { -// let userjs = (self.userjs = {}); -// } - -if (typeof userjs === 'object' && userjs.isNull instanceof Function === false) { - const win = self ?? window; - const doc = win.document; - const isMobile = /Mobile|Tablet/.test(navigator.userAgent); - /** - * Object is typeof `Element` - * @template O - * @param { O } obj - * @returns { boolean } - */ - const isElem = (obj) => { - /** @type { string } */ - const s = Object.prototype.toString.call(obj); - return s.includes('Element'); - }; - /** - * Object is typeof `Function` - * @template O - * @param { O } obj - * @returns { boolean } - */ - const isFN = (obj) => { - /** @type { string } */ - const s = Object.prototype.toString.call(obj); - return s.includes('Function'); - }; - /** - * Object is typeof `object` / JSON Object - * @template O - * @param { O } obj - * @returns { boolean } - */ - const isObj = (obj) => { - /** @type { string } */ - const s = Object.prototype.toString.call(obj); - return s.includes('Object'); - }; - /** - * Object is `null` or `undefined` - * @template O - * @param { O } obj - * @returns { boolean } - */ - const isNull = (obj) => { - return Object.is(obj, null) || Object.is(obj, undefined); - }; - /** - * Object is Blank - * @template O - * @param { O } obj - * @returns { boolean } - */ - const isBlank = (obj) => { - return ( - (typeof obj === 'string' && Object.is(obj.trim(), '')) || - ((obj instanceof Set || obj instanceof Map) && Object.is(obj.size, 0)) || - (Array.isArray(obj) && Object.is(obj.length, 0)) || - (isObj(obj) && Object.is(Object.keys(obj).length, 0)) - ); - }; - /** - * Object is Empty - * @template O - * @param { O } obj - * @returns { boolean } - */ - const isEmpty = (obj) => { - return isNull(obj) || isBlank(obj); - }; - /** - * @template T - * @param { T } target - * @param { boolean } toQuery - * @param { Element | Document | undefined } root - * @returns { T[] } - */ - const normalizeTarget = (target, toQuery = true, root) => { - if (Object.is(target, null) || Object.is(target, undefined)) { - return []; - } - if (Array.isArray(target)) { - return target; - } - if (typeof target === 'string') { - return toQuery ? Array.from((root || document).querySelectorAll(target)) : [target]; - } - if (isElem(target)) { - return [target]; - } - return Array.from(target); - }; - /** - * Add Event Listener - * @template { HTMLElement } E - * @template { keyof HTMLElementEventMap } K - * @param { E } el - * @param { K } event - * @param { (this: E, ev: HTMLElementEventMap[K]) => any } callback - * @param { boolean | AddEventListenerOptions } options - */ - const ael = (el, event, callback, options = {}) => { - try { - for (const elem of normalizeTarget(el)) { - if (!elem) { - continue; - } - if (isMobile && event === 'click') { - elem.addEventListener('touchstart', callback); - return; - } - if (event === 'fclick') { - event = 'click'; - } - elem.addEventListener(event, callback, options); - } - } catch (ex) { - console.error(ex); - } - }; - /** - * Form Attributes of Element - * @template { keyof HTMLElementTagNameMap } K - * @param { K } elem - * @param { keyof HTMLElement } attr - */ - const formAttrs = (elem, attr = {}) => { - for (const key in attr) { - if (typeof attr[key] === 'object') { - formAttrs(elem[key], attr[key]); - } else if (isFN(attr[key])) { - if (key === 'container') { - key(); - continue; - } - if (/^on/.test(key)) { - elem[key] = attr[key]; - continue; - } - ael(elem, key, attr[key]); - } else if (key === 'class') { - elem.className = attr[key]; - } else { - elem[key] = attr[key]; - } - } - }; - /** - * Make Element - * @template { keyof HTMLElementTagNameMap } K - * @param { K } tagName - * @param { string } cname - * @param { keyof HTMLElement } attrs - * @returns { HTMLElementTagNameMap[K] } - */ - const make = (tagName, cname, attrs = {}) => { - let el = null; - try { - el = document.createElement(tagName); - if (typeof cname === 'string' && !isEmpty(cname)) { - el.className = cname; - } - if (!isEmpty(attrs)) { - formAttrs(el, attrs); - } - } catch (ex) { - console.error(ex); - } - return el; - }; - /** - * setTimeout w/ Promise - * @param { number } timeout - Timeout in milliseconds (ms) - * @returns { Promise } Promise object - */ - const delay = (timeout = 5000) => new Promise((resolve) => setTimeout(resolve, timeout)); - const Network = { - /** - * Fetch a URL with fetch API as fallback - * - * When GM is supported, makes a request like XMLHttpRequest, with some special capabilities, not restricted by same-origin policy - * @link https://violentmonkey.github.io/api/gm/#gm_xmlhttprequest - * @link https://developer.mozilla.org/docs/Web/API/Fetch_API - * @param { RequestInfo | URL } url - The URL to fetch - * @param { Request['method'] } method - Fetch method - * @param { 'buffer' | 'json' | 'text' | 'blob' | 'document' } responseType - Response type - * @param { RequestInit } data - Fetch parameters - * @returns { Promise } Fetch results - */ - async req(url, method = 'GET', responseType = 'json', data = {}) { - if (isEmpty(url)) { - throw new Error('"url" parameter is empty'); - } - method = Network.bscStr(method, false); - responseType = Network.bscStr(responseType); - const params = { - method, - ...data - }; - return await new Promise((resolve, reject) => { - /** - * @param { Response } response - * @returns { Response | Document } - */ - const fetchResp = (response_1) => { - if (!response_1.ok) reject(response_1); - const check = (str_2 = 'text') => { - return isFN(response_1[str_2]) ? response_1[str_2]() : response_1; - }; - if (responseType.match(/buffer/i)) { - resolve(check('arrayBuffer')); - } else if (responseType.match(/json/i)) { - resolve(check('json')); - } else if (responseType.match(/text/i)) { - resolve(check('text')); - } else if (responseType.match(/blob/i)) { - resolve(check('blob')); - } else if (responseType.match(/formdata/i)) { - resolve(check('formData')); - } else if (responseType.match(/clone/i)) { - resolve(check('clone')); - } else if (responseType.match(/document/i) && isFN(response_1.text)) { - const domParser = new DOMParser(); - const respTxt = response_1.text(); - if (respTxt instanceof Promise) { - respTxt.then((txt) => { - const doc = domParser.parseFromString(txt, 'text/html'); - resolve(doc); - }); - } else { - const doc = domParser.parseFromString(respTxt, 'text/html'); - resolve(doc); - } - } else { - resolve(response_1); - } - }; - fetch(url, params).then(fetchResp).catch(reject); - }); - }, - format(bytes, decimals = 2) { - if (Number.isNaN(bytes)) return '0 Bytes'; - const k = 1024; - const dm = decimals < 0 ? 0 : decimals; - const i = Math.floor(Math.log(bytes) / Math.log(k)); - return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${Network.sizes[i]}`; - }, - sizes: ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], - /** - * @template { string } S - * @param { S } str - * @param { boolean } lowerCase - * @returns { S } - */ - bscStr(str = '', lowerCase = true) { - const txt = str[lowerCase ? 'toLowerCase' : 'toUpperCase'](); - return txt.replaceAll(/\W/g, ''); - } - }; - // const i18n$ = (...args) => { - // const arr = []; - // for (const arg of args) { - // arr.push(webext.i18n.getMessage(arg)); - // } - // return arr.length !== 1 ? arr : arr[0]; - // }; - - class Timeout { - constructor() { - this.ids = []; - } - - set(delay, reason) { - return new Promise((resolve, reject) => { - const id = setTimeout(() => { - isNull(reason) ? resolve() : reject(reason); - this.clear(id); - }, delay); - this.ids.push(id); - }); - } - - clear(...ids) { - this.ids = this.ids.filter((id) => { - if (ids.includes(id)) { - clearTimeout(id); - return false; - } - return true; - }); - } - } - class MUError extends Error { - /** - * @param {string} fnName - (Optional) Function name - * @param {...string} params - Extra error parameters - */ - constructor(fnName = 'muError', ...params) { - super(...params); - if (Error.captureStackTrace) { - Error.captureStackTrace(this, MUError); - } else { - this.stack = new Error().stack; - } - this.fn = `[${fnName}]`; - this.name = this.constructor.name; - } - } - - userjs.error = MUError; - userjs.isMobile = isMobile; - userjs.Timeout = Timeout; - userjs.isElem = isElem; - userjs.isFN = isFN; - userjs.isObj = isObj; - userjs.isNull = isNull; - userjs.isBlank = isBlank; - userjs.isEmpty = isEmpty; - userjs.ael = ael; - userjs.formAttrs = formAttrs; - userjs.make = make; - userjs.delay = delay; - userjs.normalizeTarget = normalizeTarget; - - Object.assign(userjs, { - makeImage(imgSrc = '', attrs = {}, cname) { - const img = new Image(); - img.alt = ''; - img.referrerPolicy = 'no-referrer'; - img.src = imgSrc; - if (!isEmpty(cname)) { - img.className = cname; - } - if (!isEmpty(attrs)) { - for (const key in attrs) { - img[key] = attrs[key]; - } - } - return img; - }, - halt(e) { - e.preventDefault(); - e.stopPropagation(); - }, - injScript(text, remove = true) { - const inj = make('script', 'mu-injected', { - type: 'text/javascript', - innerHTML: text - }); - (doc.head || doc.documentElement || doc).appendChild(inj); - if (!remove) { - return inj; - } - delay(1000).then(() => inj.remove()); - }, - /** - * @param {Node} element - * @param {MutationCallback} callback - * @param {MutationObserverInit} options - */ - observe(element, callback, options = { subtree: true, childList: true }) { - const observer = new MutationObserver(callback); - callback([], observer); - observer.observe(element, options); - return observer; - }, - /** - * @param {string} url - URL of webpage to open - * @param {object} params - GM parameters - */ - openInTab(url, params = {}) { - params = Object.is(params, {}) ? '_blank' : params; - return win.open(url, params); - } - }); -} diff --git a/src/js/mu-hermes.js b/src/js/mu-hermes.js deleted file mode 100644 index 9772b05..0000000 --- a/src/js/mu-hermes.js +++ /dev/null @@ -1,126 +0,0 @@ -'use strict'; - -if (typeof userjs === 'object') { - userjs.hermes = { - port: null, - portTimer: null, - portTimerDelay: 10000, - msgIdGenerator: 1, - pending: new Map(), - waitStartTime: 0, - shuttingDown: false, - shutdown: function () { - this.shuttingDown = true; - this.destroyPort(); - }, - disconnectListener: function () { - void webext.runtime.lastError; - this.port = null; - this.destroyPort(); - }, - disconnectListenerBound: null, - messageListener: function (details) { - if (typeof details !== 'object' || details === null) { - return; - } - // Response to specific message previously sent - if (details.msgId !== undefined) { - const resolver = this.pending.get(details.msgId); - if (resolver !== undefined) { - this.pending.delete(details.msgId); - resolver(details.msg); - return; - } - } - }, - messageListenerBound: null, - canDestroyPort: function () { - return this.pending.size === 0; - }, - portPoller: function () { - this.portTimer = null; - if (this.port !== null && this.canDestroyPort()) { - return this.destroyPort(); - } - this.portTimer = setTimeout(this.portPollerBound, this.portTimerDelay); - this.portTimerDelay = Math.min(this.portTimerDelay * 2, 60 * 60 * 1000); - }, - portPollerBound: null, - destroyPort: function () { - if (this.portTimer !== null) { - clearTimeout(this.portTimer); - this.portTimer = null; - } - const port = this.port; - if (port !== null) { - port.disconnect(); - port.onMessage.removeListener(this.messageListenerBound); - port.onDisconnect.removeListener(this.disconnectListenerBound); - this.port = null; - } - // service pending callbacks - if (this.pending.size !== 0) { - const pending = this.pending; - this.pending = new Map(); - for (const resolver of pending.values()) { - resolver(); - } - } - }, - createPort: function () { - if (this.shuttingDown) { - return null; - } - if (this.messageListenerBound === null) { - this.messageListenerBound = this.messageListener.bind(this); - this.disconnectListenerBound = this.disconnectListener.bind(this); - this.portPollerBound = this.portPoller.bind(this); - } - try { - this.port = webext.runtime.connect({ name: 'hermes' }) || null; - // eslint-disable-next-line no-unused-vars - } catch (ex) { - this.port = null; - } - if (this.port === null) { - return null; - } - this.port.onMessage.addListener(this.messageListenerBound); - this.port.onDisconnect.addListener(this.disconnectListenerBound); - this.portTimerDelay = 10000; - if (this.portTimer === null) { - this.portTimer = setTimeout(this.portPollerBound, this.portTimerDelay); - } - return this.port; - }, - getPort: function () { - return this.port !== null ? this.port : this.createPort(); - }, - send: function (channel, msg) { - // Too large a gap between the last request and the last response means - // the main process is no longer reachable: memory leaks and bad - // performance become a risk -- especially for long-lived, dynamic - // pages. Guard against this. - if (this.pending.size > 64) { - if (Date.now() - this.waitStartTime > 60000) { - this.shutdown(); - } - } - const port = this.getPort(); - if (port === null) { - return Promise.resolve(); - } - if (this.pending.size === 0) { - this.waitStartTime = Date.now(); - } - const msgId = this.msgIdGenerator++; - const promise = new Promise((resolve) => { - this.pending.set(msgId, resolve); - }); - port.postMessage({ channel, msgId, msg }); - return promise; - } - }; -} - -void 0; \ No newline at end of file diff --git a/src/js/network.js b/src/js/network.js index 50fc613..7a8440d 100644 --- a/src/js/network.js +++ b/src/js/network.js @@ -9,59 +9,57 @@ const Network = { if (isEmpty(url)) { throw new Error('"url" parameter is empty'); } - method = Network.bscStr(method, false); - responseType = Network.bscStr(responseType); + data = Object.assign({}, data); + method = this.bscStr(method, false); + responseType = this.bscStr(responseType); const params = { method, ...data }; - return await new Promise((resolve, reject) => { - /** - * @param { Response } response - * @returns { Response | Document } - */ - const fetchResp = (response_1) => { - if (!response_1.ok) reject(response_1); - const check = (str_2 = 'text') => { - return isFN(response_1[str_2]) ? response_1[str_2]() : response_1; - }; - if (responseType.match(/buffer/i)) { - resolve(check('arrayBuffer')); - } else if (responseType.match(/json/i)) { - resolve(check('json')); - } else if (responseType.match(/text/i)) { - resolve(check('text')); - } else if (responseType.match(/blob/i)) { - resolve(check('blob')); - } else if (responseType.match(/formdata/i)) { - resolve(check('formData')); - } else if (responseType.match(/clone/i)) { - resolve(check('clone')); - } else if (responseType.match(/document/i) && isFN(response_1.text)) { - const domParser = new DOMParser(); - const respTxt = response_1.text(); - if (respTxt instanceof Promise) { - respTxt.then((txt) => { - const doc = domParser.parseFromString(txt, 'text/html'); + return new Promise((resolve, reject) => { + fetch(url, params) + .then((response_1) => { + if (!response_1.ok) reject(response_1); + const check = (str_2 = 'text') => { + return isFN(response_1[str_2]) ? response_1[str_2]() : response_1; + }; + if (responseType.match(/buffer/)) { + resolve(check('arrayBuffer')); + } else if (responseType.match(/json/)) { + resolve(check('json')); + } else if (responseType.match(/text/)) { + resolve(check('text')); + } else if (responseType.match(/blob/)) { + resolve(check('blob')); + } else if (responseType.match(/formdata/)) { + resolve(check('formData')); + } else if (responseType.match(/clone/)) { + resolve(check('clone')); + } else if (responseType.match(/document/)) { + const respTxt = check('text'); + const domParser = new DOMParser(); + if (respTxt instanceof Promise) { + respTxt.then((txt) => { + const doc = domParser.parseFromString(txt, 'text/html'); + resolve(doc); + }); + } else { + const doc = domParser.parseFromString(respTxt, 'text/html'); resolve(doc); - }); + } } else { - const doc = domParser.parseFromString(respTxt, 'text/html'); - resolve(doc); + resolve(response_1); } - } else { - resolve(response_1); - } - }; - fetch(url, params).then(fetchResp).catch(reject); + }) + .catch(reject); }); }, format(bytes, decimals = 2) { - if (Number.isNaN(bytes)) return '0 Bytes'; + if (Number.isNaN(bytes)) return `0 ${this.sizes[0]}`; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const i = Math.floor(Math.log(bytes) / Math.log(k)); - return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${Network.sizes[i]}`; + return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${this.sizes[i]}`; }, sizes: ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], bscStr(str = '', lowerCase = true) { @@ -70,4 +68,4 @@ const Network = { } }; -export default Network; \ No newline at end of file +export default Network; diff --git a/src/js/popup.js b/src/js/popup.js index cde4b29..cc2373c 100644 --- a/src/js/popup.js +++ b/src/js/popup.js @@ -1,74 +1,95 @@ 'use strict'; + +import { webext, runtime, sendMessage } from './ext.js'; import { err, log, info } from './logger.js'; -import { i18n$ } from './i18n.js'; -import { dom, normalizeTarget, qs, qsA } from './querySelector.js'; -import { reqCode, parse_meta } from './request-code.js'; -import { ael, make, isBlank, isNull, isEmpty, isObj, isString, hasOwn, openInTab } from './util.js'; -import { XMap } from './XMap.js'; +import { i18n$, language } from './i18n.js'; +import { dom, qs, qsA } from './querySelector.js'; +import { ParseUserJS } from './request-code.js'; +import Network from './network.js'; +import { + ael, + make, + isNull, + isEmpty, + isElem, + isObj, + openInTab, + strToURL, + isRegExp, + loadFilters, + formatURL +} from './util.js'; +import { builtinList, template, BLANK_PAGE, badUserJS, authorID, goodUserJS } from './constants.js'; +import { DEFAULT_CONFIG } from './storage.js'; +import { BaseContainer, BaseList } from './container.js'; +/******************************************************************************/ /** * @type { import("../typings/types").config } */ let cfg = {}; +/******************************************************************************/ + +/** + * @type { chrome.tabs.Tab | browser.tabs.Tab } + */ +const currentTab = {}; +const tabURL = new URL(runtime.getURL('/')); -const { hermes } = userjs; +/******************************************************************************/ -// Lets highlight me :) -const authorID = 166061; -// Some UserJS I personally enjoy -const goodUserJS = [ - 423001, - 376510, - 23840, - 40525, - 6456, - 'https://github.com/TagoDR/MangaOnlineViewer/raw/master/Manga_OnlineViewer.user.js', - 'https://github.com/jesus2099/konami-command/raw/master/INSTALL-USER-SCRIPT.user.js', - 'https://github.com/TagoDR/MangaOnlineViewer/raw/master/dist/Manga_OnlineViewer_Adult.user.js' -]; +function normalizedHostname(hn) { + return hn.replace(/^www\./, ''); +} + +/******************************************************************************/ + +const params = new URLSearchParams(location.search); +//#region Icon SVGs const iconSVG = { - install: { - viewBox: '0 0 16 16', - html: '' - }, - search: { - viewBox: '0 0 24 24', - html: '' - }, + close: 'fa-solid fa-xmark', + code: 'fa-solid fa-code', + collapse: 'fa-solid fa-compress', + download: 'fa-solid fa-file-arrow-down', + expand: 'fa-solid fa-arrow-up-right-from-square', // fa-expand + gear: 'fa-solid fa-gear', + github: 'fa-brands fa-github', + globe: 'fa-solid fa-globe', + install: 'fa-solid fa-download', + issue: 'fa-solid fa-bug', + minus: 'fa-solid fa-minus', + nav: 'fa-solid fa-bars', + pager: 'fa-solid fa-pager', verified: { viewBox: '0 0 56 56', fill: 'currentColor', stroke: 'currentColor', html: '' }, - refresh: { - viewBox: '0 0 1024 1024', - fill: 'currentColor', - html: '' - }, - // get(type, container) { - // return new Promise((resolve) => { - // const img = new Image(); - // img.src = webext.runtime.getURL(`/img/${type}.svg`); - // img.onload = () => { - // if (container) { - // container.appendChild(img); - // } - // resolve(img); - // } - // }) - // }, + refresh: 'fa-solid fa-rotate-right', load(type, container) { - const xmlns = 'http://www.w3.org/2000/svg'; - const svgElem = document.createElementNS(xmlns, 'svg'); - for (const [k, v] of Object.entries(iconSVG[type])) { - if (k === 'html') { - continue; + let svgElem; + if (typeof iconSVG[type] === 'string') { + svgElem = make('i', iconSVG[type], { + id: `mujs_${type ?? 'Unknown'}` + }); + } else { + svgElem = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + for (const [k, v] of Object.entries(iconSVG[type])) { + if (k === 'html') { + continue; + } + svgElem.setAttributeNS(null, k, v); + } + try { + if (typeof iconSVG[type].html === 'string') { + svgElem.innerHTML = iconSVG[type].html; + dom.attr(svgElem, 'id', `mujs_${type ?? 'Unknown'}`); + } + // eslint-disable-next-line no-unused-vars + } catch (ex) { + /* empty */ } - svgElem.setAttributeNS(null, k, v); - } - if (isString(iconSVG[type].html)) { - svgElem.innerHTML = iconSVG[type].html; } if (container) { container.appendChild(svgElem); @@ -77,78 +98,8 @@ const iconSVG = { return svgElem.outerHTML; } }; - -const main = qs('mujs-main'); -const cfgpage = qs('form'); -const footer = qs('.mujs-footer'); -const rateContainer = qs('.rate-container'); - -const table = qs('table'); -const tabbody = qs('tbody'); -const tabhead = qs('thead'); - -const urlBar = qs('.mujs-url-bar'); -const btncfg = qs('mujs-btn.settings'); -const btngreasy = qs('mujs-btn.greasy'); -const btnissue = qs('mujs-btn.issue'); -const btnhome = qs('mujs-btn.github'); - -const toolbar = qs('mujs-toolbar'); - -const promptElem = make('mujs-row', 'mujs-prompt'); -main.append(promptElem); - -const makeTHead = (rows) => { - const tr = make('tr'); - for (const r of normalizeTarget(rows)) { - const tparent = make('th', r.class ?? '', r); - tr.append(tparent); - } - tabhead.append(tr); - table.append(tabhead, tabbody); -}; -makeTHead([ - { - class: 'mujs-header-name', - textContent: i18n$('name') - }, - { - textContent: i18n$('createdby') - }, - { - textContent: i18n$('daily_installs') - }, - { - textContent: i18n$('updated') - }, - { - textContent: i18n$('install') - } -]); - -const renderTheme = (theme) => { - theme = theme || cfg.theme; - if (isEmpty(theme)) { - return; - } - // if (theme === defcfg.theme) { - // return; - // } - const sty = qs('mujs-root').style; - for (const [k, v] of Object.entries(theme)) { - const str = `--mujs-${k}`; - const prop = sty.getPropertyValue(str); - if (isEmpty(v)) { - theme[k] = prop; - } - if (prop === v) { - continue; - } - sty.removeProperty(str); - sty.setProperty(str, v); - } -}; -const cfgMap = new XMap(); +//#endregion +const cfgMap = new Map(); const rebuildCfg = () => { for (const engine of cfg.engines) { if (cfgMap.has(engine.name)) { @@ -172,88 +123,457 @@ const rebuildCfg = () => { } } } - dom.prop(cfgMap.get('blacklist'), 'value', JSON.stringify(cfg.blacklist, null, ' ')); - dom.prop(cfgMap.get('theme'), 'value', JSON.stringify(cfg.theme, null, ' ')); - renderTheme(cfg.theme); + // dom.prop(cfgMap.get('blacklist'), 'value', JSON.stringify(cfg.blacklist, null, ' ')); + for (const [k, v] of Object.entries(cfg.theme)) { + dom.prop(cfgMap.get(k), 'value', v); + } + container.renderTheme(cfg.theme); }; -const getHost = (str = '') => { - return str.split('.').splice(-2).join('.'); +const Counter = { + cnt: { + total: { + count: 0 + } + }, + set(engine) { + if (!this.cnt[engine.name]) { + const counter = make('count-frame', engine.enabled ? '' : 'hidden', { + dataset: { + counter: engine.name + }, + title: engine.query ? decodeURIComponent(engine.query) : engine.url, + textContent: '0' + }); + this.cnt[engine.name] = { + root: counter, + count: 0 + }; + return counter; + } + return this.cnt[engine.name].root; + }, + update(count, engine) { + this.cnt[engine.name].count += count; + this.cnt.total.count += count; + this.updateAll(); + }, + updateAll() { + for (const v of Object.values(this.cnt)) dom.text(v.root, v.count); + webext.action.setBadgeText({ + text: `${this.cnt.total.count}` + }); + document.title = `Magic UserJS+ (${this.cnt.total.count})`; + }, + reset() { + for (const [k, v] of Object.entries(this.cnt)) { + dom.text(v.root, 0); + v.count = 0; + const engine = cfg.engines.find((engine) => k === engine.name); + if (engine) { + dom.cl[engine.enabled ? 'remove' : 'add'](v.root, 'hidden'); + } + } + webext.action.setBadgeText({ + text: '0' + }); + document.title = 'Magic UserJS+ (0)'; + } }; -const ContainerHandler = class { - constructor() { +// #region Container +class Container extends BaseContainer { + constructor(url) { + super(url); + this.refresh = this.refresh.bind(this); this.showError = this.showError.bind(this); - // this.cleanup = this.cleanup.bind(this); - this.setHost(window.top.document.location.href); - this.cache = new XMap(); - this.userjsCache = new XMap(); + + this.webpage = strToURL(url); + this.host = this.getHost(this.webpage.host); + this.domain = this.getDomain(this.webpage.host); + this.unsaved = false; this.isBlacklisted = false; this.rebuild = false; - this.counters = { - total: 0 - }; - } + this.root = qs('mujs-root'); - setHost(link) { + this.init(); + } + // #region init + init() { try { - this.webpage = new URL(link); + this.mainbtn = make('count-frame', 'mainbtn', { + textContent: '0' + }); + this.promptElem = make('mujs-row', 'mujs-prompt'); + + this.urlBar = qs('.mujs-url-bar'); + this.rateContainer = qs('.rate-container'); + this.footer = qs('.mujs-footer'); + this.countframe = qs('.counter-container'); + this.toolbar = qs('mujs-toolbar'); + this.table = qs('table'); + this.tabhead = qs('thead'); + this.cfgpage = qs('.mujs-cfg'); + this.main = qs('mujs-main'); + this.tabbody = qs('tbody'); + this.btnframe = qs('.btn-frame'); + + this.btnfullscreen = make('mujs-btn', 'fullscreen', { + title: i18n$('max'), + innerHTML: iconSVG.load('expand'), + dataset: { + command: 'fullscreen' + } + }); + this.btnHandles = make('mujs-column', 'btn-handles'); + this.btncfg = make('mujs-btn', 'settings hidden', { + title: 'Settings', + innerHTML: iconSVG.load('gear'), + dataset: { + command: 'settings' + } + }); + this.btnhome = make('mujs-btn', 'github hidden', { + title: 'GitHub', + innerHTML: iconSVG.load('github'), + dataset: { + command: 'open-tab', + webpage: 'https://github.com/magicoflolis/Userscript-Plus' + } + }); + this.btnissue = make('mujs-btn', 'issue hidden', { + innerHTML: iconSVG.load('issue'), + title: i18n$('issue'), + dataset: { + command: 'open-tab', + webpage: 'https://github.com/magicoflolis/Userscript-Plus/issues' + } + }); + this.btngreasy = make('mujs-btn', 'greasy hidden', { + title: 'Greasy Fork', + innerHTML: iconSVG.load('globe'), + dataset: { + command: 'open-tab', + webpage: 'https://greasyfork.org/scripts/421603' + } + }); + this.btnnav = make('mujs-btn', 'nav', { + title: 'Navigation', + innerHTML: iconSVG.load('nav'), + dataset: { + command: 'navigation' + } + }); + if (params.size === 0) { + this.btnHandles.append(this.btnfullscreen); + } + + this.toolbar.append(this.btnHandles); + this.btnframe.append(this.btnhome, this.btngreasy, this.btnissue, this.btncfg, this.btnnav); + this.main.append(this.promptElem); + + const { host, refresh, cache, table } = this; + class Tabs { + /** + * @param { HTMLElement } root + */ + constructor(root) { + /** + * @type { Set } + */ + this.pool = new Set(); + this.blank = BLANK_PAGE; + this.protocal = 'mujs:'; + this.protoReg = new RegExp(`${this.protocal}(.+)`, 'i'); + this.el = { + add: make('mujs-addtab', { + textContent: '+', + dataset: { + command: 'new-tab' + } + }), + head: make('mujs-tabs'), + root + }; + this.el.head.append(this.el.add); + this.el.root.append(this.el.head); + this.custom = () => {}; + } + /** + * @param {string} hostname + */ + getTab(hostname) { + return [...this.pool].find(({ dataset }) => hostname === dataset.host); + } + getActive() { + return [...this.pool].find((tab) => tab.classList.contains('active')); + } + /** + * @param {string} hostname + */ + intFN(hostname) { + if (!hostname.startsWith(this.protocal)) { + return; + } + const p = this.protoReg.exec(hostname); + if (!p) { + return; + } + if (p[1] === 'settings') { + dom.cl.remove(cfgpage, 'hidden'); + dom.cl.add(table, 'hidden'); + urlBar.placeholder = 'Search settings'; + } + } + /** + * @param {HTMLElement} tab + * @param {boolean} [build] + */ + active(tab, build = true) { + if (!this.pool.has(tab)) this.pool.add(tab); + dom.cl.add([table, cfgpage], 'hidden'); + dom.cl.remove([...this.pool], 'active'); + dom.cl.add(tab, 'active'); + if (!build) { + dom.cl.remove(table, 'hidden'); + return; + } + const host = tab.dataset.host ?? this.blank; + if (host === this.blank) { + dom.cl.add(cfgpage, 'hidden'); + dom.cl.remove(table, 'hidden'); + refresh(); + } else if (host.startsWith(this.protocal)) { + this.intFN(host); + } else { + dom.cl.add(cfgpage, 'hidden'); + dom.cl.remove(table, 'hidden'); + this.custom(host); + } + } + /** @param { HTMLElement } tab */ + close(tab) { + if (this.pool.has(tab)) this.pool.delete(tab); + const host = tab.dataset.host; + if (cfg.clearTabCache && cache.has(host)) { + cache.delete(host); + sendMessage({ + type: 'clear', + host + }); + } + if (tab.classList.contains('active')) refresh(); + const sibling = tab.nextElementSibling ?? tab.previousElementSibling; + if (sibling) { + if (sibling.dataset.command !== 'new-tab') { + this.active(sibling); + } + } + tab.remove(); + } + /** + * @param {string} [hostname] + */ + create(hostname = undefined) { + if (typeof hostname === 'string') { + const createdTab = this.getTab(hostname); + if (this.protoReg.test(hostname) && createdTab) { + this.active(createdTab); + return; + } + } + const tab = make('mujs-tab', { + dataset: { + command: 'switch-tab' + }, + style: `order: ${this.el.head.childElementCount};` + }); + const tabClose = make('mu-js', { + dataset: { + command: 'close-tab' + }, + title: i18n$('close'), + textContent: 'X' + }); + const tabHost = make('mujs-host'); + const p = this.protoReg.exec(hostname); + tab.append(tabHost, tabClose); + this.el.head.append(tab); + this.active(tab, false); + if (isNull(hostname)) { + refresh(); + tab.dataset.host = this.blank; + tabHost.title = i18n$('newTab'); + tabHost.textContent = i18n$('newTab'); + // hostname.startsWith(this.protocal) + } else if (p) { + tab.dataset.host = hostname || host; + tabHost.title = p[1] || tab.dataset.host; + tabHost.textContent = tabHost.title; + this.intFN(hostname); + } else { + tab.dataset.host = hostname || host; + tabHost.title = hostname || host; + tabHost.textContent = tabHost.title; + // this.custom(host); + } + return tab; + } + } + this.Tabs = new Tabs(this.toolbar); + + const makeTHead = (rows = []) => { + const tr = make('tr'); + for (const r of rows) { + const tparent = make('th', r.class ?? '', r); + tr.append(tparent); + } + this.tabhead.append(tr); + this.table.append(this.tabhead, this.tabbody); + }; + makeTHead([ + { + class: 'mujs-header-name', + textContent: i18n$('name') + }, + { + textContent: i18n$('createdby') + }, + { + textContent: i18n$('daily_installs') + }, + { + textContent: i18n$('updated') + }, + { + textContent: i18n$('install') + } + ]); + + const tabbody = this.tabbody; + const getCellValue = (tr, idx) => + tr.children[idx].dataset.value || tr.children[idx].textContent; + const comparer = (idx, asc) => (a, b) => + ((v1, v2) => + v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) + ? v1 - v2 + : v1.toString().localeCompare(v2))( + getCellValue(asc ? a : b, idx), + getCellValue(asc ? b : a, idx) + ); + for (const th of this.tabhead.rows[0].cells) { + if (dom.text(th) === i18n$('install')) continue; + dom.cl.add(th, 'mujs-pointer'); + ael(th, 'click', () => { + /** [Stack Overflow Reference](https://stackoverflow.com/questions/14267781/sorting-html-table-with-javascript/53880407#53880407) */ + Array.from(tabbody.querySelectorAll('tr')) + .sort(comparer(Array.from(th.parentNode.children).indexOf(th), (this.asc = !this.asc))) + .forEach((tr) => tabbody.appendChild(tr)); + }); + } + return true; } catch (ex) { - err(ex, { cause: 'ContainerHandler' }); - this.webpage = window.location; + err(ex); } - this.host = getHost(this.webpage.hostname); + return false; + } + initFn() { + Counter.cnt.total.root = this.mainbtn; + for (const engine of cfg.engines) this.countframe.append(Counter.set(engine)); + } + // #endregion + setHost(link) { + this.webpage = strToURL(link); + this.host = this.getHost(this.webpage.host); + this.domain = this.getDomain(this.webpage.host); } - checkBlacklist(str) { str = str || this.host; let blacklisted = false; - for (const b of cfg.blacklist.filter((b) => b.enabled)) { - if (b.regex === true) { - const reg = new RegExp(b.url, b.flags); - if (!reg.test(str)) continue; - blacklisted = true; - } - if (Array.isArray(b.url)) { - for (const c of b.url) { - if (!str.includes(c)) continue; + if (/accounts*\.google\./.test(this.webpage.host)) { + blacklisted = true; + } + const blacklist = cfg.blacklist ?? []; + for (const b of blacklist) { + if (typeof b === 'string') { + if (b.startsWith('userjs-')) { + const r = /userjs-(\w+)/.exec(b)[1]; + const biList = builtinList[r]; + if (isRegExp(biList)) { + if (!biList.test(str)) continue; + blacklisted = true; + } else if (isObj(biList) && biList.host === this.host) { + blacklisted = true; + } + } + } else if (isObj(b)) { + if (!b.enabled) { + continue; + } + if (b.regex === true) { + const reg = new RegExp(b.url, b.flags); + if (!reg.test(str)) continue; blacklisted = true; } + if (Array.isArray(b.url)) { + for (const c of b.url) { + if (!str.includes(c)) continue; + blacklisted = true; + } + } + if (!str.includes(b.url)) continue; + blacklisted = true; } - if (!str.includes(b.url)) continue; - blacklisted = true; - } - if (blacklisted) { - this.showError('Blacklisted'); } this.isBlacklisted = blacklisted; - return blacklisted; + return this.isBlacklisted; } - - updateCounter(count, engine) { - this.counters[engine.name] += count; - this.counters.total += count; - this.updateCounters(); + getInfo(url) { + const webpage = strToURL(url || this.webpage); + const host = this.getHost(webpage.host); + const domain = this.getDomain(webpage.host); + return { + domain, + host, + webpage + }; } - - updateCounters() { - for (const [k, v] of Object.entries(this.counters)) { - if (k === 'total') { - continue; + /** + * @template { string } S + * @param { S } str + */ + getHost(str = '') { + return str.split('.').splice(-2).join('.'); + } + /** + * @template { string } S + * @param { S } str + */ + getDomain(str = '') { + return str.split('.').at(-2) ?? BLANK_PAGE; + } + renderTheme(theme) { + theme = theme || cfg.theme || DEFAULT_CONFIG.theme; + if (theme === DEFAULT_CONFIG.theme) { + return; + } + const sty = this.root.style; + for (const [k, v] of Object.entries(theme)) { + const str = `--mujs-${k}`; + const prop = sty.getPropertyValue(str); + if (isEmpty(v)) { + theme[k] = prop; } - if (qs(`count-frame[data-counter="${k}"]`)) { - dom.text(qs(`count-frame[data-counter="${k}"]`), v); + if (prop === v) { + continue; } + sty.removeProperty(str); + sty.setProperty(str, v); } - webext.browserAction.setBadgeText({ - text: `${this.counters.total}` - }); - document.title = `Magic UserJS+ (${this.counters.total})`; } - makePrompt(txt, dataset = {}, usePrompt = true) { - if (qs('.prompt', promptElem)) { - for (const elem of qsA('.prompt', promptElem)) { + if (qs('.prompt', this.promptElem)) { + for (const elem of qsA('.prompt', this.promptElem)) { if (elem.dataset.prompt) { elem.remove(); } @@ -285,217 +605,56 @@ const ContainerHandler = class { elPrompt.append(elYes, elNo); el.append(elPrompt); } - promptElem.append(el); + this.promptElem.append(el); } - save() { this.unsaved = false; - // MU.storage.setValue('Config', cfg); + sendMessage({ + type: 'save', + cfg + }); info('Saved:', cfg); } - + /** + * @template {string | Error} E + * @param {...E} ex + */ showError(...ex) { err(...ex); const error = make('mu-js', 'error'); let str = ''; for (const e of ex) { - str += `${isString(e) ? e : `${e.message} ${e.stack}`}\n`; - } - error.appendChild(document.createTextNode(str)); - footer.append(error); - } - - refresh() { - urlBar.placeholder = i18n$('newTab'); - this.counters.total = 0; - for (const engine of cfg.engines) { - this.counters[engine.name] = 0; - } - this.updateCounters(); - dom.prop([tabbody, rateContainer, footer], 'innerHTML', ''); - } -}; -const MUJS = new ContainerHandler(); - -class Tabs { - constructor() { - this.Tab = new XMap(); - this.blank = 'about:blank'; - this.protocal = 'mujs:'; - this.protoReg = new RegExp(`${this.protocal}(.+)`); - this.el = { - add: make('mujs-addtab', '', { - textContent: '+', - dataset: { - command: 'new-tab' - } - }), - head: make('mujs-tabs') - }; - this.el.head.append(this.el.add); - toolbar.append(this.el.head); - } - hasTab(...params) { - for (const p of params) { - if (!this.Tab.has(p)) { - return false; - } - const content = normalizeTarget(this.Tab.get(p)).filter((t) => p === t.dataset.host); - if (isBlank(content)) { - return false; - } - } - return true; - } - storeTab(host) { - const h = host ?? this.blank; - if (!this.Tab.has(h)) { - this.Tab.set(h, new Set()); - } - return this.Tab.get(h); - } - cache(host, ...tabs) { - const h = host ?? this.blank; - const tabCache = this.storeTab(h); - for (const t of normalizeTarget(tabs)) { - if (tabCache.has(t)) { - continue; - } - tabCache.add(t); - } - this.Tab.set(h, tabCache); - return tabCache; - } - mujs(host) { - if (!host.startsWith(this.protocal)) { - return; - } - const type = host.match(this.protoReg)[1]; - if (type === 'settings') { - dom.cl.remove([cfgpage], 'hidden'); - dom.cl.add(table, 'hidden'); - urlBar.placeholder = i18n$('search_placeholder'); - } - } - active(tab, build = true) { - for (const t of normalizeTarget(tab, false)) { - dom.cl.add([cfgpage], 'hidden'); - dom.cl.remove(table, 'hidden'); - dom.cl.remove(qsA('mujs-tab', this.el.head), 'active'); - dom.cl.add(t, 'active'); - if (!build) { - continue; - } - const host = t.dataset.host ?? this.blank; - if (host === this.blank) { - MUJS.refresh(); - } else if (host.startsWith(this.protocal)) { - this.mujs(host); - } else { - buildlist(host); - } - } - } - /** @param { HTMLElement } tab */ - close(tab) { - for (const t of normalizeTarget(tab, false)) { - const host = t.dataset.host; - if (MUJS.cache.has(host)) { - MUJS.cache.delete(host); - } - if (dom.cl.has(t, 'active')) { - MUJS.refresh(); - } - const sibling = t.previousElementSibling ?? t.nextElementSibling; - if (sibling) { - if (sibling.dataset.command !== 'new-tab') { - this.active(sibling); + str += `${typeof e === 'string' ? e : `${e.cause ? `[${e.cause}] ` : ''}${e.message}${e.stack ? ` ${e.stack}` : ''}`}\n`; + if (isObj(e)) { + if (e.notify) { + dom.cl.add(this.mainframe, 'error'); } } - if (this.Tab.has(host)) { - this.Tab.delete(host); - } - t.remove(); } + error.appendChild(document.createTextNode(str)); + this.footer.append(error); } - create(host = undefined) { - if (isString(host)) { - if (host.startsWith(this.protocal) && this.hasTab(host)) { - this.active(this.Tab.get(host)); - return; - } - const content = normalizeTarget(this.storeTab(host)).filter((t) => host === t.dataset.host); - if (!isEmpty(content)) { - return; - } - } - const tab = make('mujs-tab', '', { - dataset: { - command: 'switch-tab' - }, - style: `order: ${this.el.head.childElementCount};` - }); - const tabClose = make('mu-js', '', { - dataset: { - command: 'close-tab' - }, - title: i18n$('close'), - textContent: 'X' - }); - const tabHost = make('mujs-host'); - tab.append(tabHost, tabClose); - this.el.head.append(tab); - this.active(tab, false); - this.cache(host, tab); - if (isNull(host)) { - MUJS.refresh(); - // urlBar.placeholder = i18n$('newTab'); - tab.dataset.host = this.blank; - tabHost.title = i18n$('newTab'); - tabHost.textContent = i18n$('newTab'); - } else if (host.startsWith(this.protocal)) { - const type = host.match(this.protoReg)[1]; - tab.dataset.host = host || MUJS.host; - tabHost.title = type || tab.dataset.host; - tabHost.textContent = tabHost.title; - this.mujs(host); - } else { - tab.dataset.host = host || MUJS.host; - tabHost.title = host || MUJS.host; - tabHost.textContent = tabHost.title; - } - return tab; + refresh() { + this.urlBar.placeholder = i18n$('newTab'); + Counter.reset(); + dom.cl.remove(this.toElem(), 'hidden'); + dom.cl.remove(qsA('mujs-section[data-name]', this.cfgpage), 'hidden'); + dom.prop([this.tabbody, this.rateContainer, this.footer], 'innerHTML', ''); } } -const tab = new Tabs(); - -const template = { - id: 0, - bad_ratings: 0, - good_ratings: 0, - ok_ratings: 0, - daily_installs: 0, - total_installs: 0, - name: 'NOT FOUND', - description: 'NOT FOUND', - version: '0.0.0', - url: 'about:blank', - code_url: 'about:blank', - created_at: Date.now(), - code_updated_at: Date.now(), - users: [ - { - name: '', - url: '' - } - ] +const container = new Container(window.top.document.location.href); +// #endregion +const { urlBar, tabbody, cfgpage, main, Tabs, showError } = container; +container.Tabs.custom = (host) => { + MUList.host = host; + MUList.build(); }; + const mkList = (txt = '', obj = {}) => { if (!obj.root || !obj.type) { return; } const { root, type } = obj; - const list = obj.list ?? []; const appliesTo = make('mu-js', 'mujs-list', { textContent: `${txt}: ` }); @@ -508,26 +667,48 @@ const mkList = (txt = '', obj = {}) => { }); ujsURLs.append(appliesTo, applyList); root.append(ujsURLs); + + const list = obj.list ?? []; if (isEmpty(list)) { const elem = make('mujs-a', '', { textContent: i18n$('listing_none') }); applyList.append(elem); - if (type === 'antifeatures') { - dom.cl.add(ujsURLs, 'hidden'); - } + dom.cl.add(ujsURLs, 'hidden'); return; } for (const c of list) { - if (isObj(c)) { + if (typeof c === 'string' && c.startsWith('http')) { const elem = make('mujs-a', '', { - textContent: c.text + textContent: c, + dataset: { + command: 'open-tab', + webpage: c + } }); - if (c.domain) { - elem.dataset.command = 'open-tab'; - elem.dataset.webpage = `https://${c.text}`; - } applyList.append(elem); + } else if (isObj(c)) { + if (type === 'resource') { + for (const [k, v] of Object.entries(c)) { + const elem = make('mujs-a', '', { + textContent: k ?? 'ERROR' + }); + if (v.startsWith('http')) { + elem.dataset.command = 'open-tab'; + elem.dataset.webpage = v; + } + applyList.append(elem); + } + } else { + const elem = make('mujs-a', '', { + textContent: c.text + }); + if (c.domain) { + elem.dataset.command = 'open-tab'; + elem.dataset.webpage = `https://${c.text}`; + } + applyList.append(elem); + } } else { const elem = make('mujs-a', '', { textContent: c @@ -535,35 +716,35 @@ const mkList = (txt = '', obj = {}) => { applyList.append(elem); } } - if (type === 'antifeatures') { - dom.cl.remove(ujsURLs, 'hidden'); - } -}; -const toLocaleDate = (str = '') => { - return new Intl.DateTimeFormat(navigator.language).format(new Date(str)); }; // #region Create UserJS +/** + * @param { import("../typings/types.d.ts").GSForkQuery } ujs + * @param { string } engine + */ const createjs = (ujs, engine) => { - for (const key in template) { - if (hasOwn(ujs, key)) { - continue; - } - ujs[key] = template[key]; - } // Lets not add this UserJS to the list if (ujs.id === 421603) { return; } - if (!MUJS.userjsCache.has(ujs.id)) { - MUJS.userjsCache.set(ujs.id, ujs); + if (badUserJS.includes(ujs.id) || badUserJS.includes(ujs.url)) { + return; } + if (!container.userjsCache.has(ujs.id)) container.userjsCache.set(ujs.id, ujs); const eframe = make('td', 'install-btn'); const uframe = make('td', 'mujs-uframe'); const fdaily = make('td', 'mujs-list', { - textContent: ujs.daily_installs + textContent: ujs.daily_installs, + dataset: { + name: 'daily_installs' + } }); const fupdated = make('td', 'mujs-list', { - textContent: toLocaleDate(ujs.code_updated_at) + textContent: language.toDate(ujs.code_updated_at), + dataset: { + name: 'code_updated_at', + value: new Date(ujs.code_updated_at).toISOString() + } }); const fname = make('td', 'mujs-name'); const fmore = make('mujs-column', 'mujs-list hidden', { @@ -587,16 +768,24 @@ const createjs = (ujs, engine) => { textContent: `${i18n$('version_number')}: ${ujs.version}` }); const fcreated = make('mu-js', 'mujs-list', { - textContent: `${i18n$('created_date')}: ${toLocaleDate(ujs.created_at)}` + textContent: `${i18n$('created_date')}: ${language.toDate(ujs.created_at)}`, + dataset: { + name: 'created_at', + value: new Date(ujs.created_at).toISOString() + } }); const flicense = make('mu-js', 'mujs-list', { title: ujs.license ?? i18n$('no_license'), textContent: `${i18n$('license')}: ${ujs.license ?? i18n$('no_license')}`, - style: - 'text-overflow: ellipsis; overflow: hidden; white-space: nowrap; width: fit-content; max-width: 20em;' + dataset: { + name: 'license' + } }); const ftotal = make('mu-js', 'mujs-list', { - textContent: `${i18n$('total_installs')}: ${ujs.total_installs}` + textContent: `${i18n$('total_installs')}: ${language.toNumber(ujs.total_installs)}`, + dataset: { + name: 'total_installs' + } }); const fratings = make('mu-js', 'mujs-list', { title: i18n$('ratings'), @@ -606,6 +795,7 @@ const createjs = (ujs, engine) => { title: i18n$('good'), textContent: ujs.good_ratings, dataset: { + name: 'good_ratings', el: 'good' } }); @@ -613,6 +803,7 @@ const createjs = (ujs, engine) => { title: i18n$('ok'), textContent: ujs.ok_ratings, dataset: { + name: 'ok_ratings', el: 'ok' } }); @@ -620,6 +811,7 @@ const createjs = (ujs, engine) => { title: i18n$('bad'), textContent: ujs.bad_ratings, dataset: { + name: 'bad_ratings', el: 'bad' } }); @@ -630,18 +822,16 @@ const createjs = (ujs, engine) => { command: 'list-description' } }); - const sIcon = ujs.code_url.endsWith('.user.css') ? '🧾' : ujs.code_url.endsWith('.user.js') ? '🐵' : '💾'; const scriptInstall = make('mu-jsbtn', 'install', { - // innerHTML: `${iconSVG.load('install')} ${i18n$('install')}`, - innerHTML: `${sIcon} ${i18n$('install')}`, + innerHTML: `${iconSVG.load('install')} ${i18n$('install')}`, title: `${i18n$('install')} "${ujs.name}"`, dataset: { command: 'install-script', userjs: ujs.code_url } }); - const scriptDownload = make('mu-jsbtn', '', { - innerHTML: `${iconSVG.load('install')} ${i18n$('saveFile')}`, + const scriptDownload = make('mu-jsbtn', { + innerHTML: `${iconSVG.load('download')} ${i18n$('saveFile')}`, dataset: { command: 'download-userjs', userjs: ujs.id, @@ -662,21 +852,26 @@ const createjs = (ujs, engine) => { spellcheck: false, wrap: 'soft' }); - const loadCode = make('mu-jsbtn', '', { - innerHTML: `${iconSVG.load('search')} ${i18n$('preview_code')}`, + const loadCode = make('mu-jsbtn', { + innerHTML: `${iconSVG.load('code')} ${i18n$('preview_code')}`, dataset: { command: 'load-userjs', userjs: ujs.id } }); - if (engine) { - tr.dataset.engine = engine; - if (!engine.includes('fork') && cfg.recommend.others && goodUserJS.includes(ujs.url)) { - tr.dataset.good = 'upsell'; + const loadMetadata = make('mu-jsbtn', { + innerHTML: `${iconSVG.load('code')} Metadata`, + dataset: { + command: 'load-header', + userjs: ujs.id } + }); + tr.dataset.engine = engine; + if (!engine.includes('fork') && cfg.recommend.others && goodUserJS.includes(ujs.url)) { + tr.dataset.good = 'upsell'; } for (const u of ujs.users) { - const user = make('mujs-a', '', { + const user = make('mujs-a', { innerHTML: u.name, title: u.url, dataset: { @@ -690,54 +885,211 @@ const createjs = (ujs, engine) => { } uframe.append(user); } - if (engine.includes('fork') && cfg.recommend.others && goodUserJS.includes(ujs.id)) { + if (cfg.recommend.others && goodUserJS.includes(ujs.id)) { tr.dataset.good = 'upsell'; } eframe.append(scriptInstall); ratings.append(fratings, fgood, fok, fbad); jsInfo.append(ftotal, ratings, fver, fcreated); - mkList('Size', { - list: ujs.code_size, - type: 'size', + mkList(i18n$('code_size'), { + list: ujs._mujs.code.code_size, + type: 'code_size', root: jsInfo }); jsInfoB.append(flicense); + const data_meta = ujs._mujs.code?.data_meta ?? {}; mkList(i18n$('antifeatures'), { - list: ujs.antifeatures, + list: data_meta.antifeatures ?? [], type: 'antifeatures', root: jsInfoB }); mkList(i18n$('applies_to'), { - list: ujs.code_match, - type: 'match-urls', + list: ujs._mujs.code?.data_names ?? [], + type: 'data_names', root: jsInfoB }); mkList('@grant', { - list: ujs.code_grant, - type: 'grants', + list: data_meta.grant ?? [], + type: 'grant', + root: jsInfoB + }); + mkList('@require', { + list: data_meta.require, + type: 'require', + root: jsInfoB + }); + mkList('@resource', { + list: isNull(data_meta.resource) ? [] : [data_meta.resource], + type: 'resource', root: jsInfoB }); fmore.append(jsInfo, jsInfoB); - fBtns.append(scriptDownload, loadCode); + fBtns.append(scriptDownload, loadCode, loadMetadata); fname.append(ftitle, fdesc, fmore, fBtns, codeArea); - if (ujs.code_data) { - codeArea.value = ujs.code_data; - } + const loadPage = make('mu-jsbtn', { + innerHTML: `${iconSVG.load('pager')} Page`, + dataset: { + command: 'load-page', + userjs: ujs.id + } + }); + fBtns.append(loadPage); - for (const e of [fname, uframe, fdaily, fupdated, eframe]) { - tr.append(e); - } - tabbody.append(tr); + if (ujs._mujs.code?.translated) tr.classList.add('translated'); + + for (const e of [fname, uframe, fdaily, fupdated, eframe]) tr.append(e); + ujs._mujs.root = tr; + return ujs._mujs.root; }; // #endregion +const applyTo = (ujs, name, elem, root) => { + const n = ujs._mujs.code[name] ?? ujs._mujs.code.data_meta[name]; + if (isEmpty(n)) { + const el = make('mujs-a', { + textContent: i18n$('listing_none') + }); + elem.append(el); + return; + } + dom.prop(elem, 'innerHTML', ''); + dom.cl.remove(root, 'hidden'); + if (isObj(n)) { + if (name === 'resource') { + for (const [k, v] of Object.entries(n)) { + const el = make('mujs-a', { + textContent: k ?? 'ERROR' + }); + if (v.startsWith('http')) { + el.dataset.command = 'open-tab'; + el.dataset.webpage = v; + } + elem.append(el); + } + } else { + const el = make('mujs-a', { + textContent: n.text + }); + if (n.domain) { + el.dataset.command = 'open-tab'; + el.dataset.webpage = `https://${n.text}`; + } + elem.append(el); + } + } else if (typeof n === 'string') { + const el = make('mujs-a', { + textContent: n + }); + elem.append(el); + } else { + for (const c of n) { + if (typeof c === 'string' && c.startsWith('http')) { + const el = make('mujs-a', { + textContent: c, + dataset: { + command: 'open-tab', + webpage: c + } + }); + elem.append(el); + } else if (isObj(c)) { + const el = make('mujs-a', { + textContent: c.text + }); + if (c.domain) { + el.dataset.command = 'open-tab'; + el.dataset.webpage = `https://${c.text}`; + } + elem.append(el); + } else { + const el = make('mujs-a', { + textContent: c + }); + elem.append(el); + } + } + } +}; const doInstallProcess = (installLink) => { - const queryOptions = { active: true, currentWindow: true }; - webext.tabs.query(queryOptions, (tabs) => { - webext.tabs.update(tabs[0].id, { url: installLink }); - }); + if (typeof currentTab.id === 'number') { + webext.tabs.update(currentTab.id, { url: installLink }); + } }; + +// #region List +class List extends BaseList { + constructor(hostname = undefined) { + super(hostname, container, cfg); + this.build = this.build.bind(this); + this.sortRecords = this.sortRecords.bind(this); + } + + // #region Builder + async build(results) { + try { + const { engines, container, host } = this; + if (isEmpty(engines)) { + for (const e of cfg.engines.filter((engine) => engine.enabled)) { + showError(`Engine: "${e.name}" unsupported on "${host}"`); + } + return; + } + if (container.checkBlacklist(host)) { + showError(`Blacklisted "${host}"`); + return; + } + container.refresh(); + if (!results) { + const { data } = await sendMessage({ + type: 'getData', + currentTab, + hostname: host + }); + results = data; + } + for (const ujs of results ?? []) { + ujs._mujs.code.request = async (translate = false, code_url) => { + if (ujs._mujs.code.data_code_block) { + return ujs._mujs.code; + } + const p = new ParseUserJS(); + await p.request(translate, code_url ?? ujs.code_url, ujs); + for (const [k, v] of Object.entries(p)) { + ujs._mujs.code[k] = v; + } + return ujs._mujs.code; + }; + createjs(ujs, ujs._mujs.info.engine.name); + } + urlBar.placeholder = i18n$('search_placeholder'); + urlBar.value = ''; + this.sortRecords(); + } catch (ex) { + showError(ex); + } + } + + sortRecords() { + const arr = Array.from(this); + for (const ujs of arr.flat().sort((a, b) => { + const sortType = cfg.autoSort ?? 'daily_installs'; + return b[sortType] - a[sortType]; + })) { + if (isElem(ujs._mujs.root)) tabbody.append(ujs._mujs.root); + } + for (const [name, value] of Object.entries(this.groupBy(arr))) { + Counter.update(value.length, { name }); + } + } + // #endregion +} +const MUList = new List(); +// #endregion + +container.renderTheme(); + +// #region Main event handlers ael(main, 'click', async (evt) => { try { /** @type { HTMLElement } */ @@ -758,7 +1110,7 @@ ael(main, 'click', async (evt) => { if (cmd === 'install-script' && dataset.userjs) { let installCode = dataset.userjs; if (!prmpt && dataset.userjs.endsWith('.user.css')) { - MUJS.makePrompt(i18n$('prmpt_css'), dataset); + container.makePrompt(i18n$('prmpt_css'), dataset); return; } else if (prmpt !== prmptChoice) { installCode = dataset.userjs.replace(/\.user\.css$/, '.user.js'); @@ -766,11 +1118,17 @@ ael(main, 'click', async (evt) => { doInstallProcess(installCode); } else if (cmd === 'open-tab' && dataset.webpage) { openInTab(dataset.webpage); + } else if (cmd === 'fullscreen') { + const tab = container.Tabs.getActive(); + openInTab(`${location.href}?host=${tab.dataset.host}`); } else if (cmd === 'navigation') { - if (dom.cl.has(btngreasy, 'hidden')) { - dom.cl.remove([btncfg, btngreasy, btnhome, btnissue], 'hidden'); - } else { - dom.cl.add([btncfg, btngreasy, btnhome, btnissue], 'hidden'); + for (const e of qsA('mujs-btn', target.parentElement)) { + if (dom.cl.has(e, 'nav')) continue; + if (dom.cl.has(e, 'hidden')) { + dom.cl.remove(e, 'hidden'); + } else { + dom.cl.add(e, 'hidden'); + } } } else if (cmd === 'list-description') { const arr = []; @@ -795,119 +1153,160 @@ ael(main, 'click', async (evt) => { } else { dom.cl.add(arr, 'hidden'); } - } else if (cmd === 'show-filter') { - dom.cl.toggle(qs('.mujs-fltlist').parentElement, 'hidden'); } else if (cmd === 'save') { if (!dom.prop(target, 'disabled')) { - MUJS.save(); - // sleazyRedirect(); - if (MUJS.rebuild) { - MUJS.cache.clear(); - buildlist(); + container.save(); + if (container.rebuild) { + container.cache.clear(); + MUList.build(); } - MUJS.unsaved = false; - MUJS.rebuild = false; + container.unsaved = false; + container.rebuild = false; } } else if (cmd === 'reset') { - // cfg = defcfg; - MUJS.unsaved = true; - MUJS.rebuild = true; + sendMessage({ type: 'reset' }); + cfg = DEFAULT_CONFIG; + container.unsaved = true; + container.rebuild = true; rebuildCfg(); } else if (cmd === 'settings') { - if (MUJS.unsaved) { - MUJS.showError('Unsaved changes'); + if (container.unsaved) { + showError('Unsaved changes'); } - tab.create('mujs:settings'); - MUJS.rebuild = false; + Tabs.create('mujs:settings'); + container.rebuild = false; } else if (cmd === 'new-tab') { - tab.create(); + Tabs.create(); } else if (cmd === 'switch-tab') { - tab.active(target); + Tabs.active(target); } else if (cmd === 'close-tab' && target.parentElement) { - tab.close(target.parentElement); + Tabs.close(target.parentElement); } else if (cmd === 'download-userjs') { - if (!MUJS.userjsCache.has(+dataset.userjs)) { + if (!container.userjsCache.has(+dataset.userjs)) { return; } - const dataUserJS = MUJS.userjsCache.get(+dataset.userjs); - const txt = await reqCode(dataUserJS); + const dataUserJS = container.userjsCache.get(+dataset.userjs); + let installCode = dataUserJS.code_url; + if (!prmpt && dataUserJS.code_url.endsWith('.user.css')) { + container.makePrompt('Download as UserStyle?', dataset); + return; + } else if (prmpt !== prmptChoice) { + installCode = dataUserJS.code_url.replace(/\.user\.css$/, '.user.js'); + } + const r = await dataUserJS._mujs.code.request(false, installCode); + const txt = r.data; if (typeof txt !== 'string') { return; } + const userjsName = dataset.userjsName ?? dataset.userjs; + const userjsExt = prmpt !== prmptChoice ? '.user.js' : '.user.css'; const makeUserJS = new Blob([txt], { type: 'text/plain' }); const dlBtn = make('a', 'mujs_Downloader'); dlBtn.href = URL.createObjectURL(makeUserJS); - dlBtn.download = `${dataset.userjsName ?? dataset.userjs}.user.js`; + dlBtn.download = `${userjsName}${userjsExt}`; dlBtn.click(); URL.revokeObjectURL(dlBtn.href); dlBtn.remove(); - } else if (cmd === 'load-userjs') { - if (!MUJS.userjsCache.has(+dataset.userjs)) { + } else if (cmd === 'load-userjs' || cmd === 'load-header') { + if (!container.userjsCache.has(+dataset.userjs)) { return; } const codeArea = qs('textarea', target.parentElement.parentElement); - if (!isEmpty(codeArea.value)) { + if (!isEmpty(codeArea.value) && cmd === codeArea.dataset.load) { dom.cl.toggle(codeArea, 'hidden'); return; } - const dataUserJS = MUJS.userjsCache.get(+dataset.userjs); - const txt = await reqCode(dataUserJS); - if (typeof txt !== 'string') { + codeArea.dataset.load = cmd; + const dataUserJS = container.userjsCache.get(+dataset.userjs); + const code_obj = await dataUserJS._mujs.code.request(); + if (typeof code_obj.data_code_block !== 'string') { + codeArea.value = 'An error occured'; return; } - codeArea.value = txt; + codeArea.value = cmd === 'load-userjs' ? code_obj.data_code_block : code_obj.data_meta_block; dom.cl.remove(codeArea, 'hidden'); - - const apTo = (name, elem) => { - if (isEmpty(dataUserJS[name])) { - const el = make('mujs-a', '', { - textContent: i18n$('listing_none') + for (const e of qsA('mujs-column[data-el="matches"]', target.parentElement.parentElement)) { + applyTo(dataUserJS, e.dataset.type, qs('.mujs-grants', e), e); + } + } else if (cmd === 'load-page') { + if (!container.userjsCache.has(+dataset.userjs)) { + return; + } + let pageArea = qs('mujs-page', target.parentElement.parentElement); + if (!pageArea) { + pageArea = make('mujs-page'); + target.parentElement.parentElement.append(pageArea); + const dataUserJS = container.userjsCache.get(+dataset.userjs); + const engine = dataUserJS._mujs.info.engine; + let pageURL; + if (engine.name.includes('fork')) { + const current = navigator.language.split('-')[0] ?? 'en'; + pageURL = dataUserJS.url.replace( + /\/scripts/, + `/${/^(zh|fr|es)/.test(current) ? navigator.language : current}/scripts` + ); + } else if (engine.name.includes('github')) { + const page_url = await Network.req(dataUserJS.page_url, 'GET', 'json', { + headers: { + Accept: 'application/vnd.github+json', + Authorization: `Bearer ${engine.token}`, + 'X-GitHub-Api-Version': '2022-11-28' + } + }).catch(() => { + return {}; }); - elem.append(el); - if (name === 'antifeatures') { - dom.cl.add(elem, 'hidden'); + if (!page_url.download_url) { + return; } + const page = await Network.req(page_url.download_url, 'GET', 'text'); + const shadow = pageArea.attachShadow({ mode: 'closed' }); + const div = make('div', { + innerHTML: page + }); + shadow.append(div); + return; } else { - for (const c of dataUserJS[name]) { - if (isObj(c)) { - const el = make('mujs-a', '', { - textContent: c.text - }); - if (c.domain) { - el.dataset.command = 'open-tab'; - el.dataset.webpage = `https://${c.text}`; - } - elem.append(el); - } else { - const el = make('mujs-a', '', { - textContent: c - }); - elem.append(el); + pageURL = dataUserJS.url; + } + if (!pageURL) { + return; + } + const page = await Network.req(pageURL, 'GET', 'document'); + const getContent = () => { + let content = 'An error occured'; + const h = new URL(dataUserJS.url); + const root = qs('.user-content', page.documentElement); + for (const e of qsA('[href]', root)) { + e.target = '_blank'; + e.style = 'pointer-events: auto;'; + if (e.href.startsWith('/')) { + e.href = `${h.origin}${e.href}`; } } - if (name === 'antifeatures') { - dom.cl.remove(elem, 'hidden'); + for (const e of qsA('img[src]', root)) { + e.style = + 'max-width: 25em; max-height: 25em; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;'; } - } - }; - const matchElem = qs( - '[data-type="match-urls"] > .mujs-grants', - target.parentElement.parentElement - ); - const grantElem = qs( - '[data-type="grants"] > .mujs-grants', - target.parentElement.parentElement - ); - const afElem = qs( - '[data-type="antifeatures"] > .mujs-grants', - target.parentElement.parentElement - ); - const sizeElem = qs('[data-type="size"] > .mujs-grants', target.parentElement.parentElement); - dom.prop([matchElem, grantElem, afElem, sizeElem], 'innerHTML', ''); - apTo('code_match', matchElem); - apTo('code_grant', grantElem); - apTo('antifeatures', afElem); - apTo('code_size', sizeElem); + if (root) { + content = root.innerHTML; + } else { + content = 'No additional info available'; + } + return content; + }; + const shadow = pageArea.attachShadow({ mode: 'closed' }); + const div = make('div', { + style: 'pointer-events: none;', + innerHTML: getContent() + }); + shadow.append(div); + return; + } + if (!dom.cl.has(pageArea, 'hidden')) { + dom.cl.add(pageArea, 'hidden'); + return; + } + dom.cl.remove(pageArea, 'hidden'); } else if (/export-/.test(cmd)) { const str = JSON.stringify(cmd === 'export-cfg' ? cfg : cfg.theme, null, ' '); const bytes = new TextEncoder().encode(str); @@ -936,29 +1335,28 @@ ael(main, 'click', async (evt) => { if (result.blacklist) { log(`Imported config: { ${file.name} }`, result); cfg = result; - MUJS.unsaved = true; - MUJS.rebuild = true; + container.unsaved = true; + container.rebuild = true; rebuildCfg(); - MUJS.save(); - // sleazyRedirect(); - MUJS.cache.clear(); - buildlist(); - MUJS.unsaved = false; - MUJS.rebuild = false; + container.save(); + container.cache.clear(); + MUList.build(); + container.unsaved = false; + container.rebuild = false; } else { log(`Imported theme: { ${file.name} }`, result); cfg.theme = result; - renderTheme(cfg.theme); + container.renderTheme(cfg.theme); } inpJSON.remove(); }; reader.onerror = () => { - MUJS.showError(reader.error); + showError(reader.error); inpJSON.remove(); }; }); } catch (ex) { - MUJS.showError(ex); + showError(ex); inpJSON.remove(); } } @@ -967,7 +1365,7 @@ ael(main, 'click', async (evt) => { inpJSON.click(); } } catch (ex) { - MUJS.showError(ex); + showError(ex); } }); ael(main, 'auxclick', (evt) => { @@ -982,61 +1380,179 @@ ael(main, 'auxclick', (evt) => { const dataset = target.dataset; const cmd = dataset.command; if (cmd === 'switch-tab' || cmd === 'close-tab') { - tab.close(target); + Tabs.close(target); } else if (cmd === 'new-tab') { - tab.create(); + Tabs.create(); } }); -renderTheme(cfg.theme); -const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent; -const comparer = (idx, asc) => (a, b) => - ((v1, v2) => - v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) ? v1 - v2 : v1.toString().localeCompare(v2))( - getCellValue(asc ? a : b, idx), - getCellValue(asc ? b : a, idx) - ); -for (const th of tabhead.rows[0].cells) { - if (dom.text(th) === i18n$('install')) continue; - dom.cl.add(th, 'mujs-pointer'); - ael(th, 'click', () => { - /** [Stack Overflow Reference](https://stackoverflow.com/questions/14267781/sorting-html-table-with-javascript/53880407#53880407) */ - Array.from(tabbody.querySelectorAll('tr')) - .sort(comparer(Array.from(th.parentNode.children).indexOf(th), (this.asc = !this.asc))) - .forEach((tr) => tabbody.appendChild(tr)); - }); -} +ael(main, 'updateditem', (evt) => { + /** + * @type {import("../typings/types.d.ts").GSForkQuery} + */ + const ujs = evt.detail; + if (!ujs._mujs) return; + for (const elem of qsA('[data-name]', ujs._mujs.root)) { + const name = elem.dataset.name; + if (name === 'code') { + if (ujs._mujs.code.data_code_block) { + if (cfg.preview.code && !cfg.preview.metadata) { + elem.value = ujs._mujs.code.data_code_block; + } else if (cfg.preview.metadata && !cfg.preview.code) { + elem.value = ujs._mujs.code.data_meta_block; + } else { + elem.value = `${ujs._mujs.code.META_START_COMMENT}${ujs._mujs.code.data_meta_block}${ujs._mujs.code.META_END_COMMENT}${ujs._mujs.code.data_code_block}`; + } + } + continue; + } + if (!ujs[name]) continue; + if (name === 'license') { + dom.attr(elem, 'title', ujs.license ?? i18n$('no_license')); + dom.text(elem, `${i18n$('license')}: ${ujs.license ?? i18n$('no_license')}`); + } else if (name === 'code_updated_at') { + dom.text(elem, language.toDate(ujs.code_updated_at)); + elem.dataset.value = new Date(ujs.code_updated_at).toISOString(); + } else if (name === 'created_date') { + dom.text(elem, `${i18n$('created_date')}: ${language.toDate(ujs.created_at)}`); + elem.dataset.value = new Date(ujs.created_at).toISOString(); + } else if (name === 'total_installs') { + dom.text(elem, `${i18n$('total_installs')}: ${language.toNumber(ujs.total_installs)}`); + } else { + dom.text(elem, ujs[name]); + } + } + if (ujs._mujs.code.data_code_block) { + for (const e of qsA('mujs-column[data-el="matches"]', ujs._mujs.root)) { + applyTo(ujs, e.dataset.type, qs('.mujs-grants', e), e); + } + } + if (container.userjsCache.has(ujs.id)) container.userjsCache.set(ujs.id, ujs); +}); ael(urlBar, 'input', (evt) => { evt.preventDefault(); if (urlBar.placeholder === i18n$('newTab')) { return; } + /** + * @type { string } + */ const val = evt.target.value; + const section = qsA('mujs-section[data-name]', cfgpage); if (isEmpty(val)) { - dom.cl.remove(qsA('tr[data-engine]', tabbody), 'hidden'); + dom.cl.remove(container.toElem(), 'hidden'); + dom.cl.remove(section, 'hidden'); return; } - const reg = new RegExp(val, 'gi'); const finds = new Set(); - const userjsCache = MUJS.userjsCache; - for (const [k, v] of userjsCache) { - const elem = qs(`tr[data-script-id="${k}"]`, tabbody); - if (!elem) { - continue; + if (!dom.cl.has(cfgpage, 'hidden')) { + const reg = new RegExp(val, 'gi'); + for (const elem of section) { + if (!isElem(elem)) { + continue; + } + if (finds.has(elem)) { + continue; + } + if (dom.text(elem).match(reg)) { + finds.add(elem); + } } - if (finds.has(elem)) { - continue; + dom.cl.add(section, 'hidden'); + dom.cl.remove([...finds], 'hidden'); + return; + } + const cacheValues = Array.from(container).filter(({ _mujs }) => { + return !finds.has(_mujs.root); + }); + /** + * @param {RegExpMatchArray} regExp + * @param {keyof import("../typings/types.d.ts").GSForkQuery} key + */ + const ezQuery = (regExp, key) => { + const q_value = val.replace(regExp, ''); + const reg = new RegExp(q_value, 'gi'); + for (const v of cacheValues) { + let k = v[key]; + if (typeof k === 'number') { + k = `${v[key]}`; + } + if (k && k.match(reg)) { + finds.add(v._mujs.root); + } + } + }; + if (val.match(/^(code_url|url):/)) { + ezQuery(/^(code_url|url):/, 'code_url'); + } else if (val.match(/^(author|users?):/)) { + const parts = /^[\w_]+:(.+)/.exec(val); + if (parts) { + const reg = new RegExp(parts[1], 'gi'); + for (const v of cacheValues.filter((v) => !isEmpty(v.users))) { + for (const user of v.users) { + for (const value of Object.values(user)) { + if (typeof value === 'string' && value.match(reg)) { + finds.add(v._mujs.root); + } else if (typeof value === 'number' && `${value}`.match(reg)) { + finds.add(v._mujs.root); + } + } + } + } } - if (v.name && v.name.match(reg)) { - finds.add(elem); + } else if (val.match(/^(locale|i18n):/)) { + ezQuery(/^(locale|i18n):/, 'locale'); + } else if (val.match(/^id:/)) { + ezQuery(/^id:/, 'id'); + } else if (val.match(/^license:/)) { + ezQuery(/^license:/, 'license'); + } else if (val.match(/^name:/)) { + ezQuery(/^name:/, 'name'); + } else if (val.match(/^description:/)) { + ezQuery(/^description:/, 'description'); + } else if (val.match(/^(search_engine|engine):/)) { + const parts = /^[\w_]+:(\w+)/.exec(val); + if (parts) { + const reg = new RegExp(parts[1], 'gi'); + for (const { _mujs } of cacheValues) { + if (!_mujs.info.engine.name.match(reg)) { + continue; + } + finds.add(_mujs.root); + } } - if (v.description && v.description.match(reg)) { - finds.add(elem); + } else if (val.match(/^filter:/)) { + const parts = /^\w+:(.+)/.exec(val); + if (parts) { + const bsFilter = loadFilters(cfg); + const filterType = bsFilter.get(parts[1].trim().toLocaleLowerCase()); + if (filterType) { + const { reg } = filterType; + for (const { name, users, _mujs } of cacheValues) { + if ([{ name }, ...users].find((o) => o.name.match(reg))) { + continue; + } + finds.add(_mujs.root); + } + } } - if (v.code_data) { - const meta = parse_meta(v.code_data); - for (const key of Object.keys(meta)) { - if (/name|desc/i.test(key) && key.match(reg)) { - finds.add(elem); + } else if (val.match(/^recommend:/)) { + for (const { url, id, users, _mujs } of cacheValues) { + if ( + users.find((u) => u.id === authorID) || + goodUserJS.includes(url) || + goodUserJS.includes(id) + ) { + finds.add(_mujs.root); + } + } + } else { + const reg = new RegExp(val, 'gi'); + for (const v of cacheValues) { + if (v.name && v.name.match(reg)) finds.add(v._mujs.root); + if (v.description && v.description.match(reg)) finds.add(v._mujs.root); + if (v._mujs.code.data_meta) { + for (const key of Object.keys(v._mujs.code.data_meta)) { + if (/name|desc/i.test(key) && key.match(reg)) finds.add(v._mujs.root); } } } @@ -1047,356 +1563,543 @@ ael(urlBar, 'input', (evt) => { ael(urlBar, 'change', (evt) => { evt.preventDefault(); const val = evt.target.value; - if (urlBar.placeholder === i18n$('newTab') && qs('mujs-tab.active', toolbar)) { - const tabElem = qs('mujs-tab.active', toolbar); - const tabHost = qs('mujs-host', tabElem); - if (val.startsWith('mujs:')) { - tab.close(tabElem); - if (tab.hasTab(val)) { - tab.active(tab.Tab.get(val)); + const tabElem = Tabs.getActive(); + if (urlBar.placeholder === i18n$('newTab') && tabElem) { + const tabHost = tabElem.firstElementChild; + const host = formatURL(normalizedHostname(val)); + if (Tabs.protoReg.test(val)) { + const createdTab = Tabs.getTab(val); + Tabs.close(tabElem); + if (createdTab) { + Tabs.active(createdTab); } else { - tab.create(val); + Tabs.create(val); } - return; - } else if (val === '*') { - tabElem.dataset.host = val; + evt.target.placeholder = i18n$('search_placeholder'); + evt.target.value = ''; + } else if (host === 'all-urls') { + tabElem.dataset.host = '*'; tabHost.title = ''; tabHost.textContent = ''; - buildlist(val); - return; - } - const value = getHost(val); - if (MUJS.checkBlacklist(value)) { - MUJS.showError(`Host blacklisted "${value}"`); - return; + MUList.host = '*'; + MUList.build(); + } else if (container.checkBlacklist(host)) { + showError(`Blacklisted "${host}"`); + } else { + tabElem.dataset.host = host; + tabHost.title = host; + tabHost.textContent = host; + MUList.host = host; + MUList.build(); } - tabElem.dataset.host = value; - tabHost.title = value; - tabHost.textContent = value; - buildlist(value); - return; } }); +// #endregion -async function buildlist(host = undefined) { - try { - if (isEmpty(host)) { - host = MUJS.host; - } - if (MUJS.checkBlacklist(host)) { - return; - } - if (!qs(`mujs-tab[data-host="${host}"]`)) { - tab.create(host); - } - MUJS.refresh(); - webext.runtime.sendMessage( - { - location: host - }, - (data) => { - if (isEmpty(data)) { - return; - } - for (const tabData of data) { - const { engine, host } = tabData; - if (!qs(`mujs-tab[data-host="${host}"]`)) { - tab.create(host); - } - for (const ujs of tabData.data) { - createjs(ujs, engine.name); - } - MUJS.updateCounter(tabData.data.length, engine); - } - urlBar.placeholder = i18n$('search_placeholder'); - urlBar.value = ''; - } - ); - } catch (ex) { - err(ex); - } -} +Tabs.custom = (host) => { + MUList.host = host; + MUList.build(); +}; -//#region Make Config +// #region Make Config const makecfg = () => { - const exBtn = make('mu-js', 'mujs-sty-flex'); - const exportCFG = make('mujs-btn', 'mujs-export', { - textContent: i18n$('export_config'), - dataset: { - command: 'export-cfg' - } - }); - const importCFG = make('mujs-btn', 'mujs-import', { - textContent: i18n$('import_config'), - dataset: { - command: 'import-cfg' - } - }); - const exportTheme = make('mujs-btn', 'mujs-export', { - textContent: i18n$('export_theme'), + const cbtn = make('mu-js', 'mujs-sty-flex'); + const savebtn = make('mujs-btn', 'save', { + textContent: i18n$('save'), dataset: { - command: 'export-theme' - } + command: 'save' + }, + disabled: false }); - const importTheme = make('mujs-btn', 'mujs-import', { - textContent: i18n$('import_theme'), + const resetbtn = make('mujs-btn', 'reset', { + textContent: i18n$('reset'), dataset: { - command: 'import-theme' + command: 'reset' } }); - exBtn.append(importCFG, importTheme, exportCFG, exportTheme); - cfgpage.append(exBtn); + cbtn.append(resetbtn, savebtn); - const makerow = (desc, type = null, nm, attrs = {}) => { - desc = desc ?? i18n$('no_license'); - nm = nm ?? i18n$('no_license'); - const sec = make('mujs-section', 'mujs-cfg-section', { - style: nm === 'cache' ? 'display: none;' : '' + const makesection = (name, tag) => { + tag = tag ?? i18n$('no_license'); + name = name ?? i18n$('no_license'); + const sec = make('mujs-section', { + dataset: { + name: tag + } + }); + const lb = make('label', { + dataset: { + command: tag + } + }); + const divDesc = make('mu-js', { + textContent: name }); - const lb = make('label'); - const divDesc = make('mu-js', 'mujs-cfg-desc', { - textContent: desc + ael(sec, 'click', (evt) => { + /** @type { HTMLElement } */ + const target = evt.target.closest('[data-command]'); + if (!target) { + return; + } + const cmd = target.dataset.command; + if (cmd === tag) { + const a = qsA(`[data-${tag}]`, sec); + if (dom.cl.has(a, 'hidden')) { + dom.cl.remove(a, 'hidden'); + } else { + dom.cl.add(a, 'hidden'); + } + } }); + lb.append(divDesc); sec.append(lb); cfgpage.append(sec); - if (isNull(type)) { + return sec; + }; + const sections = { + general: makesection('General', 'general'), + load: makesection('Automation', 'load'), + list: makesection('List', 'list'), + filters: makesection('List Filters', 'filters'), + blacklist: makesection('Blacklist (WIP)', 'blacklist'), + engine: makesection('Search Engines', 'engine'), + theme: makesection('Theme Colors', 'theme'), + exp: makesection('Import / Export', 'exp') + }; + const makeRow = (text, value, type = 'checkbox', tag = 'general', attrs = {}) => { + const lb = make('label', 'sub-section hidden', { + textContent: text, + dataset: { + [tag]: text + } + }); + cfgMap.set(text, value); + if (type === 'select') { + const inp = make('select', { + dataset: { + [tag]: text + }, + ...attrs + }); + for (const selV of Object.keys(template)) { + if (selV === 'deleted' || selV === 'users') continue; + const o = make('option', { + value: selV, + textContent: selV + }); + inp.append(o); + } + inp.value = cfg[value]; + lb.append(inp); + if (sections[tag]) { + sections[tag].append(lb); + } return lb; } - const inp = make('input', 'mujs-cfg-input', { + const inp = make('input', { type, dataset: { - name: nm + [tag]: text }, ...attrs }); - if (!cfgMap.has(nm)) { - cfgMap.set(nm, inp); + + if (tag === 'engine') { + inp.dataset.name = value; + } + + if (sections[tag]) { + sections[tag].append(lb); } + if (type === 'checkbox') { const inlab = make('mu-js', 'mujs-inlab'); - const la = make('label', '', { + const la = make('label', { onclick() { inp.dispatchEvent(new MouseEvent('click')); } }); inlab.append(inp, la); lb.append(inlab); - if (nm.includes('-')) { - return inp; - } - if (/(greasy|sleazy)fork|openuserjs|gi(thub|st)/gi.test(nm)) { - for (const i of cfg.engines) { - if (i.name !== nm) continue; - inp.checked = i.enabled; - inp.dataset.engine = i.name; + + const nm = /^(\w+)-(.+)/.exec(value); + if (nm) { + if (nm[1] === 'filters') { + inp.checked = cfg[nm[1]][nm[2]].enabled; + } else { + inp.checked = cfg[nm[1]][nm[2]]; + } + } else { + inp.checked = cfg[value]; + } + ael(inp, 'change', (evt) => { + container.unsaved = true; + if (/filterlang/i.test(value)) { + container.rebuild = true; + } + if (nm) { + if (nm[1] === 'filters') { + cfg[nm[1]][nm[2]].enabled = evt.target.checked; + } else { + cfg[nm[1]][nm[2]] = evt.target.checked; + } + } else { + cfg[value] = evt.target.checked; + } + sendMessage({ + type: 'save', + cfg + }); + }); + + if (tag === 'engine') { + const engine = cfg.engines.find((engine) => engine.name === value); + if (engine) { + inp.checked = engine.enabled; + inp.dataset.engine = engine.name; ael(inp, 'change', (evt) => { - // MUJS.unsaved = true; - // MUJS.rebuild = true; - i.enabled = evt.target.checked; - hermes.send('Save', { - prop: 'engines', - value: cfg.engines + container.unsaved = true; + container.rebuild = true; + engine.enabled = evt.target.checked; + sendMessage({ + type: 'engine', + engine }); }); + + if (engine.query) { + const d = DEFAULT_CONFIG.engines.find((e) => e.name === engine.name); + const urlInp = make('input', { + type: 'text', + defaultValue: '', + value: decodeURIComponent(engine.query) ?? '', + placeholder: decodeURIComponent(d.query) ?? '', + dataset: { + name: nm, + engine: engine.name + }, + onchange(evt) { + container.unsaved = true; + container.rebuild = true; + try { + engine.query = encodeURIComponent(new URL(evt.target.value).toString()); + sendMessage({ + type: 'engine', + engine + }); + } catch (ex) { + err(ex); + } + } + }); + lb.append(urlInp); + } + if (engine.name === 'github') { + const ghToken = make('input', { + type: 'text', + defaultValue: '', + value: engine.token ?? '', + placeholder: 'Paste Access Token', + dataset: { + engine: 'github-token' + }, + onchange(evt) { + container.unsaved = true; + container.rebuild = true; + engine.token = evt.target.value; + sendMessage({ + type: 'engine', + engine + }); + } + }); + lb.append(ghToken); + cfgMap.set('github-token', ghToken); + } } - } else { - inp.checked = cfg[nm]; - ael(inp, 'change', (evt) => { - // MUJS.unsaved = true; - // if (/filterlang/i.test(nm)) { - // MUJS.rebuild = true; - // } - cfg[nm] = evt.target.checked; - hermes.send('Save', { - prop: nm, - value: cfg[nm] - }); - }); } } else { + if (type === 'text') { + inp.defaultValue = ''; + inp.value = value ?? ''; + inp.placeholder = value ?? ''; + } + lb.append(inp); } - return inp; + + return lb; }; - makerow(i18n$('redirect'), 'checkbox', 'sleazyredirect'); - makerow(i18n$('filter'), 'checkbox', 'filterlang'); - makerow(i18n$('preview_code'), 'checkbox', 'codePreview'); - for (const inp of [ - makerow('Recommend author', 'checkbox', 'recommend-author'), - makerow('Recommend scripts', 'checkbox', 'recommend-others') - ]) { - const nm = inp.dataset.name === 'recommend-author' ? 'author' : 'others'; - inp.checked = cfg.recommend[nm]; - ael(inp, 'change', (evt) => { - // MUJS.unsaved = true; - cfg.recommend[nm] = evt.target.checked; - hermes.send('Save', { - prop: 'recommend', - value: cfg.recommend - }); + makeRow(i18n$('redirect'), 'sleazyredirect'); + + makeRow(i18n$('auto_fetch'), 'autofetch', 'checkbox', 'load'); + makeRow('Clear on Tab close', 'clearTabCache', 'checkbox', 'load'); + + makeRow('Default Sort', 'autoSort', 'select', 'list'); + makeRow(i18n$('filter'), 'filterlang', 'checkbox', 'list'); + makeRow(i18n$('preview_code'), 'preview-code', 'checkbox', 'list'); + makeRow('Preview Metadata', 'preview-metadata', 'checkbox', 'list'); + makeRow('Recommend author', 'recommend-author', 'checkbox', 'list'); + makeRow('Recommend scripts', 'recommend-others', 'checkbox', 'list'); + + for (const [k, v] of Object.entries(cfg.filters)) { + makeRow(v.name, `filters-${k}`, 'checkbox', 'filters'); + } + + makeRow('Greasy Fork', 'greasyfork', 'checkbox', 'engine'); + makeRow('Sleazy Fork', 'sleazyfork', 'checkbox', 'engine'); + // makeRow('Open UserJS', 'openuserjs', 'checkbox', 'engine'); + makeRow('GitHub API', 'github', 'checkbox', 'engine'); + + for (const [k, v] of Object.entries(cfg.theme)) { + const lb = make('label', 'hidden', { + textContent: k, + dataset: { + theme: k + } }); + const inp = make('input', { + type: 'text', + defaultValue: '', + value: v ?? '', + placeholder: v ?? '', + dataset: { + theme: k + }, + onchange(evt) { + let isvalid = true; + try { + const val = evt.target.value; + const sty = container.root.style; + const str = `--mujs-${k}`; + const prop = sty.getPropertyValue(str); + if (isEmpty(val)) { + cfg.theme[k] = DEFAULT_CONFIG.theme[k]; + sty.removeProperty(str); + return; + } + if (prop === val) { + return; + } + sty.removeProperty(str); + sty.setProperty(str, val); + cfg.theme[k] = val; + sendMessage({ + type: 'save', + cfg + }); + } catch (ex) { + err(ex); + isvalid = false; + } finally { + if (isvalid) { + dom.cl.remove(evt.target, 'mujs-invalid'); + dom.prop(savebtn, 'disabled', false); + } else { + dom.cl.add(evt.target, 'mujs-invalid'); + dom.prop(savebtn, 'disabled', true); + } + } + } + }); + cfgMap.set(k, inp); + lb.append(inp); + sections.theme.append(lb); } - makerow('Greasy Fork', 'checkbox', 'greasyfork'); - makerow('Sleazy Fork', 'checkbox', 'sleazyfork'); - makerow('Open UserJS', 'checkbox', 'openuserjs'); - makerow('GitHub API', 'checkbox', 'github'); - const ghAPI = cfg.engines.find((c) => c.name === 'github'); - const ghToken = makerow('GitHub API (Token)', 'text', 'github', { - defaultValue: '', - value: ghAPI.token ?? '', - placeholder: 'Paste Access Token', - onchange(evt) { - MUJS.unsaved = true; - MUJS.rebuild = true; - ghAPI.token = evt.target.value; - hermes.send('Save', { - prop: 'engines', - value: cfg.engines - }); + const createList = (key, v = '', disabled = false, type = 'String') => { + let txt = key; + if (typeof key === 'string') { + if (key.startsWith('userjs-')) { + disabled = true; + const s = key.substring(7); + txt = `Built-in "${s}"`; + v = builtinList[s]; + } + } else { + if (!key.enabled) { + return; + } } - }); - ghToken.dataset.engine = 'github-token'; - cfgMap.set('github-token', ghToken); - const cbtn = make('mu-js', 'mujs-sty-flex'); - const savebtn = make('mujs-btn', 'save', { - textContent: i18n$('save'), - dataset: { - command: 'save' - }, - disabled: false - }); - const resetbtn = make('mujs-btn', 'reset', { - textContent: i18n$('reset'), - dataset: { - command: 'reset' + if (isRegExp(v)) { + v = v.toString(); + type = 'RegExp'; + } else { + v = JSON.stringify(v); + type = 'Object'; } - }); - const blacklist = make('textarea', '', { - dataset: { - name: 'blacklist' - }, - rows: '10', - autocomplete: false, - spellcheck: false, - wrap: 'soft', - value: JSON.stringify(cfg.blacklist, null, ' '), - oninput(evt) { - let isvalid = true; - try { - cfg.blacklist = JSON.parse(evt.target.value); - isvalid = true; - } catch (ex) { - err(ex); - isvalid = false; - } finally { - if (isvalid) { - dom.cl.remove(evt.target, 'mujs-invalid'); - dom.prop(savebtn, 'disabled', false); - } else { - dom.cl.add(evt.target, 'mujs-invalid'); - dom.prop(savebtn, 'disabled', true); - } + + const lb = make('label', 'hidden', { + textContent: txt, + dataset: { + blacklist: key } - } - }); - const theme = make('textarea', '', { - dataset: { - name: 'theme' - }, - rows: '10', - autocomplete: false, - spellcheck: false, - wrap: 'soft', - value: JSON.stringify(cfg.theme, null, ' '), - oninput(evt) { - let isvalid = true; - try { - cfg.theme = JSON.parse(evt.target.value); - isvalid = true; - renderTheme(JSON.parse(evt.target.value)); - } catch (ex) { - err(ex); - isvalid = false; - } finally { - if (isvalid) { - dom.cl.remove(evt.target, 'mujs-invalid'); - dom.prop(savebtn, 'disabled', false); - } else { - dom.cl.add(evt.target, 'mujs-invalid'); - dom.prop(savebtn, 'disabled', true); + }); + const inp = make('input', { + type: 'text', + defaultValue: '', + value: v ?? '', + placeholder: v ?? '', + dataset: { + blacklist: key + }, + onchange(evt) { + let isvalid = true; + try { + const val = evt.target.value; + if (isEmpty(val)) { + return; + } + isvalid = true; + } catch (ex) { + err(ex); + isvalid = false; + } finally { + if (isvalid) { + dom.cl.remove(evt.target, 'mujs-invalid'); + dom.prop(savebtn, 'disabled', false); + } else { + dom.cl.add(evt.target, 'mujs-invalid'); + dom.prop(savebtn, 'disabled', true); + } } } + }); + const selType = make('select', { + disabled, + dataset: { + blacklist: key + } + }); + if (disabled) { + inp.readOnly = true; + const o = make('option', { + value: type, + textContent: type + }); + selType.append(o); + } else { + for (const selV of ['String', 'RegExp', 'Object']) { + const o = make('option', { + value: selV, + textContent: selV + }); + selType.append(o); + } } - }); - cfgMap.set('blacklist', blacklist); - cfgMap.set('theme', theme); - cbtn.append(resetbtn, savebtn); - cfgpage.append(blacklist, theme, cbtn); -}; -//#endregion - -const locSearch = location.search; + selType.value = type; + lb.append(inp, selType); + sections.blacklist.append(lb); + }; + for (const key of cfg.blacklist) { + createList(key); + } -const p = hermes.getPort(); -p.onMessage.addListener((root = {}) => { - const m = root.msg; - if (root.channel === 'Config' && isEmpty(cfg)) { - cfg = m.cfg || cfg; - for (const engine of cfg.engines) { - MUJS.counters[engine.name] = 0; - if (!engine.enabled) { - continue; - } - const counter = make('count-frame', '', { + const transfers = { + export: { + cfg: make('mujs-btn', 'mujs-export sub-section hidden', { + textContent: i18n$('export_config'), dataset: { - counter: engine.name - }, - title: engine.url, - textContent: '0' - }); - qs('.counter-container').append(counter); + command: 'export-cfg', + exp: 'export-cfg' + } + }), + theme: make('mujs-btn', 'mujs-export sub-section hidden', { + textContent: i18n$('export_theme'), + dataset: { + command: 'export-theme', + exp: 'export-theme' + } + }) + }, + import: { + cfg: make('mujs-btn', 'mujs-import sub-section hidden', { + textContent: i18n$('import_config'), + dataset: { + command: 'import-cfg', + exp: 'import-cfg' + } + }), + theme: make('mujs-btn', 'mujs-import sub-section hidden', { + textContent: i18n$('import_theme'), + dataset: { + command: 'import-theme', + exp: 'import-theme' + } + }) } - makecfg(); - if (/mujs=/.test(locSearch)) { - if (/settings/.test(locSearch)) { - tab.create('mujs:settings'); - } + }; + for (const value of Object.values(transfers)) { + for (const v of Object.values(value)) { + sections.exp.append(v); } } -}); -function primaryFN(data) { + cfgpage.append(cbtn); +}; +// #endregion + +async function init() { + const [tab] = await webext.tabs.query({ + active: true, + currentWindow: true + }); + const data = []; + if (tab instanceof Object === false) { + return true; + } + Object.assign(currentTab, tab); + let url; try { - if (isEmpty(data)) { - tab.create(); - return; - } - for (const tabData of data) { - const { engine, host } = tabData; - if (MUJS.checkBlacklist(host)) { - continue; - } - if (!qs(`mujs-tab[data-host="${host}"]`)) { - tab.create(host); - if (tabData.link) { - MUJS.setHost(tabData.link); - } + url = new URL(currentTab.url); + tabURL.href = url.href || ''; + } catch (ex) { + err(ex); + } + + if (url !== undefined) { + const hostname = formatURL(normalizedHostname(tabURL.hostname)); + const response = await sendMessage({ + init: true, + type: 'getData', + currentTab, + hostname + }); + if (response instanceof Object) { + Object.assign(cfg, response.cfg ?? DEFAULT_CONFIG); + if (Array.isArray(response.data)) { + data.push(...response.data); } - if (tabData.data) { - for (const ujs of tabData.data) { - createjs(ujs, engine.name); + container.initFn(); + makecfg(); + MUList.cfg = cfg; + MUList.engines = cfg.engines; + if (params.has('mujs', 'settings')) { + Tabs.create('mujs:settings'); + } else if (params.has('host')) { + const host = params.get('host'); + Tabs.create(host); + if (!host.startsWith(Tabs.protocal)) { + MUList.host = host; + MUList.build(data); } - MUJS.updateCounter(tabData.data.length, engine); + } else if (!url.origin.startsWith('https://')) { + Tabs.create(); + } else { + Tabs.create(hostname); + MUList.host = hostname; + MUList.build(data); } } - urlBar.placeholder = i18n$('search_placeholder'); - urlBar.value = ''; - } catch (ex) { - err(ex); } } -if (!/mujs=/.test(locSearch)) { - webext.runtime.sendMessage({}, primaryFN); +async function tryInit() { + try { + await init(); + } catch { + setTimeout(tryInit, 100); + } } + +tryInit(); diff --git a/src/js/punycode.js b/src/js/punycode.js new file mode 100644 index 0000000..a7f990d --- /dev/null +++ b/src/js/punycode.js @@ -0,0 +1,493 @@ +/*! https://mths.be/punycode v1.3.2 by @mathias */ +export default (function() { + /** + * The `punycode` object. + * @name punycode + * @type Object + */ + var punycode, + + /** Highest positive signed 32-bit float value */ + maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 + + /** Bootstring parameters */ + base = 36, + tMin = 1, + tMax = 26, + skew = 38, + damp = 700, + initialBias = 72, + initialN = 128, // 0x80 + delimiter = '-', // '\x2D' + + /** Regular expressions */ + regexPunycode = /^xn--/, + regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars + regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators + + /** Error messages */ + errors = { + 'overflow': 'Overflow: input needs wider integers to process', + 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', + 'invalid-input': 'Invalid input' + }, + + /** Convenience shortcuts */ + baseMinusTMin = base - tMin, + floor = Math.floor, + stringFromCharCode = String.fromCharCode, + + /** Temporary variable */ + key; + + /*--------------------------------------------------------------------------*/ + + /** + * A generic error utility function. + * @private + * @param {String} type The error type. + * @returns {Error} Throws a `RangeError` with the applicable error message. + */ + function error(type) { + throw new RangeError(errors[type]); + } + + /** + * A generic `Array#map` utility function. + * @private + * @param {Array} array The array to iterate over. + * @param {Function} callback The function that gets called for every array + * item. + * @returns {Array} A new array of values returned by the callback function. + */ + function map(array, fn) { + var length = array.length; + var result = []; + while (length--) { + result[length] = fn(array[length]); + } + return result; + } + + /** + * A simple `Array#map`-like wrapper to work with domain name strings or email + * addresses. + * @private + * @param {String} domain The domain name or email address. + * @param {Function} callback The function that gets called for every + * character. + * @returns {Array} A new string of characters returned by the callback + * function. + */ + function mapDomain(string, fn) { + var parts = string.split('@'); + var result = ''; + if (parts.length > 1) { + // In email addresses, only the domain name should be punycoded. Leave + // the local part (i.e. everything up to `@`) intact. + result = parts[0] + '@'; + string = parts[1]; + } + // Avoid `split(regex)` for IE8 compatibility. See #17. + string = string.replace(regexSeparators, '\x2E'); + var labels = string.split('.'); + var encoded = map(labels, fn).join('.'); + return result + encoded; + } + + /** + * Creates an array containing the numeric code points of each Unicode + * character in the string. While JavaScript uses UCS-2 internally, + * this function will convert a pair of surrogate halves (each of which + * UCS-2 exposes as separate characters) into a single code point, + * matching UTF-16. + * @see `punycode.ucs2.encode` + * @see + * @memberOf punycode.ucs2 + * @name decode + * @param {String} string The Unicode input string (UCS-2). + * @returns {Array} The new array of code points. + */ + function ucs2decode(string) { + var output = [], + counter = 0, + length = string.length, + value, + extra; + while (counter < length) { + value = string.charCodeAt(counter++); + if (value >= 0xD800 && value <= 0xDBFF && counter < length) { + // high surrogate, and there is a next character + extra = string.charCodeAt(counter++); + if ((extra & 0xFC00) == 0xDC00) { // low surrogate + output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); + } else { + // unmatched surrogate; only append this code unit, in case the next + // code unit is the high surrogate of a surrogate pair + output.push(value); + counter--; + } + } else { + output.push(value); + } + } + return output; + } + + /** + * Creates a string based on an array of numeric code points. + * @see `punycode.ucs2.decode` + * @memberOf punycode.ucs2 + * @name encode + * @param {Array} codePoints The array of numeric code points. + * @returns {String} The new Unicode string (UCS-2). + */ + function ucs2encode(array) { + return map(array, function(value) { + var output = ''; + if (value > 0xFFFF) { + value -= 0x10000; + output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); + value = 0xDC00 | value & 0x3FF; + } + output += stringFromCharCode(value); + return output; + }).join(''); + } + + /** + * Converts a basic code point into a digit/integer. + * @see `digitToBasic()` + * @private + * @param {Number} codePoint The basic numeric code point value. + * @returns {Number} The numeric value of a basic code point (for use in + * representing integers) in the range `0` to `base - 1`, or `base` if + * the code point does not represent a value. + */ + function basicToDigit(codePoint) { + if (codePoint - 48 < 10) { + return codePoint - 22; + } + if (codePoint - 65 < 26) { + return codePoint - 65; + } + if (codePoint - 97 < 26) { + return codePoint - 97; + } + return base; + } + + /** + * Converts a digit/integer into a basic code point. + * @see `basicToDigit()` + * @private + * @param {Number} digit The numeric value of a basic code point. + * @returns {Number} The basic code point whose value (when used for + * representing integers) is `digit`, which needs to be in the range + * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is + * used; else, the lowercase form is used. The behavior is undefined + * if `flag` is non-zero and `digit` has no uppercase form. + */ + function digitToBasic(digit, flag) { + // 0..25 map to ASCII a..z or A..Z + // 26..35 map to ASCII 0..9 + return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); + } + + /** + * Bias adaptation function as per section 3.4 of RFC 3492. + * http://tools.ietf.org/html/rfc3492#section-3.4 + * @private + */ + function adapt(delta, numPoints, firstTime) { + var k = 0; + delta = firstTime ? floor(delta / damp) : delta >> 1; + delta += floor(delta / numPoints); + for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { + delta = floor(delta / baseMinusTMin); + } + return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); + } + + /** + * Converts a Punycode string of ASCII-only symbols to a string of Unicode + * symbols. + * @memberOf punycode + * @param {String} input The Punycode string of ASCII-only symbols. + * @returns {String} The resulting string of Unicode symbols. + */ + function decode(input) { + // Don't use UCS-2 + var output = [], + inputLength = input.length, + out, + i = 0, + n = initialN, + bias = initialBias, + basic, + j, + index, + oldi, + w, + k, + digit, + t, + /** Cached calculation results */ + baseMinusT; + + // Handle the basic code points: let `basic` be the number of input code + // points before the last delimiter, or `0` if there is none, then copy + // the first basic code points to the output. + + basic = input.lastIndexOf(delimiter); + if (basic < 0) { + basic = 0; + } + + for (j = 0; j < basic; ++j) { + // if it's not a basic code point + if (input.charCodeAt(j) >= 0x80) { + error('not-basic'); + } + output.push(input.charCodeAt(j)); + } + + // Main decoding loop: start just after the last delimiter if any basic code + // points were copied; start at the beginning otherwise. + + for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { + + // `index` is the index of the next character to be consumed. + // Decode a generalized variable-length integer into `delta`, + // which gets added to `i`. The overflow checking is easier + // if we increase `i` as we go, then subtract off its starting + // value at the end to obtain `delta`. + for (oldi = i, w = 1, k = base; /* no condition */; k += base) { + + if (index >= inputLength) { + error('invalid-input'); + } + + digit = basicToDigit(input.charCodeAt(index++)); + + if (digit >= base || digit > floor((maxInt - i) / w)) { + error('overflow'); + } + + i += digit * w; + t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + + if (digit < t) { + break; + } + + baseMinusT = base - t; + if (w > floor(maxInt / baseMinusT)) { + error('overflow'); + } + + w *= baseMinusT; + + } + + out = output.length + 1; + bias = adapt(i - oldi, out, oldi == 0); + + // `i` was supposed to wrap around from `out` to `0`, + // incrementing `n` each time, so we'll fix that now: + if (floor(i / out) > maxInt - n) { + error('overflow'); + } + + n += floor(i / out); + i %= out; + + // Insert `n` at position `i` of the output + output.splice(i++, 0, n); + + } + + return ucs2encode(output); + } + + /** + * Converts a string of Unicode symbols (e.g. a domain name label) to a + * Punycode string of ASCII-only symbols. + * @memberOf punycode + * @param {String} input The string of Unicode symbols. + * @returns {String} The resulting Punycode string of ASCII-only symbols. + */ + function encode(input) { + var n, + delta, + handledCPCount, + basicLength, + bias, + j, + m, + q, + k, + t, + currentValue, + output = [], + /** `inputLength` will hold the number of code points in `input`. */ + inputLength, + /** Cached calculation results */ + handledCPCountPlusOne, + baseMinusT, + qMinusT; + + // Convert the input in UCS-2 to Unicode + input = ucs2decode(input); + + // Cache the length + inputLength = input.length; + + // Initialize the state + n = initialN; + delta = 0; + bias = initialBias; + + // Handle the basic code points + for (j = 0; j < inputLength; ++j) { + currentValue = input[j]; + if (currentValue < 0x80) { + output.push(stringFromCharCode(currentValue)); + } + } + + handledCPCount = basicLength = output.length; + + // `handledCPCount` is the number of code points that have been handled; + // `basicLength` is the number of basic code points. + + // Finish the basic string - if it is not empty - with a delimiter + if (basicLength) { + output.push(delimiter); + } + + // Main encoding loop: + while (handledCPCount < inputLength) { + + // All non-basic code points < n have been handled already. Find the next + // larger one: + for (m = maxInt, j = 0; j < inputLength; ++j) { + currentValue = input[j]; + if (currentValue >= n && currentValue < m) { + m = currentValue; + } + } + + // Increase `delta` enough to advance the decoder's state to , + // but guard against overflow + handledCPCountPlusOne = handledCPCount + 1; + if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { + error('overflow'); + } + + delta += (m - n) * handledCPCountPlusOne; + n = m; + + for (j = 0; j < inputLength; ++j) { + currentValue = input[j]; + + if (currentValue < n && ++delta > maxInt) { + error('overflow'); + } + + if (currentValue == n) { + // Represent delta as a generalized variable-length integer + for (q = delta, k = base; /* no condition */; k += base) { + t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); + if (q < t) { + break; + } + qMinusT = q - t; + baseMinusT = base - t; + output.push( + stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) + ); + q = floor(qMinusT / baseMinusT); + } + + output.push(stringFromCharCode(digitToBasic(q, 0))); + bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); + delta = 0; + ++handledCPCount; + } + } + + ++delta; + ++n; + + } + return output.join(''); + } + + /** + * Converts a Punycode string representing a domain name or an email address + * to Unicode. Only the Punycoded parts of the input will be converted, i.e. + * it doesn't matter if you call it on a string that has already been + * converted to Unicode. + * @memberOf punycode + * @param {String} input The Punycoded domain name or email address to + * convert to Unicode. + * @returns {String} The Unicode representation of the given Punycode + * string. + */ + function toUnicode(input) { + return mapDomain(input, function(string) { + return regexPunycode.test(string) + ? decode(string.slice(4).toLowerCase()) + : string; + }); + } + + /** + * Converts a Unicode string representing a domain name or an email address to + * Punycode. Only the non-ASCII parts of the domain name will be converted, + * i.e. it doesn't matter if you call it with a domain that's already in + * ASCII. + * @memberOf punycode + * @param {String} input The domain name or email address to convert, as a + * Unicode string. + * @returns {String} The Punycode representation of the given domain name or + * email address. + */ + function toASCII(input) { + return mapDomain(input, function(string) { + return regexNonASCII.test(string) + ? 'xn--' + encode(string) + : string; + }); + } + + /*--------------------------------------------------------------------------*/ + + /** Define the public API */ + punycode = { + /** + * A string representing the current Punycode.js version number. + * @memberOf punycode + * @type String + */ + 'version': '1.3.2', + /** + * An object of methods to convert from JavaScript's internal character + * representation (UCS-2) to Unicode code points, and back. + * @see + * @memberOf punycode + * @type Object + */ + 'ucs2': { + 'decode': ucs2decode, + 'encode': ucs2encode + }, + 'decode': decode, + 'encode': encode, + 'toASCII': toASCII, + 'toUnicode': toUnicode + }; + + return punycode; +})(); diff --git a/src/js/querySelector.js b/src/js/querySelector.js index a2e5376..3a0dc90 100644 --- a/src/js/querySelector.js +++ b/src/js/querySelector.js @@ -57,7 +57,7 @@ const SafeAnimationFrame = class { } }; /** - * @type { import("../typings/types").isElem } + * @type { import("../typings/types.d.ts").isElem } */ const isElem = (obj) => { /** @type { string } */ @@ -65,7 +65,7 @@ const isElem = (obj) => { return s.includes('Element'); }; /** - * @type { import("../typings/types").normalizeTarget } + * @type { import("../typings/types.d.ts").normalizeTarget } */ const normalizeTarget = (target, toQuery = true, root) => { if (Object.is(target, null) || Object.is(target, undefined)) { @@ -320,7 +320,7 @@ dom.cl = class { /******************************************************************************/ /** - * @type { import("../typings/types").qsA } + * @type { import("../typings/types.d.ts").qsA } */ const qsA = (selectors, root) => { try { @@ -331,7 +331,7 @@ const qsA = (selectors, root) => { return []; }; /** - * @type { import("../typings/types").qs } + * @type { import("../typings/types.d.ts").qs } */ const qs = (selector, root) => { try { @@ -343,7 +343,7 @@ const qs = (selector, root) => { }; /** - * @type { import("../typings/WebExt").query } + * @type { import("../typings/WebExt.d.ts").query } */ const query = async (selector, root) => { let el = null; diff --git a/src/js/request-code.js b/src/js/request-code.js index e4fac3e..0dc3a92 100644 --- a/src/js/request-code.js +++ b/src/js/request-code.js @@ -1,11 +1,9 @@ 'use strict'; +import { err } from './logger.js'; import Network from './network.js'; -import { intersect, isNull, isEmpty, normalizeTarget } from './util.js'; -import { language } from './language.js'; +import { isNull, isBlank, isEmpty, union } from './util.js'; -const META_START_COMMENT = '// ==UserScript=='; -const META_END_COMMENT = '// ==/UserScript=='; const TLD_EXPANSION = ['com', 'net', 'org', 'de', 'co.uk']; const APPLIES_TO_ALL_PATTERNS = [ 'http://*', @@ -19,237 +17,303 @@ const APPLIES_TO_ALL_PATTERNS = [ '*://*/*', 'http*' ]; -/** - * @param { string } code - */ -const get_meta_block = (code) => { - if (isEmpty(code)) { - return null; - } - const start_block = code.indexOf(META_START_COMMENT); - if (isNull(start_block)) { - return null; - } - const end_block = code.indexOf(META_END_COMMENT, start_block); - if (isNull(end_block)) { - return null; - } - return code.substring(start_block + META_START_COMMENT.length, end_block); -}; -/** - * @param { string } code - */ -const parse_meta = (code) => { - if (isEmpty(code)) { - return null; - } - const meta = {}; - const meta_block = get_meta_block(code); - const meta_block_map = new Map(); - for (const meta_line of meta_block.split('\n')) { - const meta_match = meta_line.match(/\/\/\s+@([a-zA-Z:-]+)\s+(.*)/); - if (isNull(meta_match)) { - continue; - } - const key = meta_match[1].trim(); - const value = meta_match[2].trim(); - if (!meta_block_map.has(key)) { - meta_block_map.set(key, []); - } - const meta_map = meta_block_map.get(key); - meta_map.push(value); - meta_block_map.set(key, meta_map); +class ParseUserJS { + /** + * @type { string } + */ + code; + /** + * @type { string } + */ + data_meta_block; + /** + * @type { string } + */ + data_code_block; + /** + * @type { { [meta: string]: string | string[] | { [resource: string]: string } } } + */ + data_meta; + /** + * @type { {text: string;domain: boolean;tld_extra: boolean}[] } + */ + data_names; + constructor(code, isUserCSS) { + this.META_START_COMMENT = isUserCSS ? '/* ==UserStyle==' : '// ==UserScript=='; + this.META_END_COMMENT = isUserCSS ? '==/UserStyle== */' : '// ==/UserScript=='; + if (code) { + this.code = code; + this.get_meta_block(); + this.get_code_block(); + this.parse_meta(); + this.calculate_applies_to_names(); + } } - for (const [key, value] of meta_block_map) { - if (value.length > 1) { - meta[key] = value; - } else { - meta[key] = value[0]; + get_meta_block() { + if (isEmpty(this.code)) { + return null; + } + if (this.data_meta_block) { + return this.data_meta_block; + } + const start_block = this.code.indexOf(this.META_START_COMMENT); + if (isNull(start_block)) { + return null; + } + const end_block = this.code.indexOf(this.META_END_COMMENT, start_block); + if (isNull(end_block)) { + return null; } + const meta_block = this.code.substring(start_block + this.META_START_COMMENT.length, end_block); + this.data_meta_block = meta_block; + return this.data_meta_block; } - return meta; -}; -/** - * @template { string } S - * @param { S } code - * @returns { S[] } - */ -const calculate_applies_to_names = (code) => { - if (isEmpty(code)) { - return null; + get_code_block() { + if (isEmpty(this.code)) { + return null; + } + if (this.data_code_block) { + return this.data_code_block; + } + const start_block = this.code.indexOf(this.META_START_COMMENT); + if (isNull(start_block)) { + return null; + } + const end_block = this.code.indexOf(this.META_END_COMMENT, start_block); + if (isNull(end_block)) { + return null; + } + const code_block = this.code.substring( + end_block + this.META_END_COMMENT.length, + this.code.length + ); + this.data_code_block = code_block + .split('\n') + .filter((l) => !isEmpty(l)) + .join('\n'); + return this.data_code_block; } - const meta = parse_meta(code); - let patterns = []; - for (const [k, v] of Object.entries(meta)) { - if (/include|match/.test(k)) { - if (Array.isArray(v)) { - patterns = patterns.concat(v); + parse_meta() { + if (isEmpty(this.code)) { + return null; + } + if (this.data_meta) { + return this.data_meta; + } + const meta = {}; + const meta_block_map = new Map(); + for (const meta_line of this.get_meta_block().split('\n')) { + const meta_match = /\/\/\s+@([a-zA-Z:-]+)\s+(.*)/.exec(meta_line); + if (!meta_match) { + continue; + } + const key = meta_match[1].trim(); + const value = meta_match[2].trim(); + if (!meta_block_map.has(key)) { + meta_block_map.set(key, []); + } + const meta_map = meta_block_map.get(key); + meta_map.push(value); + meta_block_map.set(key, meta_map); + } + for (const [key, value] of meta_block_map) { + if (value.length > 1) { + meta[key] = value; } else { - patterns = patterns.concat([v]); + meta[key] = value[0]; } } + this.data_meta = meta; + return this.data_meta; } - if (isEmpty(patterns)) { - return []; - } - if (intersect(patterns, APPLIES_TO_ALL_PATTERNS)) { - return []; - } - const name_set = new Set(); - const addObj = (obj) => { - if (name_set.has(obj)) { - return; - } - name_set.add(obj); - }; - for (let p of patterns) { - try { - const original_pattern = p; - let pre_wildcards = []; - if (p.match(/^\/(.*)\/$/)) { - pre_wildcards = [p]; - } else { - let m = p.match(/^\*(https?:.*)/i); - if (!isNull(m)) { - p = m[1]; - } - p = p - .replace(/^\*:/i, 'http:') - .replace(/^\*\/\//i, 'http://') - .replace(/^http\*:/i, 'http:') - .replace(/^(https?):([^/])/i, '$1://$2'); - m = p.match(/^([a-z]+:\/\/)\*\.?([a-z0-9-]+(?:.[a-z0-9-]+)+.*)/i); - if (!isNull(m)) { - p = m[1] + m[2]; - } - m = p.match(/^\*\.?([a-z0-9-]+\.[a-z0-9-]+.*)/i); - if (!isNull(m)) { - p = `http://${m[1]}`; + calculate_applies_to_names() { + if (isEmpty(this.code)) { + return null; + } + if (this.data_names) { + return this.data_names; + } + let patterns = []; + for (const [k, v] of Object.entries(this.parse_meta())) { + if (/include|match/i.test(k)) { + if (Array.isArray(v)) { + patterns = patterns.concat(v); + } else { + patterns = patterns.concat([v]); } - m = p.match(/^http\*(?:\/\/)?\.?((?:[a-z0-9-]+)(?:\.[a-z0-9-]+)+.*)/i); - if (!isNull(m)) { - p = `http://${m[1]}`; + } + } + if (isEmpty(patterns)) { + return []; + } + if (this.intersect(patterns, APPLIES_TO_ALL_PATTERNS)) { + this.data_names = [ + { + domain: false, + text: 'All sites', + tld_extra: false } - m = p.match(/^([a-z]+:\/\/([a-z0-9-]+(?:\.[a-z0-9-]+)*\.))\*(.*)/); - if (!isNull(m)) { - if (m[2].match(/A([0-9]+\.){2,}z/)) { - p = `${m[1]}tld${m[3]}`; - pre_wildcards = [p.split('*')[0]]; + ]; + return this.data_names; + } + this.data_names = ParseUserJS.getNames(patterns); + return this.data_names; + } + intersect(a, ...arr) { + return !isBlank([...new Set(a)].filter((v) => arr.every((b) => b.includes(v)))); + } + static getNames(patterns = []) { + const name_map = new Map(); + const addObj = (obj) => { + if (name_map.has(obj.text)) { + return; + } + name_map.set(obj.text, obj); + }; + for (let p of patterns) { + try { + const original_pattern = p; + let pre_wildcards = []; + if (p.match(/^\/(.*)\/$/)) { + pre_wildcards = [p]; + } else { + let m = /^\*(https?:.*)/i.exec(p); + if (m) { + p = m[1]; + } + p = p + .replace(/^\*:/i, 'http:') + .replace(/^\*\/\//i, 'http://') + .replace(/^http\*:/i, 'http:') + .replace(/^(https?):([^/])/i, '$1://$2'); + m = /^([a-z]+:\/\/)\*\.?([a-z0-9-]+(?:.[a-z0-9-]+)+.*)/i.exec(p); + if (m) { + p = m[1] + m[2]; + } + m = /^\*\.?([a-z0-9-]+\.[a-z0-9-]+.*)/i.exec(p); + if (m) { + p = `http://${m[1]}`; + } + m = /^http\*(?:\/\/)?\.?((?:[a-z0-9-]+)(?:\.[a-z0-9-]+)+.*)/i.exec(p); + if (m) { + p = `http://${m[1]}`; + } + m = /^([a-z]+:\/\/([a-z0-9-]+(?:\.[a-z0-9-]+)*\.))\*(.*)/.exec(p); + if (m) { + if (m[2].match(/A([0-9]+\.){2,}z/)) { + p = `${m[1]}tld${m[3]}`; + pre_wildcards = [p.split('*')[0]]; + } else { + pre_wildcards = [p]; + } } else { pre_wildcards = [p]; } - } else { - pre_wildcards = [p]; } - } - for (const pre_wildcard of pre_wildcards) { - try { - const uri = new URL(pre_wildcard); - if (isNull(uri.host)) { - addObj({ text: original_pattern, domain: false, tld_extra: false }); - } else if (!uri.host.includes('.') && uri.host.includes('*')) { - addObj({ text: original_pattern, domain: false, tld_extra: false }); - } else if (uri.host.endsWith('.tld')) { - for (let i = 0; i < TLD_EXPANSION.length; i++) { - const tld = TLD_EXPANSION[i]; + for (const pre_wildcard of pre_wildcards) { + try { + const urlObj = new URL(pre_wildcard); + const { host } = urlObj; + if (isNull(host)) { + addObj({ text: original_pattern, domain: false, tld_extra: false }); + } else if (!host.includes('.') && host.includes('*')) { + addObj({ text: original_pattern, domain: false, tld_extra: false }); + } else if (host.endsWith('.tld')) { + for (let i = 0; i < TLD_EXPANSION.length; i++) { + const tld = TLD_EXPANSION[i]; + addObj({ + text: host.replace(/tld$/i, tld), + domain: true, + tld_extra: i != 0 + }); + } + } else if (host.endsWith('.')) { addObj({ - text: uri.host.replace(/tld$/i, tld), + text: host.slice(0, -1), domain: true, - tld_extra: i != 0 + tld_extra: false + }); + } else { + addObj({ + text: host, + domain: true, + tld_extra: false }); } - } else if (uri.host.endsWith('.')) { - addObj({ - text: uri.host.slice(0, -1), - domain: true, - tld_extra: false - }); - } else { - addObj({ - text: uri.host, - domain: true, - tld_extra: false - }); + // eslint-disable-next-line no-unused-vars + } catch (ex) { + addObj({ text: original_pattern, domain: false, tld_extra: false }); } - // eslint-disable-next-line no-unused-vars - } catch (error) { - addObj({ text: original_pattern, domain: false, tld_extra: false }); } + } catch (ex) { + err(ex); } - } catch (ex) { - console.error(ex); } + return [...name_map.values()]; } - return [...name_set]; -}; -const reqCode = async (obj = {}, translate = false) => { - if (obj.code_data) { - return obj.code_data; - } - /** @type { string } */ - const code = await Network.req(obj.code_url, 'GET', 'text'); - if (typeof code !== 'string') { - return; - } - Object.assign(obj, { - code_data: code, - code_meta: {}, - code_size: [Network.format(code.length)], - code_match: [], - code_grant: [], - antifeatures: [] - }); - const grantSet = new Set(); - const afSet = new Set(); - const meta = parse_meta(code); - const applies_to_names = calculate_applies_to_names(code); - - if (translate) { - for (const lng of language.cache) { - if (meta[`name:${lng}`]) { - Object.assign(obj, { - name: meta[`name:${lng}`], - translated: true - }); - } - if (meta[`description:${lng}`]) { - Object.assign(obj, { - description: meta[`description:${lng}`], - translated: true - }); - } + async request(translate = false, code_url, obj) { + if (this.data_code_block) { + return this; } - } + /** @type { string } */ + const code = await Network.req(code_url, 'GET', 'text').catch(err); + if (typeof code !== 'string') { + return this; + } + const isUserCSS = /\.user\.css/.test(code_url); - for (const [key, value] of Object.entries(meta)) { - if (/grant/.test(key)) { - for (const v of normalizeTarget(value, false)) { - if (grantSet.has(v)) { - continue; + this.META_START_COMMENT = isUserCSS ? '/* ==UserStyle==' : '// ==UserScript=='; + this.META_END_COMMENT = isUserCSS ? '==/UserStyle== */' : '// ==/UserScript=='; + this.code = code; + this.get_meta_block(); + this.get_code_block(); + this.parse_meta(); + this.calculate_applies_to_names(); + + const { data_meta } = this; + if (translate) { + for (const k of userjs.pool.keys()) { + if (data_meta[`name:${k}`]) { + Object.assign(obj, { + name: data_meta[`name:${k}`] + }); + this.translated = true; + } + if (data_meta[`description:${k}`]) { + Object.assign(obj, { + description: data_meta[`description:${k}`] + }); + this.translated = true; } - grantSet.add(v); } - } else if (/antifeature/.test(key)) { - for (const v of normalizeTarget(value, false)) { - if (afSet.has(v)) { - continue; + } + if (Array.isArray(data_meta.grant)) { + data_meta.grant = union(data_meta.grant); + } + if (data_meta.resource) { + const obj = {}; + if (typeof data_meta.resource === 'string') { + const reg = /(.+)\s+(.+)/.exec(data_meta.resource); + if (reg) { + obj[reg[1].trim()] = reg[2]; + } + } else { + for (const r of data_meta.resource) { + const reg = /(.+)\s+(http.+)/.exec(r); + if (reg) { + obj[reg[1].trim()] = reg[2]; + } } - afSet.add(v); } + data_meta.resource = obj; } + Object.assign(this, { + code_size: [Network.format(code.length)], + meta: data_meta + }); + + return this; } - Object.assign(obj, { - code_meta: meta, - code_match: applies_to_names, - code_grant: [...grantSet], - antifeatures: [...afSet] - }); - return code; -}; +} -export { - calculate_applies_to_names, - get_meta_block, - parse_meta, - reqCode -} \ No newline at end of file +export { ParseUserJS }; diff --git a/src/js/settings.js b/src/js/settings.js deleted file mode 100644 index c4d51cc..0000000 --- a/src/js/settings.js +++ /dev/null @@ -1,294 +0,0 @@ -'use strict'; -import { err } from './logger.js'; -import { XMap } from './XMap.js'; -import { i18n$ } from './i18n.js'; -import { dom, qs } from './querySelector.js'; -import { ael, make, isNull, isEmpty } from './util.js'; - -let cfg = {}; - -const { hermes } = userjs; - -const renderTheme = (theme) => { - theme = theme || cfg.theme; - if (isEmpty(theme)) { - return; - } - // if (theme === defcfg.theme) { - // return; - // } - const sty = qs('mujs-root').style; - for (const [k, v] of Object.entries(theme)) { - const str = `--mujs-${k}`; - const prop = sty.getPropertyValue(str); - if (isEmpty(v)) { - theme[k] = prop; - } - if (prop === v) { - continue; - } - sty.removeProperty(str); - sty.setProperty(str, v); - } -}; - -const cfgMap = new XMap(); - -//#region Make Config -const cfgpage = qs('form'); -const makecfg = () => { - const exBtn = make('mu-js', 'mujs-sty-flex'); - const exportCFG = make('mujs-btn', 'mujs-export', { - textContent: i18n$('export_config'), - dataset: { - command: 'export-cfg' - } - }); - const importCFG = make('mujs-btn', 'mujs-import', { - textContent: i18n$('import_config'), - dataset: { - command: 'import-cfg' - } - }); - const exportTheme = make('mujs-btn', 'mujs-export', { - textContent: i18n$('export_theme'), - dataset: { - command: 'export-theme' - } - }); - const importTheme = make('mujs-btn', 'mujs-import', { - textContent: i18n$('import_theme'), - dataset: { - command: 'import-theme' - } - }); - exBtn.append(importCFG, importTheme, exportCFG, exportTheme); - cfgpage.append(exBtn); - - const makerow = (desc, type = null, nm, attrs = {}) => { - desc = desc ?? i18n$('no_license'); - nm = nm ?? i18n$('no_license'); - const sec = make('mujs-section', 'mujs-cfg-section', { - style: nm === 'cache' ? 'display: none;' : '' - }); - const lb = make('label'); - const divDesc = make('mu-js', 'mujs-cfg-desc', { - textContent: desc - }); - lb.append(divDesc); - sec.append(lb); - cfgpage.append(sec); - if (isNull(type)) { - return lb; - } - const inp = make('input', 'mujs-cfg-input', { - type, - dataset: { - name: nm - }, - ...attrs - }); - if (!cfgMap.has(nm)) { - cfgMap.set(nm, inp); - } - if (type === 'checkbox') { - const inlab = make('mu-js', 'mujs-inlab'); - const la = make('label', '', { - onclick() { - inp.dispatchEvent(new MouseEvent('click')); - } - }); - inlab.append(inp, la); - lb.append(inlab); - if (nm.includes('-')) { - return inp; - } - if (/(greasy|sleazy)fork|openuserjs|gi(thub|st)/gi.test(nm)) { - for (const i of cfg.engines) { - if (i.name !== nm) continue; - inp.checked = i.enabled; - inp.dataset.engine = i.name; - ael(inp, 'change', (evt) => { - // MUJS.unsaved = true; - // MUJS.rebuild = true; - i.enabled = evt.target.checked; - hermes.send('Save', { - prop: 'engines', - value: cfg.engines - }); - }); - } - } else { - inp.checked = cfg[nm]; - ael(inp, 'change', (evt) => { - // MUJS.unsaved = true; - // if (/filterlang/i.test(nm)) { - // MUJS.rebuild = true; - // } - cfg[nm] = evt.target.checked; - hermes.send('Save', { - prop: nm, - value: cfg[nm] - }); - }); - } - } else { - lb.append(inp); - } - return inp; - }; - makerow('Sync with GM', 'checkbox', 'cache'); - makerow(i18n$('redirect'), 'checkbox', 'sleazyredirect'); - makerow(i18n$('filter'), 'checkbox', 'filterlang'); - makerow(i18n$('preview_code'), 'checkbox', 'codePreview'); - for (const inp of [ - makerow('Recommend author', 'checkbox', 'recommend-author'), - makerow('Recommend scripts', 'checkbox', 'recommend-others') - ]) { - const nm = inp.dataset.name === 'recommend-author' ? 'author' : 'others'; - inp.checked = cfg.recommend[nm]; - ael(inp, 'change', (evt) => { - // MUJS.unsaved = true; - cfg.recommend[nm] = evt.target.checked; - hermes.send('Save', { - prop: 'recommend', - value: cfg.recommend - }); - }); - } - makerow('Greasy Fork', 'checkbox', 'greasyfork'); - makerow('Sleazy Fork', 'checkbox', 'sleazyfork'); - makerow('Open UserJS', 'checkbox', 'openuserjs'); - makerow('GitHub API', 'checkbox', 'github'); - const ghAPI = cfg.engines.find((c) => c.name === 'github'); - const ghToken = makerow('GitHub API (Token)', 'text', 'github', { - defaultValue: '', - value: ghAPI.token ?? '', - placeholder: 'Paste Access Token' - // onchange(evt) { - // MUJS.unsaved = true; - // MUJS.rebuild = true; - // if (isNull(legacyMsg)) { - // ghAPI.token = evt.target.value; - // } - // } - }); - ghToken.dataset.engine = 'github-token'; - cfgMap.set('github-token', ghToken); - makerow(`${i18n$('dtime')} (ms)`, 'number', 'time', { - defaultValue: 10000, - value: cfg.time, - min: 0, - step: 500, - onbeforeinput(evt) { - if (evt.target.validity.badInput) { - dom.cl.add(evt.target, 'mujs-invalid'); - dom.prop(savebtn, 'disabled', true); - } else { - dom.cl.remove(evt.target, 'mujs-invalid'); - dom.prop(savebtn, 'disabled', false); - } - }, - oninput(evt) { - // MUJS.unsaved = true; - const t = evt.target; - if (t.validity.badInput || (t.validity.rangeUnderflow && t.value !== '-1')) { - dom.cl.add(t, 'mujs-invalid'); - dom.prop(savebtn, 'disabled', true); - } else { - dom.cl.remove(t, 'mujs-invalid'); - dom.prop(savebtn, 'disabled', false); - cfg.time = isEmpty(t.value) ? cfg.time : parseFloat(t.value); - } - } - }); - - const cbtn = make('mu-js', 'mujs-sty-flex'); - const savebtn = make('mujs-btn', 'save', { - textContent: i18n$('save'), - dataset: { - command: 'save' - }, - disabled: false - }); - const resetbtn = make('mujs-btn', 'reset', { - textContent: i18n$('reset'), - dataset: { - command: 'reset' - } - }); - const blacklist = make('textarea', '', { - dataset: { - name: 'blacklist' - }, - rows: '10', - autocomplete: false, - spellcheck: false, - wrap: 'soft', - value: JSON.stringify(cfg.blacklist, null, ' '), - oninput(evt) { - let isvalid = true; - try { - cfg.blacklist = JSON.parse(evt.target.value); - isvalid = true; - } catch (ex) { - err(ex); - isvalid = false; - } finally { - if (isvalid) { - dom.cl.remove(evt.target, 'mujs-invalid'); - dom.prop(savebtn, 'disabled', false); - } else { - dom.cl.add(evt.target, 'mujs-invalid'); - dom.prop(savebtn, 'disabled', true); - } - } - } - }); - const theme = make('textarea', '', { - dataset: { - name: 'theme' - }, - rows: '10', - autocomplete: false, - spellcheck: false, - wrap: 'soft', - value: JSON.stringify(cfg.theme, null, ' '), - oninput(evt) { - let isvalid = true; - try { - cfg.theme = JSON.parse(evt.target.value); - isvalid = true; - renderTheme(JSON.parse(evt.target.value)); - } catch (ex) { - err(ex); - isvalid = false; - } finally { - if (isvalid) { - dom.cl.remove(evt.target, 'mujs-invalid'); - dom.prop(savebtn, 'disabled', false); - } else { - dom.cl.add(evt.target, 'mujs-invalid'); - dom.prop(savebtn, 'disabled', true); - } - } - } - }); - cfgMap.set('blacklist', blacklist); - cfgMap.set('theme', theme); - cbtn.append(resetbtn, savebtn); - cfgpage.append(blacklist, theme, cbtn); -}; -//#endregion - -/** - * @type {chrome.runtime.Port | browser.runtime.Port | null} - */ -const p = hermes.getPort(); -p.onMessage.addListener((root = {}) => { - const m = root.msg; - if (root.channel === 'Config' && isEmpty(cfg)) { - cfg = m.cfg || cfg; - makecfg(); - } -}); diff --git a/src/js/storage.js b/src/js/storage.js index 3b990c6..19b5300 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -1,7 +1,117 @@ 'use strict'; +import { webext } from './ext.js'; + let api = webext.storage.local; +// #region DEFAULT_CONFIG +/** + * @type { import("../typings/types.d.ts").config } + */ +export const DEFAULT_CONFIG = { + autofetch: true, + // autoinject: true, + autoSort: 'daily_installs', + clearTabCache: true, + // cache: true, + // autoexpand: false, + filterlang: false, + sleazyredirect: false, + // time: 10000, + blacklist: ['userjs-local', 'userjs-finance', 'userjs-social', 'userjs-unsupported'], + preview: { + code: false, + metadata: false + }, + engines: [ + { + enabled: true, + name: 'greasyfork', + query: encodeURIComponent('https://greasyfork.org/scripts/by-site/{host}.json?language=all') + }, + { + enabled: false, + name: 'sleazyfork', + query: encodeURIComponent('https://sleazyfork.org/scripts/by-site/{host}.json?language=all') + }, + // { + // enabled: false, + // name: 'openuserjs', + // query: encodeURIComponent('https://openuserjs.org/?q={host}') + // }, + { + enabled: false, + name: 'github', + token: '', + query: encodeURIComponent( + 'https://api.github.com/search/code?q="// ==UserScript=="+{host}+ "// ==/UserScript=="+in:file+language:js&per_page=30' + ) + } + ], + theme: { + 'even-row': '', + 'odd-row': '', + 'even-err': '', + 'odd-err': '', + 'background-color': '', + 'gf-color': '', + 'sf-color': '', + 'border-b-color': '', + 'gf-btn-color': '', + 'sf-btn-color': '', + 'sf-txt-color': '', + 'txt-color': '', + 'chck-color': '', + 'chck-gf': '', + 'chck-git': '', + 'chck-open': '', + placeholder: '', + 'position-top': '', + 'position-bottom': '', + 'position-left': '', + 'position-right': '', + 'font-family': '' + }, + recommend: { + author: true, + others: true + }, + filters: { + ASCII: { + enabled: false, + name: 'Non-ASCII', + regExp: '[^\\x00-\\x7F\\s]+' + }, + Latin: { + enabled: false, + name: 'Non-Latin', + regExp: '[^\\u0000-\\u024F\\u2000-\\u214F\\s]+' + }, + Games: { + enabled: false, + name: 'Games', + flag: 'iu', + regExp: + 'Aimbot|AntiGame|Agar|agar\\.io|alis\\.io|angel\\.io|ExtencionRipXChetoMalo|AposBot|DFxLite|ZTx-Lite|AposFeedingBot|AposLoader|Balz|Blah Blah|Orc Clan Script|Astro\\s*Empires|^\\s*Attack|^\\s*Battle|BiteFight|Blood\\s*Wars|Bloble|Bonk|Bots|Bots4|Brawler|\\bBvS\\b|Business\\s*Tycoon|Castle\\s*Age|City\\s*Ville|chopcoin\\.io|Comunio|Conquer\\s*Club|CosmoPulse|cursors\\.io|Dark\\s*Orbit|Dead\\s*Frontier|Diep\\.io|\\bDOA\\b|doblons\\.io|DotD|Dossergame|Dragons\\s*of\\s*Atlantis|driftin\\.io|Dugout|\\bDS[a-z]+\\n|elites\\.io|Empire\\s*Board|eRep(ublik)?|Epicmafia|Epic.*War|ExoPlanet|Falcon Tools|Feuerwache|Farming|FarmVille|Fightinfo|Frontier\\s*Ville|Ghost\\s*Trapper|Gladiatus|Goalline|Gondal|gota\\.io|Grepolis|Hobopolis|\\bhwm(\\b|_)|Ikariam|\\bIT2\\b|Jellyneo|Kapi\\s*Hospital|Kings\\s*Age|Kingdoms?\\s*of|knastv(o|oe)gel|Knight\\s*Fight|\\b(Power)?KoC(Atta?ck)?\\b|\\bKOL\\b|Kongregate|Krunker|Last\\s*Emperor|Legends?\\s*of|Light\\s*Rising|lite\\.ext\\.io|Lockerz|\\bLoU\\b|Mafia\\s*(Wars|Mofo)|Menelgame|Mob\\s*Wars|Mouse\\s*Hunt|Molehill\\s*Empire|MooMoo|MyFreeFarm|narwhale\\.io|Neopets|NeoQuest|Nemexia|\\bOGame\\b|Ogar(io)?|Pardus|Pennergame|Pigskin\\s*Empire|PlayerScripts|pokeradar\\.io|Popmundo|Po?we?r\\s*(Bot|Tools)|PsicoTSI|Ravenwood|Schulterglatze|Skribbl|slither\\.io|slitherplus\\.io|slitheriogameplay|SpaceWars|splix\\.io|Survivio|\\bSW_[a-z]+\\n|\\bSnP\\b|The\\s*Crims|The\\s*West|torto\\.io|Travian|Treasure\\s*Isl(and|e)|Tribal\\s*Wars|TW.?PRO|Vampire\\s*Wars|vertix\\.io|War\\s*of\\s*Ninja|World\\s*of\\s*Tanks|West\\s*Wars|wings\\.io|\\bWoD\\b|World\\s*of\\s*Dungeons|wtf\\s*battles|Wurzelimperium|Yohoho|Zombs' + }, + SocialNetworks: { + enabled: false, + name: 'Social Networks', + flag: 'iu', + regExp: + 'Face\\s*book|Google(\\+| Plus)|\\bHabbo|Kaskus|\\bLepra|Leprosorium|MySpace|meinVZ|odnoklassniki|Одноклассники|Orkut|sch(ue|ü)ler(VZ|\\.cc)?|studiVZ|Unfriend|Valenth|VK|vkontakte|ВКонтакте|Qzone|Twitter|TweetDeck' + }, + Clutter: { + enabled: false, + name: 'Clutter', + flag: 'iu', + regExp: + "^\\s*(.{1,3})\\1+\\n|^\\s*(.+?)\\n+\\2\\n*$|^\\s*.{1,5}\\n|do\\s*n('|o)?t (install|download)|nicht installieren|(just )?(\\ban? |\\b)test(ing|s|\\d|\\b)|^\\s*.{0,4}test.{0,4}\\n|\\ntest(ing)?\\s*|^\\s*(\\{@|Smolka|Hacks)|\\[\\d{4,5}\\]|free\\s*download|theme|(night|dark) ?(mode)?" + } + } +}; +// #endregion + /** @type {{ [prefix: string]: StorageArea }} */ export const storageByPrefix = {}; @@ -56,9 +166,7 @@ class StorageArea { async getMulti(ids, transform) { const keys = ids?.map(this.toKey, this); const data = await api.get(keys); - return transform || this.prefix - ? mapEntry.call(data, transform, 'toId', this) - : data; + return transform || this.prefix ? mapEntry.call(data, transform, 'toId', this) : data; } /** @@ -92,10 +200,10 @@ const storage = { api = val; }, /** @return {?StorageArea} */ - forKey: key => storageByPrefix[/^\w+:|$/.exec(key)[0]], + forKey: (key) => storageByPrefix[/^\w+:|$/.exec(key)[0]], base: new StorageArea('base', ''), config: new StorageArea('config', 'cfg:'), - cache: new StorageArea('cache', 'cac:'), + cache: new StorageArea('cache', 'cac:') }; export default storage; diff --git a/src/js/util.js b/src/js/util.js index bb22e94..362cbaf 100644 --- a/src/js/util.js +++ b/src/js/util.js @@ -1,35 +1,33 @@ 'use strict'; + +import { webext } from './ext.js'; import { err } from './logger.js'; // #region Utilities -let isMob; -// const isMobile = /Mobile|Tablet/.test(navigator.userAgent); +const userjs = {}; const getUAData = () => { - if (typeof isMob !== 'undefined') { - return isMob; + if (userjs.isMobile !== undefined) { + return userjs.isMobile; } try { - const { platform, mobile } = navigator.userAgentData ?? {}; - isMob = - /Mobile|Tablet/.test(navigator.userAgent ?? '') || - mobile || - /Android|Apple/.test(platform ?? ''); + if (navigator) { + const { userAgent, userAgentData } = navigator; + const { platform, mobile } = userAgentData ? Object(userAgentData) : {}; + userjs.isMobile = + /Mobile|Tablet/.test(userAgent ? String(userAgent) : '') || + Boolean(mobile) || + /Android|Apple/.test(platform ? String(platform) : ''); + } else { + userjs.isMobile = false; + } } catch (ex) { - err({ cause: 'getUAData', message: ex.message }); - isMob = false; + userjs.isMobile = false; + ex.cause = 'getUAData'; + err(ex); } - return isMob; + return userjs.isMobile; }; const isMobile = getUAData(); -/** - * @type { import("../typings/types").hasOwn } - */ -const hasOwn = (obj, prop) => { - if (typeof Object.hasOwn !== 'undefined') { - return Object.hasOwn(obj, prop); - } - return Object.prototype.hasOwnProperty.call(obj, prop); -}; const isString = (val) => typeof val === 'string'; /** * @type { import("../typings/types").objToStr } @@ -38,16 +36,21 @@ const objToStr = (obj) => { return Object.prototype.toString.call(obj); }; /** - * @type { import("../typings/types").strToURL } + * @template {string | URL} S + * @param {S} str */ const strToURL = (str) => { + let url; try { - str = str ?? window.location ?? 'about:blank'; - return objToStr(str).includes('URL') ? str : new URL(str); + url = objToStr(str).includes('URL') ? str : new URL(str); } catch (ex) { - err({ cause: 'strToURL', message: ex.message }); - return window.location; + ex.cause = 'strToURL'; + err(ex); } + if (url !== undefined) { + return url + } + return str; }; /** * @type { import("../typings/types").isRegExp } @@ -119,7 +122,7 @@ const normalizeTarget = (target, toQuery = true, root) => { return Array.from(target); }; /** - * @type { import("../typings/types").ael } + * @type { import("../typings/types.d.ts").ael } */ const ael = (el, type, listener, options = {}) => { try { @@ -134,11 +137,12 @@ const ael = (el, type, listener, options = {}) => { elem.addEventListener(type, listener, options); } } catch (ex) { + ex.cause = 'ael'; err(ex); } }; /** - * @type { import("../typings/types").formAttrs } + * @type { import("../typings/types.d.ts").formAttrs } */ const formAttrs = (elem, attr = {}) => { if (!elem) { @@ -162,29 +166,28 @@ const formAttrs = (elem, attr = {}) => { return elem; }; /** - * @type { import("../typings/types").make } + * @type { import("../typings/types.d.ts").make } */ const make = (tagName, cname, attrs) => { let el; try { - // el = - // tagName === 'fragment' ? document.createDocumentFragment() : document.createElement(tagName); el = document.createElement(tagName); if (!isEmpty(cname)) { - if (isString(cname)) { + if (typeof cname === 'string') { el.className = cname; } else if (isObj(cname)) { formAttrs(el, cname); } } if (!isEmpty(attrs)) { - if (isString(attrs)) { + if (typeof attrs === 'string') { el.textContent = attrs; } else if (isObj(attrs)) { formAttrs(el, attrs); } } } catch (ex) { + ex.cause = 'make'; err(ex); } return el; @@ -198,57 +201,101 @@ const openInTab = async (url) => { const newTab = await webext.tabs.create({ url }); return newTab; }; -const intersect = (a = [], b = []) => { - for (const v of a) { - if (b.includes(v)) { +const union = (...arr) => [...new Set(arr.flat())]; +const loadFilters = (cfg) => { + /** @type {Map} */ + const pool = new Map(); + const handles = { + pool, + enabled() { + return [...pool.values()].filter((o) => o.enabled); + }, + refresh() { + if (!Object.is(pool.size, 0)) pool.clear(); + for (const [key, value] of Object.entries(cfg.filters)) { + if (!pool.has(key)) + pool.set(key, { + ...value, + reg: new RegExp(value.regExp, value.flag), + keyReg: new RegExp(key.trim().toLocaleLowerCase(), 'gi'), + valueReg: new RegExp(value.name.trim().toLocaleLowerCase(), 'gi') + }); + } + return this; + }, + get(str) { + return [...pool.values()].find((v) => v.keyReg.test(str) || v.valueReg.test(str)); + }, + /** + * @param { import("../typings/types.d.ts").GSForkQuery } param0 + */ + match({ name, users }) { + const p = handles.enabled(); + if (Object.is(p.length, 0)) return true; + for (const v of p) { + if ([{ name }, ...users].find((o) => o.name.match(v.reg))) return false; + } return true; } + }; + for (const [key, value] of Object.entries(cfg.filters)) { + if (!pool.has(key)) + pool.set(key, { + ...value, + reg: new RegExp(value.regExp, value.flag), + keyReg: new RegExp(key.trim().toLocaleLowerCase(), 'gi'), + valueReg: new RegExp(value.name.trim().toLocaleLowerCase(), 'gi') + }); } - for (const v of b) { - if (a.includes(v)) { - return true; + return handles.refresh(); +}; +/** + * @param {string} txt + */ +const formatURL = (txt) => + txt + .split('.') + .splice(-2) + .join('.') + .replace(/\/|https:/g, ''); +/******************************************************************************/ + +const matchesFromHostnames = (hostnames) => { + const out = []; + for (const hn of hostnames) { + if (hn === '*' || hn === 'all-urls') { + out.length = 0; + out.push(''); + break; } + out.push(`*://*.${hn}/*`); } - return false; + return out; }; -const template = { - data: { - id: 0, - bad_ratings: 0, - good_ratings: 0, - ok_ratings: 0, - daily_installs: 0, - total_installs: 0, - name: 'NOT FOUND', - description: 'NOT FOUND', - version: '0.0.0', - url: 'about:blank', - code_url: 'about:blank', - created_at: Date.now(), - code_updated_at: Date.now(), - users: [ - { - name: '', - url: '' - } - ] - }, - merge(obj = {}) { - for (const key in template.data) { - if (hasOwn(obj, key)) continue; - obj[key] = template.data[key]; + +const hostnamesFromMatches = (origins) => { + const out = []; + for (const origin of origins) { + if (origin === '') { + out.push('all-urls'); + continue; } - return obj; + const match = /^\*:\/\/(?:\*\.)?([^/]+)\/\*/.exec(origin); + if (match === null) { + continue; + } + out.push(match[1]); } + return out; }; + +/******************************************************************************/ // #endregion export { - isMobile, - hasOwn, + formatURL, objToStr, strToURL, - intersect, isRegExp, isElem, isObj, @@ -262,5 +309,8 @@ export { formAttrs, make, openInTab, - template + union, + loadFilters, + matchesFromHostnames, + hostnamesFromMatches }; diff --git a/src/manifest/chrome.json b/src/manifest/chrome.json index 5581779..78eefbe 100644 --- a/src/manifest/chrome.json +++ b/src/manifest/chrome.json @@ -1,38 +1,41 @@ { - "manifest_version": 2, + "manifest_version": 3, "default_locale": "en", "name": "__MSG_extName__", "description": "__MSG_extShortDesc__", "short_name": "userJSPlus", "background": { - "page": "background.html" + "service_worker": "/js/background.js", + "type": "module" }, - "browser_action": { + "action": { "default_icon": { - "16": "img/icon_16.png", + "16": "img/icon_16.png", "32": "img/icon_32.png", - "64": "img/icon_64.png" + "48": "img/icon_48.png", + "64": "img/icon_64.png", + "128": "img/icon_128.png" }, "default_popup": "popup.html", "default_title": "Magic UserJS+" }, - "options_ui": { - "page": "popup.html?mujs=settings", - "open_in_tab": true - }, + "minimum_chrome_version": "122.0", + "options_page": "popup.html?mujs=settings", "permissions": [ - "tabs", - "", "storage", "unlimitedStorage", + "tabs", + "activeTab", "webRequest" ], - "content_security_policy": "script-src 'self'; object-src 'self'", + "host_permissions": [ + "https://*/*" + ], "icons": { "16": "img/icon_16.png", "32": "img/icon_32.png", + "48": "img/icon_48.png", "64": "img/icon_64.png", "128": "img/icon_128.png" - }, - "commands": {} + } } diff --git a/src/manifest/firefox.json b/src/manifest/firefox.json index cbdb471..3a7ac1b 100644 --- a/src/manifest/firefox.json +++ b/src/manifest/firefox.json @@ -1,48 +1,58 @@ { - "$schema": "https://json.schemastore.org/webextension.json", - "manifest_version": 2, + "manifest_version": 3, "default_locale": "en", "name": "__MSG_extName__", "description": "__MSG_extShortDesc__", "short_name": "userJSPlus", "background": { - "page": "background.html" + "scripts": [ + "/js/background.js" + ], + "type": "module" }, - "browser_action": { - "browser_style": false, + "action": { "default_area": "navbar", "default_icon": { - "16": "img/icon_16.png", + "16": "img/icon_16.png", "32": "img/icon_32.png", - "64": "img/icon_64.png" + "48": "img/icon_48.png", + "64": "img/icon_64.png", + "128": "img/icon_128.png" }, "default_popup": "popup.html", "default_title": "Magic UserJS+" }, + "browser_specific_settings": { + "gecko": { + "id": "uscriptplus@mol.com", + "strict_min_version": "128.0" + }, + "gecko_android": { + "strict_min_version": "128.0" + } + }, "options_ui": { - "page": "popup.html?mujs=settings", - "open_in_tab": true + "open_in_tab": true, + "page": "popup.html?mujs=settings" }, "permissions": [ - "tabs", - "", "storage", "unlimitedStorage", + "tabs", + "activeTab", "webRequest" ], - "browser_specific_settings": { - "gecko": { - "id": "uscriptplus@mol.com", - "strict_min_version": "91.1.0" - } + "host_permissions": [ + "https://*/*" + ], + "content_security_policy": { + "extension_pages": "script-src 'self'; object-src 'self'" }, - "content_security_policy": "script-src 'self'; object-src 'self'", "icons": { - "16": "img/userjs.svg", - "32": "img/userjs.svg", - "48": "img/userjs.svg", - "64": "img/userjs.svg", - "96": "img/userjs.svg" - }, - "commands": {} + "16": "img/icon_16.png", + "32": "img/icon_32.png", + "48": "img/icon_48.png", + "64": "img/icon_64.png", + "128": "img/icon_128.png" + } } diff --git a/src/sass/_main.scss b/src/sass/_main.scss index 257468a..1cbabb5 100644 --- a/src/sass/_main.scss +++ b/src/sass/_main.scss @@ -833,6 +833,7 @@ mujs-body { } @media screen and (max-width: 800px) { + align-self: center; width: 30em !important; } } @@ -844,7 +845,6 @@ mujs-body { width: -webkit-fit-content; width: -moz-fit-content; width: fit-content; - // max-width: 20em; @media screen and (max-width: 800px) { width: 100% !important; diff --git a/src/sass/fontawesome/_animated.scss b/src/sass/fontawesome/_animated.scss new file mode 100644 index 0000000..779125e --- /dev/null +++ b/src/sass/fontawesome/_animated.scss @@ -0,0 +1,152 @@ +// animating icons +// -------------------------- + +.#{$fa-css-prefix}-beat { + animation-name: #{$fa-css-prefix}-beat; + animation-delay: var(--#{$fa-css-prefix}-animation-delay, 0s); + animation-direction: var(--#{$fa-css-prefix}-animation-direction, normal); + animation-duration: var(--#{$fa-css-prefix}-animation-duration, 1s); + animation-iteration-count: var(--#{$fa-css-prefix}-animation-iteration-count, infinite); + animation-timing-function: var(--#{$fa-css-prefix}-animation-timing, ease-in-out); +} + +.#{$fa-css-prefix}-bounce { + animation-name: #{$fa-css-prefix}-bounce; + animation-delay: var(--#{$fa-css-prefix}-animation-delay, 0s); + animation-direction: var(--#{$fa-css-prefix}-animation-direction, normal); + animation-duration: var(--#{$fa-css-prefix}-animation-duration, 1s); + animation-iteration-count: var(--#{$fa-css-prefix}-animation-iteration-count, infinite); + animation-timing-function: var(--#{$fa-css-prefix}-animation-timing, cubic-bezier(0.280, 0.840, 0.420, 1)); +} + +.#{$fa-css-prefix}-fade { + animation-name: #{$fa-css-prefix}-fade; + animation-delay: var(--#{$fa-css-prefix}-animation-delay, 0s); + animation-direction: var(--#{$fa-css-prefix}-animation-direction, normal); + animation-duration: var(--#{$fa-css-prefix}-animation-duration, 1s); + animation-iteration-count: var(--#{$fa-css-prefix}-animation-iteration-count, infinite); + animation-timing-function: var(--#{$fa-css-prefix}-animation-timing, cubic-bezier(.4,0,.6,1)); +} + +.#{$fa-css-prefix}-beat-fade { + animation-name: #{$fa-css-prefix}-beat-fade; + animation-delay: var(--#{$fa-css-prefix}-animation-delay, 0s); + animation-direction: var(--#{$fa-css-prefix}-animation-direction, normal); + animation-duration: var(--#{$fa-css-prefix}-animation-duration, 1s); + animation-iteration-count: var(--#{$fa-css-prefix}-animation-iteration-count, infinite); + animation-timing-function: var(--#{$fa-css-prefix}-animation-timing, cubic-bezier(.4,0,.6,1)); +} + +.#{$fa-css-prefix}-flip { + animation-name: #{$fa-css-prefix}-flip; + animation-delay: var(--#{$fa-css-prefix}-animation-delay, 0s); + animation-direction: var(--#{$fa-css-prefix}-animation-direction, normal); + animation-duration: var(--#{$fa-css-prefix}-animation-duration, 1s); + animation-iteration-count: var(--#{$fa-css-prefix}-animation-iteration-count, infinite); + animation-timing-function: var(--#{$fa-css-prefix}-animation-timing, ease-in-out); +} + +.#{$fa-css-prefix}-shake { + animation-name: #{$fa-css-prefix}-shake; + animation-delay: var(--#{$fa-css-prefix}-animation-delay, 0s); + animation-direction: var(--#{$fa-css-prefix}-animation-direction, normal); + animation-duration: var(--#{$fa-css-prefix}-animation-duration, 1s); + animation-iteration-count: var(--#{$fa-css-prefix}-animation-iteration-count, infinite); + animation-timing-function: var(--#{$fa-css-prefix}-animation-timing, linear); +} + +.#{$fa-css-prefix}-spin { + animation-name: #{$fa-css-prefix}-spin; + animation-delay: var(--#{$fa-css-prefix}-animation-delay, 0s); + animation-direction: var(--#{$fa-css-prefix}-animation-direction, normal); + animation-duration: var(--#{$fa-css-prefix}-animation-duration, 2s); + animation-iteration-count: var(--#{$fa-css-prefix}-animation-iteration-count, infinite); + animation-timing-function: var(--#{$fa-css-prefix}-animation-timing, linear); +} + +.#{$fa-css-prefix}-spin-reverse { + --#{$fa-css-prefix}-animation-direction: reverse; +} + +.#{$fa-css-prefix}-pulse, +.#{$fa-css-prefix}-spin-pulse { + animation-name: #{$fa-css-prefix}-spin; + animation-direction: var(--#{$fa-css-prefix}-animation-direction, normal); + animation-duration: var(--#{$fa-css-prefix}-animation-duration, 1s); + animation-iteration-count: var(--#{$fa-css-prefix}-animation-iteration-count, infinite); + animation-timing-function: var(--#{$fa-css-prefix}-animation-timing, steps(8)); +} + +// if agent or operating system prefers reduced motion, disable animations +// see: https://www.smashingmagazine.com/2020/09/design-reduced-motion-sensitivities/ +// see: https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion +@media (prefers-reduced-motion: reduce) { + .#{$fa-css-prefix}-beat, + .#{$fa-css-prefix}-bounce, + .#{$fa-css-prefix}-fade, + .#{$fa-css-prefix}-beat-fade, + .#{$fa-css-prefix}-flip, + .#{$fa-css-prefix}-pulse, + .#{$fa-css-prefix}-shake, + .#{$fa-css-prefix}-spin, + .#{$fa-css-prefix}-spin-pulse { + animation-delay: -1ms; + animation-duration: 1ms; + animation-iteration-count: 1; + transition-delay: 0s; + transition-duration: 0s; + } +} + +@keyframes #{$fa-css-prefix}-beat { + 0%, 90% { transform: scale(1); } + 45% { transform: scale(var(--#{$fa-css-prefix}-beat-scale, 1.25)); } +} + +@keyframes #{$fa-css-prefix}-bounce { + 0% { transform: scale(1,1) translateY(0); } + 10% { transform: scale(var(--#{$fa-css-prefix}-bounce-start-scale-x, 1.1),var(--#{$fa-css-prefix}-bounce-start-scale-y, 0.9)) translateY(0); } + 30% { transform: scale(var(--#{$fa-css-prefix}-bounce-jump-scale-x, 0.9),var(--#{$fa-css-prefix}-bounce-jump-scale-y, 1.1)) translateY(var(--#{$fa-css-prefix}-bounce-height, -0.5em)); } + 50% { transform: scale(var(--#{$fa-css-prefix}-bounce-land-scale-x, 1.05),var(--#{$fa-css-prefix}-bounce-land-scale-y, 0.95)) translateY(0); } + 57% { transform: scale(1,1) translateY(var(--#{$fa-css-prefix}-bounce-rebound, -0.125em)); } + 64% { transform: scale(1,1) translateY(0); } + 100% { transform: scale(1,1) translateY(0); } +} + +@keyframes #{$fa-css-prefix}-fade { + 50% { opacity: var(--#{$fa-css-prefix}-fade-opacity, 0.4); } +} + +@keyframes #{$fa-css-prefix}-beat-fade { + 0%, 100% { + opacity: var(--#{$fa-css-prefix}-beat-fade-opacity, 0.4); + transform: scale(1); + } + 50% { + opacity: 1; + transform: scale(var(--#{$fa-css-prefix}-beat-fade-scale, 1.125)); + } +} + +@keyframes #{$fa-css-prefix}-flip { + 50% { + transform: rotate3d(var(--#{$fa-css-prefix}-flip-x, 0), var(--#{$fa-css-prefix}-flip-y, 1), var(--#{$fa-css-prefix}-flip-z, 0), var(--#{$fa-css-prefix}-flip-angle, -180deg)); + } +} + +@keyframes #{$fa-css-prefix}-shake { + 0% { transform: rotate(-15deg); } + 4% { transform: rotate(15deg); } + 8%, 24% { transform: rotate(-18deg); } + 12%, 28% { transform: rotate(18deg); } + 16% { transform: rotate(-22deg); } + 20% { transform: rotate(22deg); } + 32% { transform: rotate(-12deg); } + 36% { transform: rotate(12deg); } + 40%, 100% { transform: rotate(0deg); } +} + +@keyframes #{$fa-css-prefix}-spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} diff --git a/src/sass/fontawesome/_bordered-pulled.scss b/src/sass/fontawesome/_bordered-pulled.scss new file mode 100644 index 0000000..06bf72d --- /dev/null +++ b/src/sass/fontawesome/_bordered-pulled.scss @@ -0,0 +1,20 @@ +// bordered + pulled icons +// ------------------------- + +.#{$fa-css-prefix}-border { + border-color: var(--#{$fa-css-prefix}-border-color, #{$fa-border-color}); + border-radius: var(--#{$fa-css-prefix}-border-radius, #{$fa-border-radius}); + border-style: var(--#{$fa-css-prefix}-border-style, #{$fa-border-style}); + border-width: var(--#{$fa-css-prefix}-border-width, #{$fa-border-width}); + padding: var(--#{$fa-css-prefix}-border-padding, #{$fa-border-padding}); +} + +.#{$fa-css-prefix}-pull-left { + float: left; + margin-right: var(--#{$fa-css-prefix}-pull-margin, #{$fa-pull-margin}); +} + +.#{$fa-css-prefix}-pull-right { + float: right; + margin-left: var(--#{$fa-css-prefix}-pull-margin, #{$fa-pull-margin}); +} diff --git a/src/sass/fontawesome/_core.scss b/src/sass/fontawesome/_core.scss new file mode 100644 index 0000000..a850b0f --- /dev/null +++ b/src/sass/fontawesome/_core.scss @@ -0,0 +1,49 @@ +// base icon class definition +// ------------------------- + +.#{$fa-css-prefix} { + font-family: var(--#{$fa-css-prefix}-style-family, '#{$fa-style-family}'); + font-weight: var(--#{$fa-css-prefix}-style, #{$fa-style}); +} + +.fas, +.far, +.fab, +.#{$fa-css-prefix}-solid, +.#{$fa-css-prefix}-regular, +.#{$fa-css-prefix}-brands, +.#{$fa-css-prefix} { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + display: var(--#{$fa-css-prefix}-display, #{$fa-display}); + font-style: normal; + font-variant: normal; + line-height: 1; + text-rendering: auto; +} + +.fas::before, +.far::before, +.fab::before, +.#{$fa-css-prefix}-solid::before, +.#{$fa-css-prefix}-regular::before, +.#{$fa-css-prefix}-brands::before, +.#{$fa-css-prefix}::before { + content: var(#{$fa-icon-property}); +} + +.#{$fa-css-prefix}-classic, +.fas, +.#{$fa-css-prefix}-solid, +.far, +.#{$fa-css-prefix}-regular { + font-family: 'Font Awesome 6 Free'; +} +.#{$fa-css-prefix}-brands, +.fab { + font-family: 'Font Awesome 6 Brands'; +} + +%fa-icon { + @include fa-icon; +} diff --git a/src/sass/fontawesome/_fixed-width.scss b/src/sass/fontawesome/_fixed-width.scss new file mode 100644 index 0000000..7234236 --- /dev/null +++ b/src/sass/fontawesome/_fixed-width.scss @@ -0,0 +1,7 @@ +// fixed-width icons +// ------------------------- + +.#{$fa-css-prefix}-fw { + text-align: center; + width: $fa-fw-width; +} diff --git a/src/sass/fontawesome/_functions.scss b/src/sass/fontawesome/_functions.scss new file mode 100644 index 0000000..a17ffe8 --- /dev/null +++ b/src/sass/fontawesome/_functions.scss @@ -0,0 +1,57 @@ +// functions +// -------------------------- + +// fa-content: convenience function used to set content property +@function fa-content($fa-var) { + @return unquote("\"#{ $fa-var }\""); +} + +// fa-divide: Originally obtained from the Bootstrap https://github.com/twbs/bootstrap +// +// Licensed under: The MIT License (MIT) +// +// Copyright (c) 2011-2021 Twitter, Inc. +// Copyright (c) 2011-2021 The Bootstrap Authors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +@function fa-divide($dividend, $divisor, $precision: 10) { + $sign: if($dividend > 0 and $divisor > 0, 1, -1); + $dividend: abs($dividend); + $divisor: abs($divisor); + $quotient: 0; + $remainder: $dividend; + @if $dividend == 0 { + @return 0; + } + @if $divisor == 0 { + @error "Cannot divide by 0"; + } + @if $divisor == 1 { + @return $dividend; + } + @while $remainder >= $divisor { + $quotient: $quotient + 1; + $remainder: $remainder - $divisor; + } + @if $remainder > 0 and $precision > 0 { + $remainder: fa-divide($remainder * 10, $divisor, $precision - 1) * .1; + } + @return ($quotient + $remainder) * $sign; +} diff --git a/src/sass/fontawesome/_icons.scss b/src/sass/fontawesome/_icons.scss new file mode 100644 index 0000000..2f13535 --- /dev/null +++ b/src/sass/fontawesome/_icons.scss @@ -0,0 +1,12 @@ +// specific icon class definition +// ------------------------- + +/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen +readers do not read off random characters that represent icons */ + +@each $name, $icon in $fa-icons { + .#{$fa-css-prefix}-#{$name} { + #{$fa-icon-property}: unquote("\"#{ $icon }\""); + } +} + diff --git a/src/sass/fontawesome/_list.scss b/src/sass/fontawesome/_list.scss new file mode 100644 index 0000000..120506a --- /dev/null +++ b/src/sass/fontawesome/_list.scss @@ -0,0 +1,18 @@ +// icons in a list +// ------------------------- + +.#{$fa-css-prefix}-ul { + list-style-type: none; + margin-left: var(--#{$fa-css-prefix}-li-margin, #{$fa-li-margin}); + padding-left: 0; + + > li { position: relative; } +} + +.#{$fa-css-prefix}-li { + left: calc(-1 * var(--#{$fa-css-prefix}-li-width, #{$fa-li-width})); + position: absolute; + text-align: center; + width: var(--#{$fa-css-prefix}-li-width, #{$fa-li-width}); + line-height: inherit; +} diff --git a/src/sass/fontawesome/_mixins.scss b/src/sass/fontawesome/_mixins.scss new file mode 100644 index 0000000..71f99ad --- /dev/null +++ b/src/sass/fontawesome/_mixins.scss @@ -0,0 +1,65 @@ +// mixins +// -------------------------- + +// base rendering for an icon +@mixin fa-icon { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + display: inline-block; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1; +} + +// sets relative font-sizing and alignment (in _sizing) +@mixin fa-size ($font-size) { + font-size: fa-divide($font-size, $fa-size-scale-base) * 1em; // converts step in sizing scale into an em-based value that's relative to the scale's base + line-height: fa-divide(1, $font-size) * 1em; // sets the line-height of the icon back to that of it's parent + vertical-align: (fa-divide(6, $font-size) - fa-divide(3, 8)) * 1em; // vertically centers the icon taking into account the surrounding text's descender +} + +// only display content to screen readers +// see: https://www.a11yproject.com/posts/2013-01-11-how-to-hide-content/ +// see: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/ +@mixin fa-sr-only() { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} + +// use in conjunction with .sr-only to only display content when it's focused +@mixin fa-sr-only-focusable() { + &:not(:focus) { + @include fa-sr-only(); + } +} + +// sets a specific icon family to use alongside style + icon mixins +@mixin fa-family-classic() { + @extend .fa-classic; +} + +// convenience mixins for declaring pseudo-elements by CSS variable, +// including all style-specific font properties +@mixin fa-icon-solid($fa-var) { + @extend .fa-solid; + + & { #{$fa-icon-property}: unquote("\"#{ $fa-var }\""); #{$fa-duotone-icon-property}: unquote("\"#{ $fa-var }#{ $fa-var }\""); } +} +@mixin fa-icon-regular($fa-var) { + @extend .fa-regular; + + & { #{$fa-icon-property}: unquote("\"#{ $fa-var }\""); #{$fa-duotone-icon-property}: unquote("\"#{ $fa-var }#{ $fa-var }\""); } +} +@mixin fa-icon-brands($fa-var) { + @extend .fa-brands; + + & { #{$fa-icon-property}: unquote("\"#{ $fa-var }\""); #{$fa-duotone-icon-property}: unquote("\"#{ $fa-var }#{ $fa-var }\""); } +} diff --git a/src/sass/fontawesome/_rotated-flipped.scss b/src/sass/fontawesome/_rotated-flipped.scss new file mode 100644 index 0000000..0bd4b7c --- /dev/null +++ b/src/sass/fontawesome/_rotated-flipped.scss @@ -0,0 +1,31 @@ +// rotating + flipping icons +// ------------------------- + +.#{$fa-css-prefix}-rotate-90 { + transform: rotate(90deg); +} + +.#{$fa-css-prefix}-rotate-180 { + transform: rotate(180deg); +} + +.#{$fa-css-prefix}-rotate-270 { + transform: rotate(270deg); +} + +.#{$fa-css-prefix}-flip-horizontal { + transform: scale(-1, 1); +} + +.#{$fa-css-prefix}-flip-vertical { + transform: scale(1, -1); +} + +.#{$fa-css-prefix}-flip-both, +.#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { + transform: scale(-1, -1); +} + +.#{$fa-css-prefix}-rotate-by { + transform: rotate(var(--#{$fa-css-prefix}-rotate-angle, 0)); +} diff --git a/src/sass/fontawesome/_screen-reader.scss b/src/sass/fontawesome/_screen-reader.scss new file mode 100644 index 0000000..2beb887 --- /dev/null +++ b/src/sass/fontawesome/_screen-reader.scss @@ -0,0 +1,14 @@ +// screen-reader utilities +// ------------------------- + +// only display content to screen readers +.sr-only, +.#{$fa-css-prefix}-sr-only { + @include fa-sr-only; +} + +// use in conjunction with .sr-only to only display content when it's focused +.sr-only-focusable, +.#{$fa-css-prefix}-sr-only-focusable { + @include fa-sr-only-focusable; +} diff --git a/src/sass/fontawesome/_shims.scss b/src/sass/fontawesome/_shims.scss new file mode 100644 index 0000000..3fb6d41 --- /dev/null +++ b/src/sass/fontawesome/_shims.scss @@ -0,0 +1,1578 @@ +.#{$fa-css-prefix}.#{$fa-css-prefix}-glass { #{$fa-icon-property}: unquote("\"#{ $fa-var-martini-glass-empty }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-envelope-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-envelope-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-envelope }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-star }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-remove { #{$fa-icon-property}: unquote("\"#{ $fa-var-xmark }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-close { #{$fa-icon-property}: unquote("\"#{ $fa-var-xmark }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-gear { #{$fa-icon-property}: unquote("\"#{ $fa-var-gear }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-trash-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-trash-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-trash-can }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-home { #{$fa-icon-property}: unquote("\"#{ $fa-var-house }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-clock-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-clock-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-clock }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-down { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-down { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle-down }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-up { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-up { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle-up }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-play-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-play-circle-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle-play }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-repeat { #{$fa-icon-property}: unquote("\"#{ $fa-var-arrow-rotate-right }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-rotate-right { #{$fa-icon-property}: unquote("\"#{ $fa-var-arrow-rotate-right }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-refresh { #{$fa-icon-property}: unquote("\"#{ $fa-var-arrows-rotate }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-list-alt { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-list-alt { #{$fa-icon-property}: unquote("\"#{ $fa-var-rectangle-list }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-dedent { #{$fa-icon-property}: unquote("\"#{ $fa-var-outdent }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-video-camera { #{$fa-icon-property}: unquote("\"#{ $fa-var-video }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-picture-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-picture-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-image }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-photo { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-photo { #{$fa-icon-property}: unquote("\"#{ $fa-var-image }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-image { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-image { #{$fa-icon-property}: unquote("\"#{ $fa-var-image }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-map-marker { #{$fa-icon-property}: unquote("\"#{ $fa-var-location-dot }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-pencil-square-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-pencil-square-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-pen-to-square }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-edit { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-edit { #{$fa-icon-property}: unquote("\"#{ $fa-var-pen-to-square }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-share-square-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-share-from-square }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-check-square-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-check-square-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-check }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrows { #{$fa-icon-property}: unquote("\"#{ $fa-var-up-down-left-right }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-times-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-times-circle-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle-xmark }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-check-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-check-circle-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle-check }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-mail-forward { #{$fa-icon-property}: unquote("\"#{ $fa-var-share }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-expand { #{$fa-icon-property}: unquote("\"#{ $fa-var-up-right-and-down-left-from-center }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-compress { #{$fa-icon-property}: unquote("\"#{ $fa-var-down-left-and-up-right-to-center }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-eye { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-eye-slash { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-warning { #{$fa-icon-property}: unquote("\"#{ $fa-var-triangle-exclamation }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar { #{$fa-icon-property}: unquote("\"#{ $fa-var-calendar-days }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrows-v { #{$fa-icon-property}: unquote("\"#{ $fa-var-up-down }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrows-h { #{$fa-icon-property}: unquote("\"#{ $fa-var-left-right }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-bar-chart { #{$fa-icon-property}: unquote("\"#{ $fa-var-chart-column }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-bar-chart-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-chart-column }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-twitter-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-twitter-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-twitter }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-facebook }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-gears { #{$fa-icon-property}: unquote("\"#{ $fa-var-gears }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-thumbs-o-up { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-thumbs-o-up { #{$fa-icon-property}: unquote("\"#{ $fa-var-thumbs-up }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-thumbs-o-down { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-thumbs-o-down { #{$fa-icon-property}: unquote("\"#{ $fa-var-thumbs-down }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-heart-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-heart-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-heart }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-sign-out { #{$fa-icon-property}: unquote("\"#{ $fa-var-right-from-bracket }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-linkedin-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-linkedin-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-linkedin }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-thumb-tack { #{$fa-icon-property}: unquote("\"#{ $fa-var-thumbtack }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-external-link { #{$fa-icon-property}: unquote("\"#{ $fa-var-up-right-from-square }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-sign-in { #{$fa-icon-property}: unquote("\"#{ $fa-var-right-to-bracket }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-github-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-github-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-github }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-lemon-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-lemon-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-lemon }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-square-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-square-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-square }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-bookmark-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bookmark-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-bookmark }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-twitter { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook { #{$fa-icon-property}: unquote("\"#{ $fa-var-facebook-f }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-f { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-f { #{$fa-icon-property}: unquote("\"#{ $fa-var-facebook-f }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-github { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-credit-card { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-feed { #{$fa-icon-property}: unquote("\"#{ $fa-var-rss }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hdd-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hdd-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-hard-drive }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-right { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-right { #{$fa-icon-property}: unquote("\"#{ $fa-var-hand-point-right }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-left { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-left { #{$fa-icon-property}: unquote("\"#{ $fa-var-hand-point-left }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-up { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-up { #{$fa-icon-property}: unquote("\"#{ $fa-var-hand-point-up }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-down { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-o-down { #{$fa-icon-property}: unquote("\"#{ $fa-var-hand-point-down }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-globe { #{$fa-icon-property}: unquote("\"#{ $fa-var-earth-americas }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-tasks { #{$fa-icon-property}: unquote("\"#{ $fa-var-bars-progress }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrows-alt { #{$fa-icon-property}: unquote("\"#{ $fa-var-maximize }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-group { #{$fa-icon-property}: unquote("\"#{ $fa-var-users }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-chain { #{$fa-icon-property}: unquote("\"#{ $fa-var-link }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-cut { #{$fa-icon-property}: unquote("\"#{ $fa-var-scissors }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-files-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-files-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-copy }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-floppy-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-floppy-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-floppy-disk }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-save { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-save { #{$fa-icon-property}: unquote("\"#{ $fa-var-floppy-disk }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-navicon { #{$fa-icon-property}: unquote("\"#{ $fa-var-bars }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-reorder { #{$fa-icon-property}: unquote("\"#{ $fa-var-bars }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-magic { #{$fa-icon-property}: unquote("\"#{ $fa-var-wand-magic-sparkles }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-pinterest { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-pinterest-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-pinterest-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-pinterest }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-google-plus }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus { #{$fa-icon-property}: unquote("\"#{ $fa-var-google-plus-g }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-money { #{$fa-icon-property}: unquote("\"#{ $fa-var-money-bill-1 }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-unsorted { #{$fa-icon-property}: unquote("\"#{ $fa-var-sort }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-desc { #{$fa-icon-property}: unquote("\"#{ $fa-var-sort-down }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-asc { #{$fa-icon-property}: unquote("\"#{ $fa-var-sort-up }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-linkedin { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-linkedin { #{$fa-icon-property}: unquote("\"#{ $fa-var-linkedin-in }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-rotate-left { #{$fa-icon-property}: unquote("\"#{ $fa-var-arrow-rotate-left }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-legal { #{$fa-icon-property}: unquote("\"#{ $fa-var-gavel }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-tachometer { #{$fa-icon-property}: unquote("\"#{ $fa-var-gauge-high }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-dashboard { #{$fa-icon-property}: unquote("\"#{ $fa-var-gauge-high }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-comment-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-comment-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-comment }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-comments-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-comments-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-comments }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-flash { #{$fa-icon-property}: unquote("\"#{ $fa-var-bolt }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-clipboard { #{$fa-icon-property}: unquote("\"#{ $fa-var-paste }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-lightbulb-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-lightbulb-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-lightbulb }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-exchange { #{$fa-icon-property}: unquote("\"#{ $fa-var-right-left }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-cloud-download { #{$fa-icon-property}: unquote("\"#{ $fa-var-cloud-arrow-down }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-cloud-upload { #{$fa-icon-property}: unquote("\"#{ $fa-var-cloud-arrow-up }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-bell-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bell-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-bell }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-cutlery { #{$fa-icon-property}: unquote("\"#{ $fa-var-utensils }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-text-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-text-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-lines }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-building-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-building-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-building }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hospital-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hospital-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-hospital }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-tablet { #{$fa-icon-property}: unquote("\"#{ $fa-var-tablet-screen-button }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-mobile { #{$fa-icon-property}: unquote("\"#{ $fa-var-mobile-screen-button }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-mobile-phone { #{$fa-icon-property}: unquote("\"#{ $fa-var-mobile-screen-button }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-mail-reply { #{$fa-icon-property}: unquote("\"#{ $fa-var-reply }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-github-alt { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-folder-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-folder-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-folder }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-folder-open-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-folder-open-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-folder-open }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-smile-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-smile-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-face-smile }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-frown-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-frown-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-face-frown }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-meh-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-meh-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-face-meh }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-keyboard-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-keyboard-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-keyboard }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-flag-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-flag-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-flag }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-mail-reply-all { #{$fa-icon-property}: unquote("\"#{ $fa-var-reply-all }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-star-half-stroke }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-empty { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-empty { #{$fa-icon-property}: unquote("\"#{ $fa-var-star-half-stroke }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-full { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-star-half-full { #{$fa-icon-property}: unquote("\"#{ $fa-var-star-half-stroke }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-code-fork { #{$fa-icon-property}: unquote("\"#{ $fa-var-code-branch }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-chain-broken { #{$fa-icon-property}: unquote("\"#{ $fa-var-link-slash }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-unlink { #{$fa-icon-property}: unquote("\"#{ $fa-var-link-slash }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-calendar }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-maxcdn { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-html5 { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-css3 { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-unlock-alt { #{$fa-icon-property}: unquote("\"#{ $fa-var-unlock }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-minus-square-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-minus-square-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-minus }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-level-up { #{$fa-icon-property}: unquote("\"#{ $fa-var-turn-up }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-level-down { #{$fa-icon-property}: unquote("\"#{ $fa-var-turn-down }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-pencil-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-pen }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-external-link-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-up-right }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-compass { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-down { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-down { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-caret-down }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-down { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-down { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-caret-down }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-up { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-up { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-caret-up }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-up { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-up { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-caret-up }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-right { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-right { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-caret-right }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-right { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-right { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-caret-right }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-eur { #{$fa-icon-property}: unquote("\"#{ $fa-var-euro-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-euro { #{$fa-icon-property}: unquote("\"#{ $fa-var-euro-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-gbp { #{$fa-icon-property}: unquote("\"#{ $fa-var-sterling-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-usd { #{$fa-icon-property}: unquote("\"#{ $fa-var-dollar-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-dollar { #{$fa-icon-property}: unquote("\"#{ $fa-var-dollar-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-inr { #{$fa-icon-property}: unquote("\"#{ $fa-var-indian-rupee-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-rupee { #{$fa-icon-property}: unquote("\"#{ $fa-var-indian-rupee-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-jpy { #{$fa-icon-property}: unquote("\"#{ $fa-var-yen-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-cny { #{$fa-icon-property}: unquote("\"#{ $fa-var-yen-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-rmb { #{$fa-icon-property}: unquote("\"#{ $fa-var-yen-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-yen { #{$fa-icon-property}: unquote("\"#{ $fa-var-yen-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-rub { #{$fa-icon-property}: unquote("\"#{ $fa-var-ruble-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-ruble { #{$fa-icon-property}: unquote("\"#{ $fa-var-ruble-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-rouble { #{$fa-icon-property}: unquote("\"#{ $fa-var-ruble-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-krw { #{$fa-icon-property}: unquote("\"#{ $fa-var-won-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-won { #{$fa-icon-property}: unquote("\"#{ $fa-var-won-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-btc { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bitcoin { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bitcoin { #{$fa-icon-property}: unquote("\"#{ $fa-var-btc }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-text { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-lines }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-alpha-asc { #{$fa-icon-property}: unquote("\"#{ $fa-var-arrow-down-a-z }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-alpha-desc { #{$fa-icon-property}: unquote("\"#{ $fa-var-arrow-down-z-a }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-amount-asc { #{$fa-icon-property}: unquote("\"#{ $fa-var-arrow-down-short-wide }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-amount-desc { #{$fa-icon-property}: unquote("\"#{ $fa-var-arrow-down-wide-short }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-numeric-asc { #{$fa-icon-property}: unquote("\"#{ $fa-var-arrow-down-1-9 }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-sort-numeric-desc { #{$fa-icon-property}: unquote("\"#{ $fa-var-arrow-down-9-1 }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-youtube-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-youtube-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-youtube }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-youtube { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-xing { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-xing-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-xing-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-xing }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-youtube-play { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-youtube-play { #{$fa-icon-property}: unquote("\"#{ $fa-var-youtube }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-dropbox { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-stack-overflow { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-instagram { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-flickr { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-adn { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bitbucket { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bitbucket-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bitbucket-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-bitbucket }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-tumblr { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-tumblr-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-tumblr-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-tumblr }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-long-arrow-down { #{$fa-icon-property}: unquote("\"#{ $fa-var-down-long }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-long-arrow-up { #{$fa-icon-property}: unquote("\"#{ $fa-var-up-long }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-long-arrow-left { #{$fa-icon-property}: unquote("\"#{ $fa-var-left-long }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-long-arrow-right { #{$fa-icon-property}: unquote("\"#{ $fa-var-right-long }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-apple { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-windows { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-android { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-linux { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-dribbble { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-skype { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-foursquare { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-trello { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-gratipay { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-gittip { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-gittip { #{$fa-icon-property}: unquote("\"#{ $fa-var-gratipay }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-sun-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-sun-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-sun }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-moon-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-moon-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-moon }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-vk { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-weibo { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-renren { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-pagelines { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-stack-exchange { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-right { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-right { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle-right }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-left { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-arrow-circle-o-left { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle-left }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-left { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-caret-square-o-left { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-caret-left }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-left { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-toggle-left { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-caret-left }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-dot-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-dot-circle-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle-dot }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-vimeo-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-vimeo-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-vimeo }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-try { #{$fa-icon-property}: unquote("\"#{ $fa-var-turkish-lira-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-turkish-lira { #{$fa-icon-property}: unquote("\"#{ $fa-var-turkish-lira-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-plus-square-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-plus-square-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-plus }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-slack { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-wordpress { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-openid { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-institution { #{$fa-icon-property}: unquote("\"#{ $fa-var-building-columns }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-bank { #{$fa-icon-property}: unquote("\"#{ $fa-var-building-columns }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-mortar-board { #{$fa-icon-property}: unquote("\"#{ $fa-var-graduation-cap }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-yahoo { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-google { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-reddit { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-reddit-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-reddit-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-reddit }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-stumbleupon-circle { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-stumbleupon { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-delicious { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-digg { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-pied-piper-pp { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-pied-piper-alt { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-drupal { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-joomla { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-behance { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-behance-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-behance-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-behance }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-steam { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-steam-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-steam-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-steam }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-automobile { #{$fa-icon-property}: unquote("\"#{ $fa-var-car }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-cab { #{$fa-icon-property}: unquote("\"#{ $fa-var-taxi }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-spotify { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-deviantart { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-soundcloud { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-pdf-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-pdf-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-pdf }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-word-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-word-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-word }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-excel-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-excel-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-excel }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-powerpoint-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-powerpoint-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-powerpoint }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-image-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-image-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-image }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-photo-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-photo-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-image }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-picture-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-picture-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-image }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-archive-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-archive-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-zipper }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-zip-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-zip-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-zipper }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-audio-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-audio-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-audio }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-sound-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-sound-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-audio }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-video-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-video-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-video }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-movie-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-movie-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-video }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-code-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-file-code-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-file-code }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-vine { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-codepen { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-jsfiddle { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-life-bouy { #{$fa-icon-property}: unquote("\"#{ $fa-var-life-ring }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-life-buoy { #{$fa-icon-property}: unquote("\"#{ $fa-var-life-ring }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-life-saver { #{$fa-icon-property}: unquote("\"#{ $fa-var-life-ring }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-support { #{$fa-icon-property}: unquote("\"#{ $fa-var-life-ring }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-o-notch { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle-notch }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-rebel { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-ra { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-ra { #{$fa-icon-property}: unquote("\"#{ $fa-var-rebel }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-resistance { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-resistance { #{$fa-icon-property}: unquote("\"#{ $fa-var-rebel }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-empire { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-ge { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-ge { #{$fa-icon-property}: unquote("\"#{ $fa-var-empire }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-git-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-git-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-git }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-git { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hacker-news { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-y-combinator-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-y-combinator-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-hacker-news }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-yc-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-yc-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-hacker-news }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-tencent-weibo { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-qq { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-weixin { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-wechat { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-wechat { #{$fa-icon-property}: unquote("\"#{ $fa-var-weixin }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-send { #{$fa-icon-property}: unquote("\"#{ $fa-var-paper-plane }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-paper-plane-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-paper-plane-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-paper-plane }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-send-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-send-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-paper-plane }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-thin { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-circle-thin { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-header { #{$fa-icon-property}: unquote("\"#{ $fa-var-heading }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-futbol-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-futbol-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-futbol }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-soccer-ball-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-soccer-ball-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-futbol }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-slideshare { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-twitch { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-yelp { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-newspaper-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-newspaper-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-newspaper }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-paypal { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-wallet { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-visa { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-mastercard { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-discover { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-amex { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-paypal { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-stripe { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bell-slash-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bell-slash-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-bell-slash }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-trash { #{$fa-icon-property}: unquote("\"#{ $fa-var-trash-can }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-copyright { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-eyedropper { #{$fa-icon-property}: unquote("\"#{ $fa-var-eye-dropper }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-area-chart { #{$fa-icon-property}: unquote("\"#{ $fa-var-chart-area }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-pie-chart { #{$fa-icon-property}: unquote("\"#{ $fa-var-chart-pie }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-line-chart { #{$fa-icon-property}: unquote("\"#{ $fa-var-chart-line }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-lastfm { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-lastfm-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-lastfm-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-lastfm }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-ioxhost { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-angellist { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc { #{$fa-icon-property}: unquote("\"#{ $fa-var-closed-captioning }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-ils { #{$fa-icon-property}: unquote("\"#{ $fa-var-shekel-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-shekel { #{$fa-icon-property}: unquote("\"#{ $fa-var-shekel-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-sheqel { #{$fa-icon-property}: unquote("\"#{ $fa-var-shekel-sign }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-buysellads { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-connectdevelop { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-dashcube { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-forumbee { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-leanpub { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-sellsy { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-shirtsinbulk { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-simplybuilt { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-skyatlas { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-diamond { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-diamond { #{$fa-icon-property}: unquote("\"#{ $fa-var-gem }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-transgender { #{$fa-icon-property}: unquote("\"#{ $fa-var-mars-and-venus }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-intersex { #{$fa-icon-property}: unquote("\"#{ $fa-var-mars-and-venus }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-transgender-alt { #{$fa-icon-property}: unquote("\"#{ $fa-var-transgender }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-official { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-facebook-official { #{$fa-icon-property}: unquote("\"#{ $fa-var-facebook }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-pinterest-p { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-whatsapp { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hotel { #{$fa-icon-property}: unquote("\"#{ $fa-var-bed }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-viacoin { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-medium { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-y-combinator { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-yc { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-yc { #{$fa-icon-property}: unquote("\"#{ $fa-var-y-combinator }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-optin-monster { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-opencart { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-expeditedssl { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-4 { #{$fa-icon-property}: unquote("\"#{ $fa-var-battery-full }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-battery { #{$fa-icon-property}: unquote("\"#{ $fa-var-battery-full }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-3 { #{$fa-icon-property}: unquote("\"#{ $fa-var-battery-three-quarters }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-2 { #{$fa-icon-property}: unquote("\"#{ $fa-var-battery-half }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-1 { #{$fa-icon-property}: unquote("\"#{ $fa-var-battery-quarter }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-battery-0 { #{$fa-icon-property}: unquote("\"#{ $fa-var-battery-empty }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-object-group { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-object-ungroup { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-sticky-note-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-sticky-note-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-note-sticky }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-jcb { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-cc-diners-club { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-clone { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-hourglass }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-1 { #{$fa-icon-property}: unquote("\"#{ $fa-var-hourglass-start }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-2 { #{$fa-icon-property}: unquote("\"#{ $fa-var-hourglass-half }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hourglass-3 { #{$fa-icon-property}: unquote("\"#{ $fa-var-hourglass-end }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-rock-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-rock-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-hand-back-fist }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-grab-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-grab-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-hand-back-fist }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-paper-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-paper-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-hand }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-stop-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-stop-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-hand }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-scissors-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-scissors-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-hand-scissors }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-lizard-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-lizard-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-hand-lizard }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-spock-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-spock-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-hand-spock }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-pointer-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-pointer-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-hand-pointer }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-peace-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-hand-peace-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-hand-peace }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-registered { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-creative-commons { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-gg { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-gg-circle { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-odnoklassniki { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-odnoklassniki-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-odnoklassniki-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-odnoklassniki }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-get-pocket { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-wikipedia-w { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-safari { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-chrome { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-firefox { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-opera { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-internet-explorer { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-television { #{$fa-icon-property}: unquote("\"#{ $fa-var-tv }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-contao { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-500px { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-amazon { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-plus-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-plus-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-calendar-plus }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-minus-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-minus-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-calendar-minus }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-times-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-times-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-calendar-xmark }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-check-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-calendar-check-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-calendar-check }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-map-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-map-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-map }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-commenting { #{$fa-icon-property}: unquote("\"#{ $fa-var-comment-dots }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-commenting-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-commenting-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-comment-dots }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-houzz { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-vimeo { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-vimeo { #{$fa-icon-property}: unquote("\"#{ $fa-var-vimeo-v }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-black-tie { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-fonticons { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-reddit-alien { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-edge { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-credit-card-alt { #{$fa-icon-property}: unquote("\"#{ $fa-var-credit-card }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-codiepie { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-modx { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-fort-awesome { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-usb { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-product-hunt { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-mixcloud { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-scribd { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-pause-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-pause-circle-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle-pause }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-stop-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-stop-circle-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle-stop }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-bluetooth { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-bluetooth-b { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-gitlab { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-wpbeginner { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-wpforms { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-envira { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-wheelchair-alt { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-wheelchair-alt { #{$fa-icon-property}: unquote("\"#{ $fa-var-accessible-icon }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-question-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-question-circle-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle-question }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-volume-control-phone { #{$fa-icon-property}: unquote("\"#{ $fa-var-phone-volume }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-asl-interpreting { #{$fa-icon-property}: unquote("\"#{ $fa-var-hands-asl-interpreting }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-deafness { #{$fa-icon-property}: unquote("\"#{ $fa-var-ear-deaf }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-hard-of-hearing { #{$fa-icon-property}: unquote("\"#{ $fa-var-ear-deaf }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-glide { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-glide-g { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-signing { #{$fa-icon-property}: unquote("\"#{ $fa-var-hands }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-viadeo { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-viadeo-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-viadeo-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-viadeo }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-snapchat { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-snapchat-ghost { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-snapchat-ghost { #{$fa-icon-property}: unquote("\"#{ $fa-var-snapchat }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-snapchat-square { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-snapchat-square { #{$fa-icon-property}: unquote("\"#{ $fa-var-square-snapchat }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-pied-piper { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-first-order { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-yoast { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-themeisle { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-official { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-official { #{$fa-icon-property}: unquote("\"#{ $fa-var-google-plus }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-circle { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-google-plus-circle { #{$fa-icon-property}: unquote("\"#{ $fa-var-google-plus }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-font-awesome { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-fa { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-fa { #{$fa-icon-property}: unquote("\"#{ $fa-var-font-awesome }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-handshake-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-handshake-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-handshake }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-envelope-open-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-envelope-open-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-envelope-open }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-linode { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-address-book-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-address-book-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-address-book }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-vcard { #{$fa-icon-property}: unquote("\"#{ $fa-var-address-card }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-address-card-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-address-card-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-address-card }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-vcard-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-vcard-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-address-card }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-user-circle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-user-circle-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-circle-user }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-user-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-user-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-user }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-id-badge { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-drivers-license { #{$fa-icon-property}: unquote("\"#{ $fa-var-id-card }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-id-card-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-id-card-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-id-card }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-drivers-license-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-drivers-license-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-id-card }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-quora { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-free-code-camp { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-telegram { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-4 { #{$fa-icon-property}: unquote("\"#{ $fa-var-temperature-full }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer { #{$fa-icon-property}: unquote("\"#{ $fa-var-temperature-full }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-3 { #{$fa-icon-property}: unquote("\"#{ $fa-var-temperature-three-quarters }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-2 { #{$fa-icon-property}: unquote("\"#{ $fa-var-temperature-half }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-1 { #{$fa-icon-property}: unquote("\"#{ $fa-var-temperature-quarter }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-thermometer-0 { #{$fa-icon-property}: unquote("\"#{ $fa-var-temperature-empty }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-bathtub { #{$fa-icon-property}: unquote("\"#{ $fa-var-bath }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-s15 { #{$fa-icon-property}: unquote("\"#{ $fa-var-bath }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-window-maximize { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-window-restore { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-times-rectangle { #{$fa-icon-property}: unquote("\"#{ $fa-var-rectangle-xmark }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-window-close-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-window-close-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-rectangle-xmark }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-times-rectangle-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-times-rectangle-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-rectangle-xmark }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-bandcamp { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-grav { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-etsy { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-imdb { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-ravelry { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-eercast { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-eercast { #{$fa-icon-property}: unquote("\"#{ $fa-var-sellcast }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-snowflake-o { + font-family: 'Font Awesome 6 Free'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-snowflake-o { #{$fa-icon-property}: unquote("\"#{ $fa-var-snowflake }\""); } +.#{$fa-css-prefix}.#{$fa-css-prefix}-superpowers { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-wpexplorer { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} +.#{$fa-css-prefix}.#{$fa-css-prefix}-meetup { + font-family: 'Font Awesome 6 Brands'; + font-weight: 400; +} diff --git a/src/sass/fontawesome/_sizing.scss b/src/sass/fontawesome/_sizing.scss new file mode 100644 index 0000000..e171e7d --- /dev/null +++ b/src/sass/fontawesome/_sizing.scss @@ -0,0 +1,16 @@ +// sizing icons +// ------------------------- + +// literal magnification scale +@for $i from 1 through 10 { + .#{$fa-css-prefix}-#{$i}x { + font-size: $i * 1em; + } +} + +// step-based scale (with alignment) +@each $size, $value in $fa-sizes { + .#{$fa-css-prefix}-#{$size} { + @include fa-size($value); + } +} diff --git a/src/sass/fontawesome/_stacked.scss b/src/sass/fontawesome/_stacked.scss new file mode 100644 index 0000000..d9a9d4e --- /dev/null +++ b/src/sass/fontawesome/_stacked.scss @@ -0,0 +1,32 @@ +// stacking icons +// ------------------------- + +.#{$fa-css-prefix}-stack { + display: inline-block; + height: 2em; + line-height: 2em; + position: relative; + vertical-align: $fa-stack-vertical-align; + width: $fa-stack-width; +} + +.#{$fa-css-prefix}-stack-1x, +.#{$fa-css-prefix}-stack-2x { + left: 0; + position: absolute; + text-align: center; + width: 100%; + z-index: var(--#{$fa-css-prefix}-stack-z-index, #{$fa-stack-z-index}); +} + +.#{$fa-css-prefix}-stack-1x { + line-height: inherit; +} + +.#{$fa-css-prefix}-stack-2x { + font-size: 2em; +} + +.#{$fa-css-prefix}-inverse { + color: var(--#{$fa-css-prefix}-inverse, #{$fa-inverse}); +} diff --git a/src/sass/fontawesome/_variables.scss b/src/sass/fontawesome/_variables.scss new file mode 100644 index 0000000..87d19d3 --- /dev/null +++ b/src/sass/fontawesome/_variables.scss @@ -0,0 +1,5044 @@ +// variables +// -------------------------- + +$fa-css-prefix : fa !default; +$fa-style : 900 !default; +$fa-style-family : "Font Awesome 6 Free" !default; + +$fa-icon-property : --fa; +$fa-duotone-icon-property : --fa--fa; + +$fa-display : inline-block !default; + +$fa-fw-width : fa-divide(20em, 16) !default; +$fa-inverse : #fff !default; + +$fa-border-color : #eee !default; +$fa-border-padding : .2em .25em .15em !default; +$fa-border-radius : .1em !default; +$fa-border-style : solid !default; +$fa-border-width : .08em !default; + +$fa-size-scale-2xs : 10 !default; +$fa-size-scale-xs : 12 !default; +$fa-size-scale-sm : 14 !default; +$fa-size-scale-base : 16 !default; +$fa-size-scale-lg : 20 !default; +$fa-size-scale-xl : 24 !default; +$fa-size-scale-2xl : 32 !default; + +$fa-sizes: ( + "2xs" : $fa-size-scale-2xs, + "xs" : $fa-size-scale-xs, + "sm" : $fa-size-scale-sm, + "lg" : $fa-size-scale-lg, + "xl" : $fa-size-scale-xl, + "2xl" : $fa-size-scale-2xl +) !default; + +$fa-li-width : 2em !default; +$fa-li-margin : $fa-li-width * fa-divide(5, 4) !default; + +$fa-pull-margin : .3em !default; + +$fa-primary-opacity : 1 !default; +$fa-secondary-opacity : .4 !default; + +$fa-stack-vertical-align : middle !default; +$fa-stack-width : ($fa-fw-width * 2) !default; +$fa-stack-z-index : auto !default; + +$fa-font-display : block !default; +$fa-font-path : "../../webfonts" !default; + +$fa-var-0: \30; +$fa-var-1: \31; +$fa-var-2: \32; +$fa-var-3: \33; +$fa-var-4: \34; +$fa-var-5: \35; +$fa-var-6: \36; +$fa-var-7: \37; +$fa-var-8: \38; +$fa-var-9: \39; +$fa-var-fill-drip: \f576; +$fa-var-arrows-to-circle: \e4bd; +$fa-var-circle-chevron-right: \f138; +$fa-var-chevron-circle-right: \f138; +$fa-var-at: \40; +$fa-var-trash-can: \f2ed; +$fa-var-trash-alt: \f2ed; +$fa-var-text-height: \f034; +$fa-var-user-xmark: \f235; +$fa-var-user-times: \f235; +$fa-var-stethoscope: \f0f1; +$fa-var-message: \f27a; +$fa-var-comment-alt: \f27a; +$fa-var-info: \f129; +$fa-var-down-left-and-up-right-to-center: \f422; +$fa-var-compress-alt: \f422; +$fa-var-explosion: \e4e9; +$fa-var-file-lines: \f15c; +$fa-var-file-alt: \f15c; +$fa-var-file-text: \f15c; +$fa-var-wave-square: \f83e; +$fa-var-ring: \f70b; +$fa-var-building-un: \e4d9; +$fa-var-dice-three: \f527; +$fa-var-calendar-days: \f073; +$fa-var-calendar-alt: \f073; +$fa-var-anchor-circle-check: \e4aa; +$fa-var-building-circle-arrow-right: \e4d1; +$fa-var-volleyball: \f45f; +$fa-var-volleyball-ball: \f45f; +$fa-var-arrows-up-to-line: \e4c2; +$fa-var-sort-down: \f0dd; +$fa-var-sort-desc: \f0dd; +$fa-var-circle-minus: \f056; +$fa-var-minus-circle: \f056; +$fa-var-door-open: \f52b; +$fa-var-right-from-bracket: \f2f5; +$fa-var-sign-out-alt: \f2f5; +$fa-var-atom: \f5d2; +$fa-var-soap: \e06e; +$fa-var-icons: \f86d; +$fa-var-heart-music-camera-bolt: \f86d; +$fa-var-microphone-lines-slash: \f539; +$fa-var-microphone-alt-slash: \f539; +$fa-var-bridge-circle-check: \e4c9; +$fa-var-pump-medical: \e06a; +$fa-var-fingerprint: \f577; +$fa-var-hand-point-right: \f0a4; +$fa-var-magnifying-glass-location: \f689; +$fa-var-search-location: \f689; +$fa-var-forward-step: \f051; +$fa-var-step-forward: \f051; +$fa-var-face-smile-beam: \f5b8; +$fa-var-smile-beam: \f5b8; +$fa-var-flag-checkered: \f11e; +$fa-var-football: \f44e; +$fa-var-football-ball: \f44e; +$fa-var-school-circle-exclamation: \e56c; +$fa-var-crop: \f125; +$fa-var-angles-down: \f103; +$fa-var-angle-double-down: \f103; +$fa-var-users-rectangle: \e594; +$fa-var-people-roof: \e537; +$fa-var-people-line: \e534; +$fa-var-beer-mug-empty: \f0fc; +$fa-var-beer: \f0fc; +$fa-var-diagram-predecessor: \e477; +$fa-var-arrow-up-long: \f176; +$fa-var-long-arrow-up: \f176; +$fa-var-fire-flame-simple: \f46a; +$fa-var-burn: \f46a; +$fa-var-person: \f183; +$fa-var-male: \f183; +$fa-var-laptop: \f109; +$fa-var-file-csv: \f6dd; +$fa-var-menorah: \f676; +$fa-var-truck-plane: \e58f; +$fa-var-record-vinyl: \f8d9; +$fa-var-face-grin-stars: \f587; +$fa-var-grin-stars: \f587; +$fa-var-bong: \f55c; +$fa-var-spaghetti-monster-flying: \f67b; +$fa-var-pastafarianism: \f67b; +$fa-var-arrow-down-up-across-line: \e4af; +$fa-var-spoon: \f2e5; +$fa-var-utensil-spoon: \f2e5; +$fa-var-jar-wheat: \e517; +$fa-var-envelopes-bulk: \f674; +$fa-var-mail-bulk: \f674; +$fa-var-file-circle-exclamation: \e4eb; +$fa-var-circle-h: \f47e; +$fa-var-hospital-symbol: \f47e; +$fa-var-pager: \f815; +$fa-var-address-book: \f2b9; +$fa-var-contact-book: \f2b9; +$fa-var-strikethrough: \f0cc; +$fa-var-k: \4b; +$fa-var-landmark-flag: \e51c; +$fa-var-pencil: \f303; +$fa-var-pencil-alt: \f303; +$fa-var-backward: \f04a; +$fa-var-caret-right: \f0da; +$fa-var-comments: \f086; +$fa-var-paste: \f0ea; +$fa-var-file-clipboard: \f0ea; +$fa-var-code-pull-request: \e13c; +$fa-var-clipboard-list: \f46d; +$fa-var-truck-ramp-box: \f4de; +$fa-var-truck-loading: \f4de; +$fa-var-user-check: \f4fc; +$fa-var-vial-virus: \e597; +$fa-var-sheet-plastic: \e571; +$fa-var-blog: \f781; +$fa-var-user-ninja: \f504; +$fa-var-person-arrow-up-from-line: \e539; +$fa-var-scroll-torah: \f6a0; +$fa-var-torah: \f6a0; +$fa-var-broom-ball: \f458; +$fa-var-quidditch: \f458; +$fa-var-quidditch-broom-ball: \f458; +$fa-var-toggle-off: \f204; +$fa-var-box-archive: \f187; +$fa-var-archive: \f187; +$fa-var-person-drowning: \e545; +$fa-var-arrow-down-9-1: \f886; +$fa-var-sort-numeric-desc: \f886; +$fa-var-sort-numeric-down-alt: \f886; +$fa-var-face-grin-tongue-squint: \f58a; +$fa-var-grin-tongue-squint: \f58a; +$fa-var-spray-can: \f5bd; +$fa-var-truck-monster: \f63b; +$fa-var-w: \57; +$fa-var-earth-africa: \f57c; +$fa-var-globe-africa: \f57c; +$fa-var-rainbow: \f75b; +$fa-var-circle-notch: \f1ce; +$fa-var-tablet-screen-button: \f3fa; +$fa-var-tablet-alt: \f3fa; +$fa-var-paw: \f1b0; +$fa-var-cloud: \f0c2; +$fa-var-trowel-bricks: \e58a; +$fa-var-face-flushed: \f579; +$fa-var-flushed: \f579; +$fa-var-hospital-user: \f80d; +$fa-var-tent-arrow-left-right: \e57f; +$fa-var-gavel: \f0e3; +$fa-var-legal: \f0e3; +$fa-var-binoculars: \f1e5; +$fa-var-microphone-slash: \f131; +$fa-var-box-tissue: \e05b; +$fa-var-motorcycle: \f21c; +$fa-var-bell-concierge: \f562; +$fa-var-concierge-bell: \f562; +$fa-var-pen-ruler: \f5ae; +$fa-var-pencil-ruler: \f5ae; +$fa-var-people-arrows: \e068; +$fa-var-people-arrows-left-right: \e068; +$fa-var-mars-and-venus-burst: \e523; +$fa-var-square-caret-right: \f152; +$fa-var-caret-square-right: \f152; +$fa-var-scissors: \f0c4; +$fa-var-cut: \f0c4; +$fa-var-sun-plant-wilt: \e57a; +$fa-var-toilets-portable: \e584; +$fa-var-hockey-puck: \f453; +$fa-var-table: \f0ce; +$fa-var-magnifying-glass-arrow-right: \e521; +$fa-var-tachograph-digital: \f566; +$fa-var-digital-tachograph: \f566; +$fa-var-users-slash: \e073; +$fa-var-clover: \e139; +$fa-var-reply: \f3e5; +$fa-var-mail-reply: \f3e5; +$fa-var-star-and-crescent: \f699; +$fa-var-house-fire: \e50c; +$fa-var-square-minus: \f146; +$fa-var-minus-square: \f146; +$fa-var-helicopter: \f533; +$fa-var-compass: \f14e; +$fa-var-square-caret-down: \f150; +$fa-var-caret-square-down: \f150; +$fa-var-file-circle-question: \e4ef; +$fa-var-laptop-code: \f5fc; +$fa-var-swatchbook: \f5c3; +$fa-var-prescription-bottle: \f485; +$fa-var-bars: \f0c9; +$fa-var-navicon: \f0c9; +$fa-var-people-group: \e533; +$fa-var-hourglass-end: \f253; +$fa-var-hourglass-3: \f253; +$fa-var-heart-crack: \f7a9; +$fa-var-heart-broken: \f7a9; +$fa-var-square-up-right: \f360; +$fa-var-external-link-square-alt: \f360; +$fa-var-face-kiss-beam: \f597; +$fa-var-kiss-beam: \f597; +$fa-var-film: \f008; +$fa-var-ruler-horizontal: \f547; +$fa-var-people-robbery: \e536; +$fa-var-lightbulb: \f0eb; +$fa-var-caret-left: \f0d9; +$fa-var-circle-exclamation: \f06a; +$fa-var-exclamation-circle: \f06a; +$fa-var-school-circle-xmark: \e56d; +$fa-var-arrow-right-from-bracket: \f08b; +$fa-var-sign-out: \f08b; +$fa-var-circle-chevron-down: \f13a; +$fa-var-chevron-circle-down: \f13a; +$fa-var-unlock-keyhole: \f13e; +$fa-var-unlock-alt: \f13e; +$fa-var-cloud-showers-heavy: \f740; +$fa-var-headphones-simple: \f58f; +$fa-var-headphones-alt: \f58f; +$fa-var-sitemap: \f0e8; +$fa-var-circle-dollar-to-slot: \f4b9; +$fa-var-donate: \f4b9; +$fa-var-memory: \f538; +$fa-var-road-spikes: \e568; +$fa-var-fire-burner: \e4f1; +$fa-var-flag: \f024; +$fa-var-hanukiah: \f6e6; +$fa-var-feather: \f52d; +$fa-var-volume-low: \f027; +$fa-var-volume-down: \f027; +$fa-var-comment-slash: \f4b3; +$fa-var-cloud-sun-rain: \f743; +$fa-var-compress: \f066; +$fa-var-wheat-awn: \e2cd; +$fa-var-wheat-alt: \e2cd; +$fa-var-ankh: \f644; +$fa-var-hands-holding-child: \e4fa; +$fa-var-asterisk: \2a; +$fa-var-square-check: \f14a; +$fa-var-check-square: \f14a; +$fa-var-peseta-sign: \e221; +$fa-var-heading: \f1dc; +$fa-var-header: \f1dc; +$fa-var-ghost: \f6e2; +$fa-var-list: \f03a; +$fa-var-list-squares: \f03a; +$fa-var-square-phone-flip: \f87b; +$fa-var-phone-square-alt: \f87b; +$fa-var-cart-plus: \f217; +$fa-var-gamepad: \f11b; +$fa-var-circle-dot: \f192; +$fa-var-dot-circle: \f192; +$fa-var-face-dizzy: \f567; +$fa-var-dizzy: \f567; +$fa-var-egg: \f7fb; +$fa-var-house-medical-circle-xmark: \e513; +$fa-var-campground: \f6bb; +$fa-var-folder-plus: \f65e; +$fa-var-futbol: \f1e3; +$fa-var-futbol-ball: \f1e3; +$fa-var-soccer-ball: \f1e3; +$fa-var-paintbrush: \f1fc; +$fa-var-paint-brush: \f1fc; +$fa-var-lock: \f023; +$fa-var-gas-pump: \f52f; +$fa-var-hot-tub-person: \f593; +$fa-var-hot-tub: \f593; +$fa-var-map-location: \f59f; +$fa-var-map-marked: \f59f; +$fa-var-house-flood-water: \e50e; +$fa-var-tree: \f1bb; +$fa-var-bridge-lock: \e4cc; +$fa-var-sack-dollar: \f81d; +$fa-var-pen-to-square: \f044; +$fa-var-edit: \f044; +$fa-var-car-side: \f5e4; +$fa-var-share-nodes: \f1e0; +$fa-var-share-alt: \f1e0; +$fa-var-heart-circle-minus: \e4ff; +$fa-var-hourglass-half: \f252; +$fa-var-hourglass-2: \f252; +$fa-var-microscope: \f610; +$fa-var-sink: \e06d; +$fa-var-bag-shopping: \f290; +$fa-var-shopping-bag: \f290; +$fa-var-arrow-down-z-a: \f881; +$fa-var-sort-alpha-desc: \f881; +$fa-var-sort-alpha-down-alt: \f881; +$fa-var-mitten: \f7b5; +$fa-var-person-rays: \e54d; +$fa-var-users: \f0c0; +$fa-var-eye-slash: \f070; +$fa-var-flask-vial: \e4f3; +$fa-var-hand: \f256; +$fa-var-hand-paper: \f256; +$fa-var-om: \f679; +$fa-var-worm: \e599; +$fa-var-house-circle-xmark: \e50b; +$fa-var-plug: \f1e6; +$fa-var-chevron-up: \f077; +$fa-var-hand-spock: \f259; +$fa-var-stopwatch: \f2f2; +$fa-var-face-kiss: \f596; +$fa-var-kiss: \f596; +$fa-var-bridge-circle-xmark: \e4cb; +$fa-var-face-grin-tongue: \f589; +$fa-var-grin-tongue: \f589; +$fa-var-chess-bishop: \f43a; +$fa-var-face-grin-wink: \f58c; +$fa-var-grin-wink: \f58c; +$fa-var-ear-deaf: \f2a4; +$fa-var-deaf: \f2a4; +$fa-var-deafness: \f2a4; +$fa-var-hard-of-hearing: \f2a4; +$fa-var-road-circle-check: \e564; +$fa-var-dice-five: \f523; +$fa-var-square-rss: \f143; +$fa-var-rss-square: \f143; +$fa-var-land-mine-on: \e51b; +$fa-var-i-cursor: \f246; +$fa-var-stamp: \f5bf; +$fa-var-stairs: \e289; +$fa-var-i: \49; +$fa-var-hryvnia-sign: \f6f2; +$fa-var-hryvnia: \f6f2; +$fa-var-pills: \f484; +$fa-var-face-grin-wide: \f581; +$fa-var-grin-alt: \f581; +$fa-var-tooth: \f5c9; +$fa-var-v: \56; +$fa-var-bangladeshi-taka-sign: \e2e6; +$fa-var-bicycle: \f206; +$fa-var-staff-snake: \e579; +$fa-var-rod-asclepius: \e579; +$fa-var-rod-snake: \e579; +$fa-var-staff-aesculapius: \e579; +$fa-var-head-side-cough-slash: \e062; +$fa-var-truck-medical: \f0f9; +$fa-var-ambulance: \f0f9; +$fa-var-wheat-awn-circle-exclamation: \e598; +$fa-var-snowman: \f7d0; +$fa-var-mortar-pestle: \f5a7; +$fa-var-road-barrier: \e562; +$fa-var-school: \f549; +$fa-var-igloo: \f7ae; +$fa-var-joint: \f595; +$fa-var-angle-right: \f105; +$fa-var-horse: \f6f0; +$fa-var-q: \51; +$fa-var-g: \47; +$fa-var-notes-medical: \f481; +$fa-var-temperature-half: \f2c9; +$fa-var-temperature-2: \f2c9; +$fa-var-thermometer-2: \f2c9; +$fa-var-thermometer-half: \f2c9; +$fa-var-dong-sign: \e169; +$fa-var-capsules: \f46b; +$fa-var-poo-storm: \f75a; +$fa-var-poo-bolt: \f75a; +$fa-var-face-frown-open: \f57a; +$fa-var-frown-open: \f57a; +$fa-var-hand-point-up: \f0a6; +$fa-var-money-bill: \f0d6; +$fa-var-bookmark: \f02e; +$fa-var-align-justify: \f039; +$fa-var-umbrella-beach: \f5ca; +$fa-var-helmet-un: \e503; +$fa-var-bullseye: \f140; +$fa-var-bacon: \f7e5; +$fa-var-hand-point-down: \f0a7; +$fa-var-arrow-up-from-bracket: \e09a; +$fa-var-folder: \f07b; +$fa-var-folder-blank: \f07b; +$fa-var-file-waveform: \f478; +$fa-var-file-medical-alt: \f478; +$fa-var-radiation: \f7b9; +$fa-var-chart-simple: \e473; +$fa-var-mars-stroke: \f229; +$fa-var-vial: \f492; +$fa-var-gauge: \f624; +$fa-var-dashboard: \f624; +$fa-var-gauge-med: \f624; +$fa-var-tachometer-alt-average: \f624; +$fa-var-wand-magic-sparkles: \e2ca; +$fa-var-magic-wand-sparkles: \e2ca; +$fa-var-e: \45; +$fa-var-pen-clip: \f305; +$fa-var-pen-alt: \f305; +$fa-var-bridge-circle-exclamation: \e4ca; +$fa-var-user: \f007; +$fa-var-school-circle-check: \e56b; +$fa-var-dumpster: \f793; +$fa-var-van-shuttle: \f5b6; +$fa-var-shuttle-van: \f5b6; +$fa-var-building-user: \e4da; +$fa-var-square-caret-left: \f191; +$fa-var-caret-square-left: \f191; +$fa-var-highlighter: \f591; +$fa-var-key: \f084; +$fa-var-bullhorn: \f0a1; +$fa-var-globe: \f0ac; +$fa-var-synagogue: \f69b; +$fa-var-person-half-dress: \e548; +$fa-var-road-bridge: \e563; +$fa-var-location-arrow: \f124; +$fa-var-c: \43; +$fa-var-tablet-button: \f10a; +$fa-var-building-lock: \e4d6; +$fa-var-pizza-slice: \f818; +$fa-var-money-bill-wave: \f53a; +$fa-var-chart-area: \f1fe; +$fa-var-area-chart: \f1fe; +$fa-var-house-flag: \e50d; +$fa-var-person-circle-minus: \e540; +$fa-var-ban: \f05e; +$fa-var-cancel: \f05e; +$fa-var-camera-rotate: \e0d8; +$fa-var-spray-can-sparkles: \f5d0; +$fa-var-air-freshener: \f5d0; +$fa-var-star: \f005; +$fa-var-repeat: \f363; +$fa-var-cross: \f654; +$fa-var-box: \f466; +$fa-var-venus-mars: \f228; +$fa-var-arrow-pointer: \f245; +$fa-var-mouse-pointer: \f245; +$fa-var-maximize: \f31e; +$fa-var-expand-arrows-alt: \f31e; +$fa-var-charging-station: \f5e7; +$fa-var-shapes: \f61f; +$fa-var-triangle-circle-square: \f61f; +$fa-var-shuffle: \f074; +$fa-var-random: \f074; +$fa-var-person-running: \f70c; +$fa-var-running: \f70c; +$fa-var-mobile-retro: \e527; +$fa-var-grip-lines-vertical: \f7a5; +$fa-var-spider: \f717; +$fa-var-hands-bound: \e4f9; +$fa-var-file-invoice-dollar: \f571; +$fa-var-plane-circle-exclamation: \e556; +$fa-var-x-ray: \f497; +$fa-var-spell-check: \f891; +$fa-var-slash: \f715; +$fa-var-computer-mouse: \f8cc; +$fa-var-mouse: \f8cc; +$fa-var-arrow-right-to-bracket: \f090; +$fa-var-sign-in: \f090; +$fa-var-shop-slash: \e070; +$fa-var-store-alt-slash: \e070; +$fa-var-server: \f233; +$fa-var-virus-covid-slash: \e4a9; +$fa-var-shop-lock: \e4a5; +$fa-var-hourglass-start: \f251; +$fa-var-hourglass-1: \f251; +$fa-var-blender-phone: \f6b6; +$fa-var-building-wheat: \e4db; +$fa-var-person-breastfeeding: \e53a; +$fa-var-right-to-bracket: \f2f6; +$fa-var-sign-in-alt: \f2f6; +$fa-var-venus: \f221; +$fa-var-passport: \f5ab; +$fa-var-thumbtack-slash: \e68f; +$fa-var-thumb-tack-slash: \e68f; +$fa-var-heart-pulse: \f21e; +$fa-var-heartbeat: \f21e; +$fa-var-people-carry-box: \f4ce; +$fa-var-people-carry: \f4ce; +$fa-var-temperature-high: \f769; +$fa-var-microchip: \f2db; +$fa-var-crown: \f521; +$fa-var-weight-hanging: \f5cd; +$fa-var-xmarks-lines: \e59a; +$fa-var-file-prescription: \f572; +$fa-var-weight-scale: \f496; +$fa-var-weight: \f496; +$fa-var-user-group: \f500; +$fa-var-user-friends: \f500; +$fa-var-arrow-up-a-z: \f15e; +$fa-var-sort-alpha-up: \f15e; +$fa-var-chess-knight: \f441; +$fa-var-face-laugh-squint: \f59b; +$fa-var-laugh-squint: \f59b; +$fa-var-wheelchair: \f193; +$fa-var-circle-arrow-up: \f0aa; +$fa-var-arrow-circle-up: \f0aa; +$fa-var-toggle-on: \f205; +$fa-var-person-walking: \f554; +$fa-var-walking: \f554; +$fa-var-l: \4c; +$fa-var-fire: \f06d; +$fa-var-bed-pulse: \f487; +$fa-var-procedures: \f487; +$fa-var-shuttle-space: \f197; +$fa-var-space-shuttle: \f197; +$fa-var-face-laugh: \f599; +$fa-var-laugh: \f599; +$fa-var-folder-open: \f07c; +$fa-var-heart-circle-plus: \e500; +$fa-var-code-fork: \e13b; +$fa-var-city: \f64f; +$fa-var-microphone-lines: \f3c9; +$fa-var-microphone-alt: \f3c9; +$fa-var-pepper-hot: \f816; +$fa-var-unlock: \f09c; +$fa-var-colon-sign: \e140; +$fa-var-headset: \f590; +$fa-var-store-slash: \e071; +$fa-var-road-circle-xmark: \e566; +$fa-var-user-minus: \f503; +$fa-var-mars-stroke-up: \f22a; +$fa-var-mars-stroke-v: \f22a; +$fa-var-champagne-glasses: \f79f; +$fa-var-glass-cheers: \f79f; +$fa-var-clipboard: \f328; +$fa-var-house-circle-exclamation: \e50a; +$fa-var-file-arrow-up: \f574; +$fa-var-file-upload: \f574; +$fa-var-wifi: \f1eb; +$fa-var-wifi-3: \f1eb; +$fa-var-wifi-strong: \f1eb; +$fa-var-bath: \f2cd; +$fa-var-bathtub: \f2cd; +$fa-var-underline: \f0cd; +$fa-var-user-pen: \f4ff; +$fa-var-user-edit: \f4ff; +$fa-var-signature: \f5b7; +$fa-var-stroopwafel: \f551; +$fa-var-bold: \f032; +$fa-var-anchor-lock: \e4ad; +$fa-var-building-ngo: \e4d7; +$fa-var-manat-sign: \e1d5; +$fa-var-not-equal: \f53e; +$fa-var-border-top-left: \f853; +$fa-var-border-style: \f853; +$fa-var-map-location-dot: \f5a0; +$fa-var-map-marked-alt: \f5a0; +$fa-var-jedi: \f669; +$fa-var-square-poll-vertical: \f681; +$fa-var-poll: \f681; +$fa-var-mug-hot: \f7b6; +$fa-var-car-battery: \f5df; +$fa-var-battery-car: \f5df; +$fa-var-gift: \f06b; +$fa-var-dice-two: \f528; +$fa-var-chess-queen: \f445; +$fa-var-glasses: \f530; +$fa-var-chess-board: \f43c; +$fa-var-building-circle-check: \e4d2; +$fa-var-person-chalkboard: \e53d; +$fa-var-mars-stroke-right: \f22b; +$fa-var-mars-stroke-h: \f22b; +$fa-var-hand-back-fist: \f255; +$fa-var-hand-rock: \f255; +$fa-var-square-caret-up: \f151; +$fa-var-caret-square-up: \f151; +$fa-var-cloud-showers-water: \e4e4; +$fa-var-chart-bar: \f080; +$fa-var-bar-chart: \f080; +$fa-var-hands-bubbles: \e05e; +$fa-var-hands-wash: \e05e; +$fa-var-less-than-equal: \f537; +$fa-var-train: \f238; +$fa-var-eye-low-vision: \f2a8; +$fa-var-low-vision: \f2a8; +$fa-var-crow: \f520; +$fa-var-sailboat: \e445; +$fa-var-window-restore: \f2d2; +$fa-var-square-plus: \f0fe; +$fa-var-plus-square: \f0fe; +$fa-var-torii-gate: \f6a1; +$fa-var-frog: \f52e; +$fa-var-bucket: \e4cf; +$fa-var-image: \f03e; +$fa-var-microphone: \f130; +$fa-var-cow: \f6c8; +$fa-var-caret-up: \f0d8; +$fa-var-screwdriver: \f54a; +$fa-var-folder-closed: \e185; +$fa-var-house-tsunami: \e515; +$fa-var-square-nfi: \e576; +$fa-var-arrow-up-from-ground-water: \e4b5; +$fa-var-martini-glass: \f57b; +$fa-var-glass-martini-alt: \f57b; +$fa-var-square-binary: \e69b; +$fa-var-rotate-left: \f2ea; +$fa-var-rotate-back: \f2ea; +$fa-var-rotate-backward: \f2ea; +$fa-var-undo-alt: \f2ea; +$fa-var-table-columns: \f0db; +$fa-var-columns: \f0db; +$fa-var-lemon: \f094; +$fa-var-head-side-mask: \e063; +$fa-var-handshake: \f2b5; +$fa-var-gem: \f3a5; +$fa-var-dolly: \f472; +$fa-var-dolly-box: \f472; +$fa-var-smoking: \f48d; +$fa-var-minimize: \f78c; +$fa-var-compress-arrows-alt: \f78c; +$fa-var-monument: \f5a6; +$fa-var-snowplow: \f7d2; +$fa-var-angles-right: \f101; +$fa-var-angle-double-right: \f101; +$fa-var-cannabis: \f55f; +$fa-var-circle-play: \f144; +$fa-var-play-circle: \f144; +$fa-var-tablets: \f490; +$fa-var-ethernet: \f796; +$fa-var-euro-sign: \f153; +$fa-var-eur: \f153; +$fa-var-euro: \f153; +$fa-var-chair: \f6c0; +$fa-var-circle-check: \f058; +$fa-var-check-circle: \f058; +$fa-var-circle-stop: \f28d; +$fa-var-stop-circle: \f28d; +$fa-var-compass-drafting: \f568; +$fa-var-drafting-compass: \f568; +$fa-var-plate-wheat: \e55a; +$fa-var-icicles: \f7ad; +$fa-var-person-shelter: \e54f; +$fa-var-neuter: \f22c; +$fa-var-id-badge: \f2c1; +$fa-var-marker: \f5a1; +$fa-var-face-laugh-beam: \f59a; +$fa-var-laugh-beam: \f59a; +$fa-var-helicopter-symbol: \e502; +$fa-var-universal-access: \f29a; +$fa-var-circle-chevron-up: \f139; +$fa-var-chevron-circle-up: \f139; +$fa-var-lari-sign: \e1c8; +$fa-var-volcano: \f770; +$fa-var-person-walking-dashed-line-arrow-right: \e553; +$fa-var-sterling-sign: \f154; +$fa-var-gbp: \f154; +$fa-var-pound-sign: \f154; +$fa-var-viruses: \e076; +$fa-var-square-person-confined: \e577; +$fa-var-user-tie: \f508; +$fa-var-arrow-down-long: \f175; +$fa-var-long-arrow-down: \f175; +$fa-var-tent-arrow-down-to-line: \e57e; +$fa-var-certificate: \f0a3; +$fa-var-reply-all: \f122; +$fa-var-mail-reply-all: \f122; +$fa-var-suitcase: \f0f2; +$fa-var-person-skating: \f7c5; +$fa-var-skating: \f7c5; +$fa-var-filter-circle-dollar: \f662; +$fa-var-funnel-dollar: \f662; +$fa-var-camera-retro: \f083; +$fa-var-circle-arrow-down: \f0ab; +$fa-var-arrow-circle-down: \f0ab; +$fa-var-file-import: \f56f; +$fa-var-arrow-right-to-file: \f56f; +$fa-var-square-arrow-up-right: \f14c; +$fa-var-external-link-square: \f14c; +$fa-var-box-open: \f49e; +$fa-var-scroll: \f70e; +$fa-var-spa: \f5bb; +$fa-var-location-pin-lock: \e51f; +$fa-var-pause: \f04c; +$fa-var-hill-avalanche: \e507; +$fa-var-temperature-empty: \f2cb; +$fa-var-temperature-0: \f2cb; +$fa-var-thermometer-0: \f2cb; +$fa-var-thermometer-empty: \f2cb; +$fa-var-bomb: \f1e2; +$fa-var-registered: \f25d; +$fa-var-address-card: \f2bb; +$fa-var-contact-card: \f2bb; +$fa-var-vcard: \f2bb; +$fa-var-scale-unbalanced-flip: \f516; +$fa-var-balance-scale-right: \f516; +$fa-var-subscript: \f12c; +$fa-var-diamond-turn-right: \f5eb; +$fa-var-directions: \f5eb; +$fa-var-burst: \e4dc; +$fa-var-house-laptop: \e066; +$fa-var-laptop-house: \e066; +$fa-var-face-tired: \f5c8; +$fa-var-tired: \f5c8; +$fa-var-money-bills: \e1f3; +$fa-var-smog: \f75f; +$fa-var-crutch: \f7f7; +$fa-var-cloud-arrow-up: \f0ee; +$fa-var-cloud-upload: \f0ee; +$fa-var-cloud-upload-alt: \f0ee; +$fa-var-palette: \f53f; +$fa-var-arrows-turn-right: \e4c0; +$fa-var-vest: \e085; +$fa-var-ferry: \e4ea; +$fa-var-arrows-down-to-people: \e4b9; +$fa-var-seedling: \f4d8; +$fa-var-sprout: \f4d8; +$fa-var-left-right: \f337; +$fa-var-arrows-alt-h: \f337; +$fa-var-boxes-packing: \e4c7; +$fa-var-circle-arrow-left: \f0a8; +$fa-var-arrow-circle-left: \f0a8; +$fa-var-group-arrows-rotate: \e4f6; +$fa-var-bowl-food: \e4c6; +$fa-var-candy-cane: \f786; +$fa-var-arrow-down-wide-short: \f160; +$fa-var-sort-amount-asc: \f160; +$fa-var-sort-amount-down: \f160; +$fa-var-cloud-bolt: \f76c; +$fa-var-thunderstorm: \f76c; +$fa-var-text-slash: \f87d; +$fa-var-remove-format: \f87d; +$fa-var-face-smile-wink: \f4da; +$fa-var-smile-wink: \f4da; +$fa-var-file-word: \f1c2; +$fa-var-file-powerpoint: \f1c4; +$fa-var-arrows-left-right: \f07e; +$fa-var-arrows-h: \f07e; +$fa-var-house-lock: \e510; +$fa-var-cloud-arrow-down: \f0ed; +$fa-var-cloud-download: \f0ed; +$fa-var-cloud-download-alt: \f0ed; +$fa-var-children: \e4e1; +$fa-var-chalkboard: \f51b; +$fa-var-blackboard: \f51b; +$fa-var-user-large-slash: \f4fa; +$fa-var-user-alt-slash: \f4fa; +$fa-var-envelope-open: \f2b6; +$fa-var-handshake-simple-slash: \e05f; +$fa-var-handshake-alt-slash: \e05f; +$fa-var-mattress-pillow: \e525; +$fa-var-guarani-sign: \e19a; +$fa-var-arrows-rotate: \f021; +$fa-var-refresh: \f021; +$fa-var-sync: \f021; +$fa-var-fire-extinguisher: \f134; +$fa-var-cruzeiro-sign: \e152; +$fa-var-greater-than-equal: \f532; +$fa-var-shield-halved: \f3ed; +$fa-var-shield-alt: \f3ed; +$fa-var-book-atlas: \f558; +$fa-var-atlas: \f558; +$fa-var-virus: \e074; +$fa-var-envelope-circle-check: \e4e8; +$fa-var-layer-group: \f5fd; +$fa-var-arrows-to-dot: \e4be; +$fa-var-archway: \f557; +$fa-var-heart-circle-check: \e4fd; +$fa-var-house-chimney-crack: \f6f1; +$fa-var-house-damage: \f6f1; +$fa-var-file-zipper: \f1c6; +$fa-var-file-archive: \f1c6; +$fa-var-square: \f0c8; +$fa-var-martini-glass-empty: \f000; +$fa-var-glass-martini: \f000; +$fa-var-couch: \f4b8; +$fa-var-cedi-sign: \e0df; +$fa-var-italic: \f033; +$fa-var-table-cells-column-lock: \e678; +$fa-var-church: \f51d; +$fa-var-comments-dollar: \f653; +$fa-var-democrat: \f747; +$fa-var-z: \5a; +$fa-var-person-skiing: \f7c9; +$fa-var-skiing: \f7c9; +$fa-var-road-lock: \e567; +$fa-var-a: \41; +$fa-var-temperature-arrow-down: \e03f; +$fa-var-temperature-down: \e03f; +$fa-var-feather-pointed: \f56b; +$fa-var-feather-alt: \f56b; +$fa-var-p: \50; +$fa-var-snowflake: \f2dc; +$fa-var-newspaper: \f1ea; +$fa-var-rectangle-ad: \f641; +$fa-var-ad: \f641; +$fa-var-circle-arrow-right: \f0a9; +$fa-var-arrow-circle-right: \f0a9; +$fa-var-filter-circle-xmark: \e17b; +$fa-var-locust: \e520; +$fa-var-sort: \f0dc; +$fa-var-unsorted: \f0dc; +$fa-var-list-ol: \f0cb; +$fa-var-list-1-2: \f0cb; +$fa-var-list-numeric: \f0cb; +$fa-var-person-dress-burst: \e544; +$fa-var-money-check-dollar: \f53d; +$fa-var-money-check-alt: \f53d; +$fa-var-vector-square: \f5cb; +$fa-var-bread-slice: \f7ec; +$fa-var-language: \f1ab; +$fa-var-face-kiss-wink-heart: \f598; +$fa-var-kiss-wink-heart: \f598; +$fa-var-filter: \f0b0; +$fa-var-question: \3f; +$fa-var-file-signature: \f573; +$fa-var-up-down-left-right: \f0b2; +$fa-var-arrows-alt: \f0b2; +$fa-var-house-chimney-user: \e065; +$fa-var-hand-holding-heart: \f4be; +$fa-var-puzzle-piece: \f12e; +$fa-var-money-check: \f53c; +$fa-var-star-half-stroke: \f5c0; +$fa-var-star-half-alt: \f5c0; +$fa-var-code: \f121; +$fa-var-whiskey-glass: \f7a0; +$fa-var-glass-whiskey: \f7a0; +$fa-var-building-circle-exclamation: \e4d3; +$fa-var-magnifying-glass-chart: \e522; +$fa-var-arrow-up-right-from-square: \f08e; +$fa-var-external-link: \f08e; +$fa-var-cubes-stacked: \e4e6; +$fa-var-won-sign: \f159; +$fa-var-krw: \f159; +$fa-var-won: \f159; +$fa-var-virus-covid: \e4a8; +$fa-var-austral-sign: \e0a9; +$fa-var-f: \46; +$fa-var-leaf: \f06c; +$fa-var-road: \f018; +$fa-var-taxi: \f1ba; +$fa-var-cab: \f1ba; +$fa-var-person-circle-plus: \e541; +$fa-var-chart-pie: \f200; +$fa-var-pie-chart: \f200; +$fa-var-bolt-lightning: \e0b7; +$fa-var-sack-xmark: \e56a; +$fa-var-file-excel: \f1c3; +$fa-var-file-contract: \f56c; +$fa-var-fish-fins: \e4f2; +$fa-var-building-flag: \e4d5; +$fa-var-face-grin-beam: \f582; +$fa-var-grin-beam: \f582; +$fa-var-object-ungroup: \f248; +$fa-var-poop: \f619; +$fa-var-location-pin: \f041; +$fa-var-map-marker: \f041; +$fa-var-kaaba: \f66b; +$fa-var-toilet-paper: \f71e; +$fa-var-helmet-safety: \f807; +$fa-var-hard-hat: \f807; +$fa-var-hat-hard: \f807; +$fa-var-eject: \f052; +$fa-var-circle-right: \f35a; +$fa-var-arrow-alt-circle-right: \f35a; +$fa-var-plane-circle-check: \e555; +$fa-var-face-rolling-eyes: \f5a5; +$fa-var-meh-rolling-eyes: \f5a5; +$fa-var-object-group: \f247; +$fa-var-chart-line: \f201; +$fa-var-line-chart: \f201; +$fa-var-mask-ventilator: \e524; +$fa-var-arrow-right: \f061; +$fa-var-signs-post: \f277; +$fa-var-map-signs: \f277; +$fa-var-cash-register: \f788; +$fa-var-person-circle-question: \e542; +$fa-var-h: \48; +$fa-var-tarp: \e57b; +$fa-var-screwdriver-wrench: \f7d9; +$fa-var-tools: \f7d9; +$fa-var-arrows-to-eye: \e4bf; +$fa-var-plug-circle-bolt: \e55b; +$fa-var-heart: \f004; +$fa-var-mars-and-venus: \f224; +$fa-var-house-user: \e1b0; +$fa-var-home-user: \e1b0; +$fa-var-dumpster-fire: \f794; +$fa-var-house-crack: \e3b1; +$fa-var-martini-glass-citrus: \f561; +$fa-var-cocktail: \f561; +$fa-var-face-surprise: \f5c2; +$fa-var-surprise: \f5c2; +$fa-var-bottle-water: \e4c5; +$fa-var-circle-pause: \f28b; +$fa-var-pause-circle: \f28b; +$fa-var-toilet-paper-slash: \e072; +$fa-var-apple-whole: \f5d1; +$fa-var-apple-alt: \f5d1; +$fa-var-kitchen-set: \e51a; +$fa-var-r: \52; +$fa-var-temperature-quarter: \f2ca; +$fa-var-temperature-1: \f2ca; +$fa-var-thermometer-1: \f2ca; +$fa-var-thermometer-quarter: \f2ca; +$fa-var-cube: \f1b2; +$fa-var-bitcoin-sign: \e0b4; +$fa-var-shield-dog: \e573; +$fa-var-solar-panel: \f5ba; +$fa-var-lock-open: \f3c1; +$fa-var-elevator: \e16d; +$fa-var-money-bill-transfer: \e528; +$fa-var-money-bill-trend-up: \e529; +$fa-var-house-flood-water-circle-arrow-right: \e50f; +$fa-var-square-poll-horizontal: \f682; +$fa-var-poll-h: \f682; +$fa-var-circle: \f111; +$fa-var-backward-fast: \f049; +$fa-var-fast-backward: \f049; +$fa-var-recycle: \f1b8; +$fa-var-user-astronaut: \f4fb; +$fa-var-plane-slash: \e069; +$fa-var-trademark: \f25c; +$fa-var-basketball: \f434; +$fa-var-basketball-ball: \f434; +$fa-var-satellite-dish: \f7c0; +$fa-var-circle-up: \f35b; +$fa-var-arrow-alt-circle-up: \f35b; +$fa-var-mobile-screen-button: \f3cd; +$fa-var-mobile-alt: \f3cd; +$fa-var-volume-high: \f028; +$fa-var-volume-up: \f028; +$fa-var-users-rays: \e593; +$fa-var-wallet: \f555; +$fa-var-clipboard-check: \f46c; +$fa-var-file-audio: \f1c7; +$fa-var-burger: \f805; +$fa-var-hamburger: \f805; +$fa-var-wrench: \f0ad; +$fa-var-bugs: \e4d0; +$fa-var-rupee-sign: \f156; +$fa-var-rupee: \f156; +$fa-var-file-image: \f1c5; +$fa-var-circle-question: \f059; +$fa-var-question-circle: \f059; +$fa-var-plane-departure: \f5b0; +$fa-var-handshake-slash: \e060; +$fa-var-book-bookmark: \e0bb; +$fa-var-code-branch: \f126; +$fa-var-hat-cowboy: \f8c0; +$fa-var-bridge: \e4c8; +$fa-var-phone-flip: \f879; +$fa-var-phone-alt: \f879; +$fa-var-truck-front: \e2b7; +$fa-var-cat: \f6be; +$fa-var-anchor-circle-exclamation: \e4ab; +$fa-var-truck-field: \e58d; +$fa-var-route: \f4d7; +$fa-var-clipboard-question: \e4e3; +$fa-var-panorama: \e209; +$fa-var-comment-medical: \f7f5; +$fa-var-teeth-open: \f62f; +$fa-var-file-circle-minus: \e4ed; +$fa-var-tags: \f02c; +$fa-var-wine-glass: \f4e3; +$fa-var-forward-fast: \f050; +$fa-var-fast-forward: \f050; +$fa-var-face-meh-blank: \f5a4; +$fa-var-meh-blank: \f5a4; +$fa-var-square-parking: \f540; +$fa-var-parking: \f540; +$fa-var-house-signal: \e012; +$fa-var-bars-progress: \f828; +$fa-var-tasks-alt: \f828; +$fa-var-faucet-drip: \e006; +$fa-var-cart-flatbed: \f474; +$fa-var-dolly-flatbed: \f474; +$fa-var-ban-smoking: \f54d; +$fa-var-smoking-ban: \f54d; +$fa-var-terminal: \f120; +$fa-var-mobile-button: \f10b; +$fa-var-house-medical-flag: \e514; +$fa-var-basket-shopping: \f291; +$fa-var-shopping-basket: \f291; +$fa-var-tape: \f4db; +$fa-var-bus-simple: \f55e; +$fa-var-bus-alt: \f55e; +$fa-var-eye: \f06e; +$fa-var-face-sad-cry: \f5b3; +$fa-var-sad-cry: \f5b3; +$fa-var-audio-description: \f29e; +$fa-var-person-military-to-person: \e54c; +$fa-var-file-shield: \e4f0; +$fa-var-user-slash: \f506; +$fa-var-pen: \f304; +$fa-var-tower-observation: \e586; +$fa-var-file-code: \f1c9; +$fa-var-signal: \f012; +$fa-var-signal-5: \f012; +$fa-var-signal-perfect: \f012; +$fa-var-bus: \f207; +$fa-var-heart-circle-xmark: \e501; +$fa-var-house-chimney: \e3af; +$fa-var-home-lg: \e3af; +$fa-var-window-maximize: \f2d0; +$fa-var-face-frown: \f119; +$fa-var-frown: \f119; +$fa-var-prescription: \f5b1; +$fa-var-shop: \f54f; +$fa-var-store-alt: \f54f; +$fa-var-floppy-disk: \f0c7; +$fa-var-save: \f0c7; +$fa-var-vihara: \f6a7; +$fa-var-scale-unbalanced: \f515; +$fa-var-balance-scale-left: \f515; +$fa-var-sort-up: \f0de; +$fa-var-sort-asc: \f0de; +$fa-var-comment-dots: \f4ad; +$fa-var-commenting: \f4ad; +$fa-var-plant-wilt: \e5aa; +$fa-var-diamond: \f219; +$fa-var-face-grin-squint: \f585; +$fa-var-grin-squint: \f585; +$fa-var-hand-holding-dollar: \f4c0; +$fa-var-hand-holding-usd: \f4c0; +$fa-var-chart-diagram: \e695; +$fa-var-bacterium: \e05a; +$fa-var-hand-pointer: \f25a; +$fa-var-drum-steelpan: \f56a; +$fa-var-hand-scissors: \f257; +$fa-var-hands-praying: \f684; +$fa-var-praying-hands: \f684; +$fa-var-arrow-rotate-right: \f01e; +$fa-var-arrow-right-rotate: \f01e; +$fa-var-arrow-rotate-forward: \f01e; +$fa-var-redo: \f01e; +$fa-var-biohazard: \f780; +$fa-var-location-crosshairs: \f601; +$fa-var-location: \f601; +$fa-var-mars-double: \f227; +$fa-var-child-dress: \e59c; +$fa-var-users-between-lines: \e591; +$fa-var-lungs-virus: \e067; +$fa-var-face-grin-tears: \f588; +$fa-var-grin-tears: \f588; +$fa-var-phone: \f095; +$fa-var-calendar-xmark: \f273; +$fa-var-calendar-times: \f273; +$fa-var-child-reaching: \e59d; +$fa-var-head-side-virus: \e064; +$fa-var-user-gear: \f4fe; +$fa-var-user-cog: \f4fe; +$fa-var-arrow-up-1-9: \f163; +$fa-var-sort-numeric-up: \f163; +$fa-var-door-closed: \f52a; +$fa-var-shield-virus: \e06c; +$fa-var-dice-six: \f526; +$fa-var-mosquito-net: \e52c; +$fa-var-file-fragment: \e697; +$fa-var-bridge-water: \e4ce; +$fa-var-person-booth: \f756; +$fa-var-text-width: \f035; +$fa-var-hat-wizard: \f6e8; +$fa-var-pen-fancy: \f5ac; +$fa-var-person-digging: \f85e; +$fa-var-digging: \f85e; +$fa-var-trash: \f1f8; +$fa-var-gauge-simple: \f629; +$fa-var-gauge-simple-med: \f629; +$fa-var-tachometer-average: \f629; +$fa-var-book-medical: \f7e6; +$fa-var-poo: \f2fe; +$fa-var-quote-right: \f10e; +$fa-var-quote-right-alt: \f10e; +$fa-var-shirt: \f553; +$fa-var-t-shirt: \f553; +$fa-var-tshirt: \f553; +$fa-var-cubes: \f1b3; +$fa-var-divide: \f529; +$fa-var-tenge-sign: \f7d7; +$fa-var-tenge: \f7d7; +$fa-var-headphones: \f025; +$fa-var-hands-holding: \f4c2; +$fa-var-hands-clapping: \e1a8; +$fa-var-republican: \f75e; +$fa-var-arrow-left: \f060; +$fa-var-person-circle-xmark: \e543; +$fa-var-ruler: \f545; +$fa-var-align-left: \f036; +$fa-var-dice-d6: \f6d1; +$fa-var-restroom: \f7bd; +$fa-var-j: \4a; +$fa-var-users-viewfinder: \e595; +$fa-var-file-video: \f1c8; +$fa-var-up-right-from-square: \f35d; +$fa-var-external-link-alt: \f35d; +$fa-var-table-cells: \f00a; +$fa-var-th: \f00a; +$fa-var-file-pdf: \f1c1; +$fa-var-book-bible: \f647; +$fa-var-bible: \f647; +$fa-var-o: \4f; +$fa-var-suitcase-medical: \f0fa; +$fa-var-medkit: \f0fa; +$fa-var-user-secret: \f21b; +$fa-var-otter: \f700; +$fa-var-person-dress: \f182; +$fa-var-female: \f182; +$fa-var-comment-dollar: \f651; +$fa-var-business-time: \f64a; +$fa-var-briefcase-clock: \f64a; +$fa-var-table-cells-large: \f009; +$fa-var-th-large: \f009; +$fa-var-book-tanakh: \f827; +$fa-var-tanakh: \f827; +$fa-var-phone-volume: \f2a0; +$fa-var-volume-control-phone: \f2a0; +$fa-var-hat-cowboy-side: \f8c1; +$fa-var-clipboard-user: \f7f3; +$fa-var-child: \f1ae; +$fa-var-lira-sign: \f195; +$fa-var-satellite: \f7bf; +$fa-var-plane-lock: \e558; +$fa-var-tag: \f02b; +$fa-var-comment: \f075; +$fa-var-cake-candles: \f1fd; +$fa-var-birthday-cake: \f1fd; +$fa-var-cake: \f1fd; +$fa-var-envelope: \f0e0; +$fa-var-angles-up: \f102; +$fa-var-angle-double-up: \f102; +$fa-var-paperclip: \f0c6; +$fa-var-arrow-right-to-city: \e4b3; +$fa-var-ribbon: \f4d6; +$fa-var-lungs: \f604; +$fa-var-arrow-up-9-1: \f887; +$fa-var-sort-numeric-up-alt: \f887; +$fa-var-litecoin-sign: \e1d3; +$fa-var-border-none: \f850; +$fa-var-circle-nodes: \e4e2; +$fa-var-parachute-box: \f4cd; +$fa-var-indent: \f03c; +$fa-var-truck-field-un: \e58e; +$fa-var-hourglass: \f254; +$fa-var-hourglass-empty: \f254; +$fa-var-mountain: \f6fc; +$fa-var-user-doctor: \f0f0; +$fa-var-user-md: \f0f0; +$fa-var-circle-info: \f05a; +$fa-var-info-circle: \f05a; +$fa-var-cloud-meatball: \f73b; +$fa-var-camera: \f030; +$fa-var-camera-alt: \f030; +$fa-var-square-virus: \e578; +$fa-var-meteor: \f753; +$fa-var-car-on: \e4dd; +$fa-var-sleigh: \f7cc; +$fa-var-arrow-down-1-9: \f162; +$fa-var-sort-numeric-asc: \f162; +$fa-var-sort-numeric-down: \f162; +$fa-var-hand-holding-droplet: \f4c1; +$fa-var-hand-holding-water: \f4c1; +$fa-var-water: \f773; +$fa-var-calendar-check: \f274; +$fa-var-braille: \f2a1; +$fa-var-prescription-bottle-medical: \f486; +$fa-var-prescription-bottle-alt: \f486; +$fa-var-landmark: \f66f; +$fa-var-truck: \f0d1; +$fa-var-crosshairs: \f05b; +$fa-var-person-cane: \e53c; +$fa-var-tent: \e57d; +$fa-var-vest-patches: \e086; +$fa-var-check-double: \f560; +$fa-var-arrow-down-a-z: \f15d; +$fa-var-sort-alpha-asc: \f15d; +$fa-var-sort-alpha-down: \f15d; +$fa-var-money-bill-wheat: \e52a; +$fa-var-cookie: \f563; +$fa-var-arrow-rotate-left: \f0e2; +$fa-var-arrow-left-rotate: \f0e2; +$fa-var-arrow-rotate-back: \f0e2; +$fa-var-arrow-rotate-backward: \f0e2; +$fa-var-undo: \f0e2; +$fa-var-hard-drive: \f0a0; +$fa-var-hdd: \f0a0; +$fa-var-face-grin-squint-tears: \f586; +$fa-var-grin-squint-tears: \f586; +$fa-var-dumbbell: \f44b; +$fa-var-rectangle-list: \f022; +$fa-var-list-alt: \f022; +$fa-var-tarp-droplet: \e57c; +$fa-var-house-medical-circle-check: \e511; +$fa-var-person-skiing-nordic: \f7ca; +$fa-var-skiing-nordic: \f7ca; +$fa-var-calendar-plus: \f271; +$fa-var-plane-arrival: \f5af; +$fa-var-circle-left: \f359; +$fa-var-arrow-alt-circle-left: \f359; +$fa-var-train-subway: \f239; +$fa-var-subway: \f239; +$fa-var-chart-gantt: \e0e4; +$fa-var-indian-rupee-sign: \e1bc; +$fa-var-indian-rupee: \e1bc; +$fa-var-inr: \e1bc; +$fa-var-crop-simple: \f565; +$fa-var-crop-alt: \f565; +$fa-var-money-bill-1: \f3d1; +$fa-var-money-bill-alt: \f3d1; +$fa-var-left-long: \f30a; +$fa-var-long-arrow-alt-left: \f30a; +$fa-var-dna: \f471; +$fa-var-virus-slash: \e075; +$fa-var-minus: \f068; +$fa-var-subtract: \f068; +$fa-var-chess: \f439; +$fa-var-arrow-left-long: \f177; +$fa-var-long-arrow-left: \f177; +$fa-var-plug-circle-check: \e55c; +$fa-var-street-view: \f21d; +$fa-var-franc-sign: \e18f; +$fa-var-volume-off: \f026; +$fa-var-hands-asl-interpreting: \f2a3; +$fa-var-american-sign-language-interpreting: \f2a3; +$fa-var-asl-interpreting: \f2a3; +$fa-var-hands-american-sign-language-interpreting: \f2a3; +$fa-var-gear: \f013; +$fa-var-cog: \f013; +$fa-var-droplet-slash: \f5c7; +$fa-var-tint-slash: \f5c7; +$fa-var-mosque: \f678; +$fa-var-mosquito: \e52b; +$fa-var-star-of-david: \f69a; +$fa-var-person-military-rifle: \e54b; +$fa-var-cart-shopping: \f07a; +$fa-var-shopping-cart: \f07a; +$fa-var-vials: \f493; +$fa-var-plug-circle-plus: \e55f; +$fa-var-place-of-worship: \f67f; +$fa-var-grip-vertical: \f58e; +$fa-var-hexagon-nodes: \e699; +$fa-var-arrow-turn-up: \f148; +$fa-var-level-up: \f148; +$fa-var-u: \55; +$fa-var-square-root-variable: \f698; +$fa-var-square-root-alt: \f698; +$fa-var-clock: \f017; +$fa-var-clock-four: \f017; +$fa-var-backward-step: \f048; +$fa-var-step-backward: \f048; +$fa-var-pallet: \f482; +$fa-var-faucet: \e005; +$fa-var-baseball-bat-ball: \f432; +$fa-var-s: \53; +$fa-var-timeline: \e29c; +$fa-var-keyboard: \f11c; +$fa-var-caret-down: \f0d7; +$fa-var-house-chimney-medical: \f7f2; +$fa-var-clinic-medical: \f7f2; +$fa-var-temperature-three-quarters: \f2c8; +$fa-var-temperature-3: \f2c8; +$fa-var-thermometer-3: \f2c8; +$fa-var-thermometer-three-quarters: \f2c8; +$fa-var-mobile-screen: \f3cf; +$fa-var-mobile-android-alt: \f3cf; +$fa-var-plane-up: \e22d; +$fa-var-piggy-bank: \f4d3; +$fa-var-battery-half: \f242; +$fa-var-battery-3: \f242; +$fa-var-mountain-city: \e52e; +$fa-var-coins: \f51e; +$fa-var-khanda: \f66d; +$fa-var-sliders: \f1de; +$fa-var-sliders-h: \f1de; +$fa-var-folder-tree: \f802; +$fa-var-network-wired: \f6ff; +$fa-var-map-pin: \f276; +$fa-var-hamsa: \f665; +$fa-var-cent-sign: \e3f5; +$fa-var-flask: \f0c3; +$fa-var-person-pregnant: \e31e; +$fa-var-wand-sparkles: \f72b; +$fa-var-ellipsis-vertical: \f142; +$fa-var-ellipsis-v: \f142; +$fa-var-ticket: \f145; +$fa-var-power-off: \f011; +$fa-var-right-long: \f30b; +$fa-var-long-arrow-alt-right: \f30b; +$fa-var-flag-usa: \f74d; +$fa-var-laptop-file: \e51d; +$fa-var-tty: \f1e4; +$fa-var-teletype: \f1e4; +$fa-var-diagram-next: \e476; +$fa-var-person-rifle: \e54e; +$fa-var-house-medical-circle-exclamation: \e512; +$fa-var-closed-captioning: \f20a; +$fa-var-person-hiking: \f6ec; +$fa-var-hiking: \f6ec; +$fa-var-venus-double: \f226; +$fa-var-images: \f302; +$fa-var-calculator: \f1ec; +$fa-var-people-pulling: \e535; +$fa-var-n: \4e; +$fa-var-cable-car: \f7da; +$fa-var-tram: \f7da; +$fa-var-cloud-rain: \f73d; +$fa-var-building-circle-xmark: \e4d4; +$fa-var-ship: \f21a; +$fa-var-arrows-down-to-line: \e4b8; +$fa-var-download: \f019; +$fa-var-face-grin: \f580; +$fa-var-grin: \f580; +$fa-var-delete-left: \f55a; +$fa-var-backspace: \f55a; +$fa-var-eye-dropper: \f1fb; +$fa-var-eye-dropper-empty: \f1fb; +$fa-var-eyedropper: \f1fb; +$fa-var-file-circle-check: \e5a0; +$fa-var-forward: \f04e; +$fa-var-mobile: \f3ce; +$fa-var-mobile-android: \f3ce; +$fa-var-mobile-phone: \f3ce; +$fa-var-face-meh: \f11a; +$fa-var-meh: \f11a; +$fa-var-align-center: \f037; +$fa-var-book-skull: \f6b7; +$fa-var-book-dead: \f6b7; +$fa-var-id-card: \f2c2; +$fa-var-drivers-license: \f2c2; +$fa-var-outdent: \f03b; +$fa-var-dedent: \f03b; +$fa-var-heart-circle-exclamation: \e4fe; +$fa-var-house: \f015; +$fa-var-home: \f015; +$fa-var-home-alt: \f015; +$fa-var-home-lg-alt: \f015; +$fa-var-calendar-week: \f784; +$fa-var-laptop-medical: \f812; +$fa-var-b: \42; +$fa-var-file-medical: \f477; +$fa-var-dice-one: \f525; +$fa-var-kiwi-bird: \f535; +$fa-var-arrow-right-arrow-left: \f0ec; +$fa-var-exchange: \f0ec; +$fa-var-rotate-right: \f2f9; +$fa-var-redo-alt: \f2f9; +$fa-var-rotate-forward: \f2f9; +$fa-var-utensils: \f2e7; +$fa-var-cutlery: \f2e7; +$fa-var-arrow-up-wide-short: \f161; +$fa-var-sort-amount-up: \f161; +$fa-var-mill-sign: \e1ed; +$fa-var-bowl-rice: \e2eb; +$fa-var-skull: \f54c; +$fa-var-tower-broadcast: \f519; +$fa-var-broadcast-tower: \f519; +$fa-var-truck-pickup: \f63c; +$fa-var-up-long: \f30c; +$fa-var-long-arrow-alt-up: \f30c; +$fa-var-stop: \f04d; +$fa-var-code-merge: \f387; +$fa-var-upload: \f093; +$fa-var-hurricane: \f751; +$fa-var-mound: \e52d; +$fa-var-toilet-portable: \e583; +$fa-var-compact-disc: \f51f; +$fa-var-file-arrow-down: \f56d; +$fa-var-file-download: \f56d; +$fa-var-caravan: \f8ff; +$fa-var-shield-cat: \e572; +$fa-var-bolt: \f0e7; +$fa-var-zap: \f0e7; +$fa-var-glass-water: \e4f4; +$fa-var-oil-well: \e532; +$fa-var-vault: \e2c5; +$fa-var-mars: \f222; +$fa-var-toilet: \f7d8; +$fa-var-plane-circle-xmark: \e557; +$fa-var-yen-sign: \f157; +$fa-var-cny: \f157; +$fa-var-jpy: \f157; +$fa-var-rmb: \f157; +$fa-var-yen: \f157; +$fa-var-ruble-sign: \f158; +$fa-var-rouble: \f158; +$fa-var-rub: \f158; +$fa-var-ruble: \f158; +$fa-var-sun: \f185; +$fa-var-guitar: \f7a6; +$fa-var-face-laugh-wink: \f59c; +$fa-var-laugh-wink: \f59c; +$fa-var-horse-head: \f7ab; +$fa-var-bore-hole: \e4c3; +$fa-var-industry: \f275; +$fa-var-circle-down: \f358; +$fa-var-arrow-alt-circle-down: \f358; +$fa-var-arrows-turn-to-dots: \e4c1; +$fa-var-florin-sign: \e184; +$fa-var-arrow-down-short-wide: \f884; +$fa-var-sort-amount-desc: \f884; +$fa-var-sort-amount-down-alt: \f884; +$fa-var-less-than: \3c; +$fa-var-angle-down: \f107; +$fa-var-car-tunnel: \e4de; +$fa-var-head-side-cough: \e061; +$fa-var-grip-lines: \f7a4; +$fa-var-thumbs-down: \f165; +$fa-var-user-lock: \f502; +$fa-var-arrow-right-long: \f178; +$fa-var-long-arrow-right: \f178; +$fa-var-anchor-circle-xmark: \e4ac; +$fa-var-ellipsis: \f141; +$fa-var-ellipsis-h: \f141; +$fa-var-chess-pawn: \f443; +$fa-var-kit-medical: \f479; +$fa-var-first-aid: \f479; +$fa-var-person-through-window: \e5a9; +$fa-var-toolbox: \f552; +$fa-var-hands-holding-circle: \e4fb; +$fa-var-bug: \f188; +$fa-var-credit-card: \f09d; +$fa-var-credit-card-alt: \f09d; +$fa-var-car: \f1b9; +$fa-var-automobile: \f1b9; +$fa-var-hand-holding-hand: \e4f7; +$fa-var-book-open-reader: \f5da; +$fa-var-book-reader: \f5da; +$fa-var-mountain-sun: \e52f; +$fa-var-arrows-left-right-to-line: \e4ba; +$fa-var-dice-d20: \f6cf; +$fa-var-truck-droplet: \e58c; +$fa-var-file-circle-xmark: \e5a1; +$fa-var-temperature-arrow-up: \e040; +$fa-var-temperature-up: \e040; +$fa-var-medal: \f5a2; +$fa-var-bed: \f236; +$fa-var-square-h: \f0fd; +$fa-var-h-square: \f0fd; +$fa-var-podcast: \f2ce; +$fa-var-temperature-full: \f2c7; +$fa-var-temperature-4: \f2c7; +$fa-var-thermometer-4: \f2c7; +$fa-var-thermometer-full: \f2c7; +$fa-var-bell: \f0f3; +$fa-var-superscript: \f12b; +$fa-var-plug-circle-xmark: \e560; +$fa-var-star-of-life: \f621; +$fa-var-phone-slash: \f3dd; +$fa-var-paint-roller: \f5aa; +$fa-var-handshake-angle: \f4c4; +$fa-var-hands-helping: \f4c4; +$fa-var-location-dot: \f3c5; +$fa-var-map-marker-alt: \f3c5; +$fa-var-file: \f15b; +$fa-var-greater-than: \3e; +$fa-var-person-swimming: \f5c4; +$fa-var-swimmer: \f5c4; +$fa-var-arrow-down: \f063; +$fa-var-droplet: \f043; +$fa-var-tint: \f043; +$fa-var-eraser: \f12d; +$fa-var-earth-americas: \f57d; +$fa-var-earth: \f57d; +$fa-var-earth-america: \f57d; +$fa-var-globe-americas: \f57d; +$fa-var-person-burst: \e53b; +$fa-var-dove: \f4ba; +$fa-var-battery-empty: \f244; +$fa-var-battery-0: \f244; +$fa-var-socks: \f696; +$fa-var-inbox: \f01c; +$fa-var-section: \e447; +$fa-var-gauge-high: \f625; +$fa-var-tachometer-alt: \f625; +$fa-var-tachometer-alt-fast: \f625; +$fa-var-envelope-open-text: \f658; +$fa-var-hospital: \f0f8; +$fa-var-hospital-alt: \f0f8; +$fa-var-hospital-wide: \f0f8; +$fa-var-wine-bottle: \f72f; +$fa-var-chess-rook: \f447; +$fa-var-bars-staggered: \f550; +$fa-var-reorder: \f550; +$fa-var-stream: \f550; +$fa-var-dharmachakra: \f655; +$fa-var-hotdog: \f80f; +$fa-var-person-walking-with-cane: \f29d; +$fa-var-blind: \f29d; +$fa-var-drum: \f569; +$fa-var-ice-cream: \f810; +$fa-var-heart-circle-bolt: \e4fc; +$fa-var-fax: \f1ac; +$fa-var-paragraph: \f1dd; +$fa-var-check-to-slot: \f772; +$fa-var-vote-yea: \f772; +$fa-var-star-half: \f089; +$fa-var-boxes-stacked: \f468; +$fa-var-boxes: \f468; +$fa-var-boxes-alt: \f468; +$fa-var-link: \f0c1; +$fa-var-chain: \f0c1; +$fa-var-ear-listen: \f2a2; +$fa-var-assistive-listening-systems: \f2a2; +$fa-var-tree-city: \e587; +$fa-var-play: \f04b; +$fa-var-font: \f031; +$fa-var-table-cells-row-lock: \e67a; +$fa-var-rupiah-sign: \e23d; +$fa-var-magnifying-glass: \f002; +$fa-var-search: \f002; +$fa-var-table-tennis-paddle-ball: \f45d; +$fa-var-ping-pong-paddle-ball: \f45d; +$fa-var-table-tennis: \f45d; +$fa-var-person-dots-from-line: \f470; +$fa-var-diagnoses: \f470; +$fa-var-trash-can-arrow-up: \f82a; +$fa-var-trash-restore-alt: \f82a; +$fa-var-naira-sign: \e1f6; +$fa-var-cart-arrow-down: \f218; +$fa-var-walkie-talkie: \f8ef; +$fa-var-file-pen: \f31c; +$fa-var-file-edit: \f31c; +$fa-var-receipt: \f543; +$fa-var-square-pen: \f14b; +$fa-var-pen-square: \f14b; +$fa-var-pencil-square: \f14b; +$fa-var-suitcase-rolling: \f5c1; +$fa-var-person-circle-exclamation: \e53f; +$fa-var-chevron-down: \f078; +$fa-var-battery-full: \f240; +$fa-var-battery: \f240; +$fa-var-battery-5: \f240; +$fa-var-skull-crossbones: \f714; +$fa-var-code-compare: \e13a; +$fa-var-list-ul: \f0ca; +$fa-var-list-dots: \f0ca; +$fa-var-school-lock: \e56f; +$fa-var-tower-cell: \e585; +$fa-var-down-long: \f309; +$fa-var-long-arrow-alt-down: \f309; +$fa-var-ranking-star: \e561; +$fa-var-chess-king: \f43f; +$fa-var-person-harassing: \e549; +$fa-var-brazilian-real-sign: \e46c; +$fa-var-landmark-dome: \f752; +$fa-var-landmark-alt: \f752; +$fa-var-arrow-up: \f062; +$fa-var-tv: \f26c; +$fa-var-television: \f26c; +$fa-var-tv-alt: \f26c; +$fa-var-shrimp: \e448; +$fa-var-list-check: \f0ae; +$fa-var-tasks: \f0ae; +$fa-var-jug-detergent: \e519; +$fa-var-circle-user: \f2bd; +$fa-var-user-circle: \f2bd; +$fa-var-user-shield: \f505; +$fa-var-wind: \f72e; +$fa-var-car-burst: \f5e1; +$fa-var-car-crash: \f5e1; +$fa-var-y: \59; +$fa-var-person-snowboarding: \f7ce; +$fa-var-snowboarding: \f7ce; +$fa-var-truck-fast: \f48b; +$fa-var-shipping-fast: \f48b; +$fa-var-fish: \f578; +$fa-var-user-graduate: \f501; +$fa-var-circle-half-stroke: \f042; +$fa-var-adjust: \f042; +$fa-var-clapperboard: \e131; +$fa-var-circle-radiation: \f7ba; +$fa-var-radiation-alt: \f7ba; +$fa-var-baseball: \f433; +$fa-var-baseball-ball: \f433; +$fa-var-jet-fighter-up: \e518; +$fa-var-diagram-project: \f542; +$fa-var-project-diagram: \f542; +$fa-var-copy: \f0c5; +$fa-var-volume-xmark: \f6a9; +$fa-var-volume-mute: \f6a9; +$fa-var-volume-times: \f6a9; +$fa-var-hand-sparkles: \e05d; +$fa-var-grip: \f58d; +$fa-var-grip-horizontal: \f58d; +$fa-var-share-from-square: \f14d; +$fa-var-share-square: \f14d; +$fa-var-child-combatant: \e4e0; +$fa-var-child-rifle: \e4e0; +$fa-var-gun: \e19b; +$fa-var-square-phone: \f098; +$fa-var-phone-square: \f098; +$fa-var-plus: \2b; +$fa-var-add: \2b; +$fa-var-expand: \f065; +$fa-var-computer: \e4e5; +$fa-var-xmark: \f00d; +$fa-var-close: \f00d; +$fa-var-multiply: \f00d; +$fa-var-remove: \f00d; +$fa-var-times: \f00d; +$fa-var-arrows-up-down-left-right: \f047; +$fa-var-arrows: \f047; +$fa-var-chalkboard-user: \f51c; +$fa-var-chalkboard-teacher: \f51c; +$fa-var-peso-sign: \e222; +$fa-var-building-shield: \e4d8; +$fa-var-baby: \f77c; +$fa-var-users-line: \e592; +$fa-var-quote-left: \f10d; +$fa-var-quote-left-alt: \f10d; +$fa-var-tractor: \f722; +$fa-var-trash-arrow-up: \f829; +$fa-var-trash-restore: \f829; +$fa-var-arrow-down-up-lock: \e4b0; +$fa-var-lines-leaning: \e51e; +$fa-var-ruler-combined: \f546; +$fa-var-copyright: \f1f9; +$fa-var-equals: \3d; +$fa-var-blender: \f517; +$fa-var-teeth: \f62e; +$fa-var-shekel-sign: \f20b; +$fa-var-ils: \f20b; +$fa-var-shekel: \f20b; +$fa-var-sheqel: \f20b; +$fa-var-sheqel-sign: \f20b; +$fa-var-map: \f279; +$fa-var-rocket: \f135; +$fa-var-photo-film: \f87c; +$fa-var-photo-video: \f87c; +$fa-var-folder-minus: \f65d; +$fa-var-hexagon-nodes-bolt: \e69a; +$fa-var-store: \f54e; +$fa-var-arrow-trend-up: \e098; +$fa-var-plug-circle-minus: \e55e; +$fa-var-sign-hanging: \f4d9; +$fa-var-sign: \f4d9; +$fa-var-bezier-curve: \f55b; +$fa-var-bell-slash: \f1f6; +$fa-var-tablet: \f3fb; +$fa-var-tablet-android: \f3fb; +$fa-var-school-flag: \e56e; +$fa-var-fill: \f575; +$fa-var-angle-up: \f106; +$fa-var-drumstick-bite: \f6d7; +$fa-var-holly-berry: \f7aa; +$fa-var-chevron-left: \f053; +$fa-var-bacteria: \e059; +$fa-var-hand-lizard: \f258; +$fa-var-notdef: \e1fe; +$fa-var-disease: \f7fa; +$fa-var-briefcase-medical: \f469; +$fa-var-genderless: \f22d; +$fa-var-chevron-right: \f054; +$fa-var-retweet: \f079; +$fa-var-car-rear: \f5de; +$fa-var-car-alt: \f5de; +$fa-var-pump-soap: \e06b; +$fa-var-video-slash: \f4e2; +$fa-var-battery-quarter: \f243; +$fa-var-battery-2: \f243; +$fa-var-radio: \f8d7; +$fa-var-baby-carriage: \f77d; +$fa-var-carriage-baby: \f77d; +$fa-var-traffic-light: \f637; +$fa-var-thermometer: \f491; +$fa-var-vr-cardboard: \f729; +$fa-var-hand-middle-finger: \f806; +$fa-var-percent: \25; +$fa-var-percentage: \25; +$fa-var-truck-moving: \f4df; +$fa-var-glass-water-droplet: \e4f5; +$fa-var-display: \e163; +$fa-var-face-smile: \f118; +$fa-var-smile: \f118; +$fa-var-thumbtack: \f08d; +$fa-var-thumb-tack: \f08d; +$fa-var-trophy: \f091; +$fa-var-person-praying: \f683; +$fa-var-pray: \f683; +$fa-var-hammer: \f6e3; +$fa-var-hand-peace: \f25b; +$fa-var-rotate: \f2f1; +$fa-var-sync-alt: \f2f1; +$fa-var-spinner: \f110; +$fa-var-robot: \f544; +$fa-var-peace: \f67c; +$fa-var-gears: \f085; +$fa-var-cogs: \f085; +$fa-var-warehouse: \f494; +$fa-var-arrow-up-right-dots: \e4b7; +$fa-var-splotch: \f5bc; +$fa-var-face-grin-hearts: \f584; +$fa-var-grin-hearts: \f584; +$fa-var-dice-four: \f524; +$fa-var-sim-card: \f7c4; +$fa-var-transgender: \f225; +$fa-var-transgender-alt: \f225; +$fa-var-mercury: \f223; +$fa-var-arrow-turn-down: \f149; +$fa-var-level-down: \f149; +$fa-var-person-falling-burst: \e547; +$fa-var-award: \f559; +$fa-var-ticket-simple: \f3ff; +$fa-var-ticket-alt: \f3ff; +$fa-var-building: \f1ad; +$fa-var-angles-left: \f100; +$fa-var-angle-double-left: \f100; +$fa-var-qrcode: \f029; +$fa-var-clock-rotate-left: \f1da; +$fa-var-history: \f1da; +$fa-var-face-grin-beam-sweat: \f583; +$fa-var-grin-beam-sweat: \f583; +$fa-var-file-export: \f56e; +$fa-var-arrow-right-from-file: \f56e; +$fa-var-shield: \f132; +$fa-var-shield-blank: \f132; +$fa-var-arrow-up-short-wide: \f885; +$fa-var-sort-amount-up-alt: \f885; +$fa-var-comment-nodes: \e696; +$fa-var-house-medical: \e3b2; +$fa-var-golf-ball-tee: \f450; +$fa-var-golf-ball: \f450; +$fa-var-circle-chevron-left: \f137; +$fa-var-chevron-circle-left: \f137; +$fa-var-house-chimney-window: \e00d; +$fa-var-pen-nib: \f5ad; +$fa-var-tent-arrow-turn-left: \e580; +$fa-var-tents: \e582; +$fa-var-wand-magic: \f0d0; +$fa-var-magic: \f0d0; +$fa-var-dog: \f6d3; +$fa-var-carrot: \f787; +$fa-var-moon: \f186; +$fa-var-wine-glass-empty: \f5ce; +$fa-var-wine-glass-alt: \f5ce; +$fa-var-cheese: \f7ef; +$fa-var-yin-yang: \f6ad; +$fa-var-music: \f001; +$fa-var-code-commit: \f386; +$fa-var-temperature-low: \f76b; +$fa-var-person-biking: \f84a; +$fa-var-biking: \f84a; +$fa-var-broom: \f51a; +$fa-var-shield-heart: \e574; +$fa-var-gopuram: \f664; +$fa-var-earth-oceania: \e47b; +$fa-var-globe-oceania: \e47b; +$fa-var-square-xmark: \f2d3; +$fa-var-times-square: \f2d3; +$fa-var-xmark-square: \f2d3; +$fa-var-hashtag: \23; +$fa-var-up-right-and-down-left-from-center: \f424; +$fa-var-expand-alt: \f424; +$fa-var-oil-can: \f613; +$fa-var-t: \54; +$fa-var-hippo: \f6ed; +$fa-var-chart-column: \e0e3; +$fa-var-infinity: \f534; +$fa-var-vial-circle-check: \e596; +$fa-var-person-arrow-down-to-line: \e538; +$fa-var-voicemail: \f897; +$fa-var-fan: \f863; +$fa-var-person-walking-luggage: \e554; +$fa-var-up-down: \f338; +$fa-var-arrows-alt-v: \f338; +$fa-var-cloud-moon-rain: \f73c; +$fa-var-calendar: \f133; +$fa-var-trailer: \e041; +$fa-var-bahai: \f666; +$fa-var-haykal: \f666; +$fa-var-sd-card: \f7c2; +$fa-var-dragon: \f6d5; +$fa-var-shoe-prints: \f54b; +$fa-var-circle-plus: \f055; +$fa-var-plus-circle: \f055; +$fa-var-face-grin-tongue-wink: \f58b; +$fa-var-grin-tongue-wink: \f58b; +$fa-var-hand-holding: \f4bd; +$fa-var-plug-circle-exclamation: \e55d; +$fa-var-link-slash: \f127; +$fa-var-chain-broken: \f127; +$fa-var-chain-slash: \f127; +$fa-var-unlink: \f127; +$fa-var-clone: \f24d; +$fa-var-person-walking-arrow-loop-left: \e551; +$fa-var-arrow-up-z-a: \f882; +$fa-var-sort-alpha-up-alt: \f882; +$fa-var-fire-flame-curved: \f7e4; +$fa-var-fire-alt: \f7e4; +$fa-var-tornado: \f76f; +$fa-var-file-circle-plus: \e494; +$fa-var-book-quran: \f687; +$fa-var-quran: \f687; +$fa-var-anchor: \f13d; +$fa-var-border-all: \f84c; +$fa-var-face-angry: \f556; +$fa-var-angry: \f556; +$fa-var-cookie-bite: \f564; +$fa-var-arrow-trend-down: \e097; +$fa-var-rss: \f09e; +$fa-var-feed: \f09e; +$fa-var-draw-polygon: \f5ee; +$fa-var-scale-balanced: \f24e; +$fa-var-balance-scale: \f24e; +$fa-var-gauge-simple-high: \f62a; +$fa-var-tachometer: \f62a; +$fa-var-tachometer-fast: \f62a; +$fa-var-shower: \f2cc; +$fa-var-desktop: \f390; +$fa-var-desktop-alt: \f390; +$fa-var-m: \4d; +$fa-var-table-list: \f00b; +$fa-var-th-list: \f00b; +$fa-var-comment-sms: \f7cd; +$fa-var-sms: \f7cd; +$fa-var-book: \f02d; +$fa-var-user-plus: \f234; +$fa-var-check: \f00c; +$fa-var-battery-three-quarters: \f241; +$fa-var-battery-4: \f241; +$fa-var-house-circle-check: \e509; +$fa-var-angle-left: \f104; +$fa-var-diagram-successor: \e47a; +$fa-var-truck-arrow-right: \e58b; +$fa-var-arrows-split-up-and-left: \e4bc; +$fa-var-hand-fist: \f6de; +$fa-var-fist-raised: \f6de; +$fa-var-cloud-moon: \f6c3; +$fa-var-briefcase: \f0b1; +$fa-var-person-falling: \e546; +$fa-var-image-portrait: \f3e0; +$fa-var-portrait: \f3e0; +$fa-var-user-tag: \f507; +$fa-var-rug: \e569; +$fa-var-earth-europe: \f7a2; +$fa-var-globe-europe: \f7a2; +$fa-var-cart-flatbed-suitcase: \f59d; +$fa-var-luggage-cart: \f59d; +$fa-var-rectangle-xmark: \f410; +$fa-var-rectangle-times: \f410; +$fa-var-times-rectangle: \f410; +$fa-var-window-close: \f410; +$fa-var-baht-sign: \e0ac; +$fa-var-book-open: \f518; +$fa-var-book-journal-whills: \f66a; +$fa-var-journal-whills: \f66a; +$fa-var-handcuffs: \e4f8; +$fa-var-triangle-exclamation: \f071; +$fa-var-exclamation-triangle: \f071; +$fa-var-warning: \f071; +$fa-var-database: \f1c0; +$fa-var-share: \f064; +$fa-var-mail-forward: \f064; +$fa-var-bottle-droplet: \e4c4; +$fa-var-mask-face: \e1d7; +$fa-var-hill-rockslide: \e508; +$fa-var-right-left: \f362; +$fa-var-exchange-alt: \f362; +$fa-var-paper-plane: \f1d8; +$fa-var-road-circle-exclamation: \e565; +$fa-var-dungeon: \f6d9; +$fa-var-align-right: \f038; +$fa-var-money-bill-1-wave: \f53b; +$fa-var-money-bill-wave-alt: \f53b; +$fa-var-life-ring: \f1cd; +$fa-var-hands: \f2a7; +$fa-var-sign-language: \f2a7; +$fa-var-signing: \f2a7; +$fa-var-calendar-day: \f783; +$fa-var-water-ladder: \f5c5; +$fa-var-ladder-water: \f5c5; +$fa-var-swimming-pool: \f5c5; +$fa-var-arrows-up-down: \f07d; +$fa-var-arrows-v: \f07d; +$fa-var-face-grimace: \f57f; +$fa-var-grimace: \f57f; +$fa-var-wheelchair-move: \e2ce; +$fa-var-wheelchair-alt: \e2ce; +$fa-var-turn-down: \f3be; +$fa-var-level-down-alt: \f3be; +$fa-var-person-walking-arrow-right: \e552; +$fa-var-square-envelope: \f199; +$fa-var-envelope-square: \f199; +$fa-var-dice: \f522; +$fa-var-bowling-ball: \f436; +$fa-var-brain: \f5dc; +$fa-var-bandage: \f462; +$fa-var-band-aid: \f462; +$fa-var-calendar-minus: \f272; +$fa-var-circle-xmark: \f057; +$fa-var-times-circle: \f057; +$fa-var-xmark-circle: \f057; +$fa-var-gifts: \f79c; +$fa-var-hotel: \f594; +$fa-var-earth-asia: \f57e; +$fa-var-globe-asia: \f57e; +$fa-var-id-card-clip: \f47f; +$fa-var-id-card-alt: \f47f; +$fa-var-magnifying-glass-plus: \f00e; +$fa-var-search-plus: \f00e; +$fa-var-thumbs-up: \f164; +$fa-var-user-clock: \f4fd; +$fa-var-hand-dots: \f461; +$fa-var-allergies: \f461; +$fa-var-file-invoice: \f570; +$fa-var-window-minimize: \f2d1; +$fa-var-mug-saucer: \f0f4; +$fa-var-coffee: \f0f4; +$fa-var-brush: \f55d; +$fa-var-file-half-dashed: \e698; +$fa-var-mask: \f6fa; +$fa-var-magnifying-glass-minus: \f010; +$fa-var-search-minus: \f010; +$fa-var-ruler-vertical: \f548; +$fa-var-user-large: \f406; +$fa-var-user-alt: \f406; +$fa-var-train-tram: \e5b4; +$fa-var-user-nurse: \f82f; +$fa-var-syringe: \f48e; +$fa-var-cloud-sun: \f6c4; +$fa-var-stopwatch-20: \e06f; +$fa-var-square-full: \f45c; +$fa-var-magnet: \f076; +$fa-var-jar: \e516; +$fa-var-note-sticky: \f249; +$fa-var-sticky-note: \f249; +$fa-var-bug-slash: \e490; +$fa-var-arrow-up-from-water-pump: \e4b6; +$fa-var-bone: \f5d7; +$fa-var-table-cells-row-unlock: \e691; +$fa-var-user-injured: \f728; +$fa-var-face-sad-tear: \f5b4; +$fa-var-sad-tear: \f5b4; +$fa-var-plane: \f072; +$fa-var-tent-arrows-down: \e581; +$fa-var-exclamation: \21; +$fa-var-arrows-spin: \e4bb; +$fa-var-print: \f02f; +$fa-var-turkish-lira-sign: \e2bb; +$fa-var-try: \e2bb; +$fa-var-turkish-lira: \e2bb; +$fa-var-dollar-sign: \24; +$fa-var-dollar: \24; +$fa-var-usd: \24; +$fa-var-x: \58; +$fa-var-magnifying-glass-dollar: \f688; +$fa-var-search-dollar: \f688; +$fa-var-users-gear: \f509; +$fa-var-users-cog: \f509; +$fa-var-person-military-pointing: \e54a; +$fa-var-building-columns: \f19c; +$fa-var-bank: \f19c; +$fa-var-institution: \f19c; +$fa-var-museum: \f19c; +$fa-var-university: \f19c; +$fa-var-umbrella: \f0e9; +$fa-var-trowel: \e589; +$fa-var-d: \44; +$fa-var-stapler: \e5af; +$fa-var-masks-theater: \f630; +$fa-var-theater-masks: \f630; +$fa-var-kip-sign: \e1c4; +$fa-var-hand-point-left: \f0a5; +$fa-var-handshake-simple: \f4c6; +$fa-var-handshake-alt: \f4c6; +$fa-var-jet-fighter: \f0fb; +$fa-var-fighter-jet: \f0fb; +$fa-var-square-share-nodes: \f1e1; +$fa-var-share-alt-square: \f1e1; +$fa-var-barcode: \f02a; +$fa-var-plus-minus: \e43c; +$fa-var-video: \f03d; +$fa-var-video-camera: \f03d; +$fa-var-graduation-cap: \f19d; +$fa-var-mortar-board: \f19d; +$fa-var-hand-holding-medical: \e05c; +$fa-var-person-circle-check: \e53e; +$fa-var-turn-up: \f3bf; +$fa-var-level-up-alt: \f3bf; + +$fa-var-monero: \f3d0; +$fa-var-hooli: \f427; +$fa-var-yelp: \f1e9; +$fa-var-cc-visa: \f1f0; +$fa-var-lastfm: \f202; +$fa-var-shopware: \f5b5; +$fa-var-creative-commons-nc: \f4e8; +$fa-var-aws: \f375; +$fa-var-redhat: \f7bc; +$fa-var-yoast: \f2b1; +$fa-var-cloudflare: \e07d; +$fa-var-ups: \f7e0; +$fa-var-pixiv: \e640; +$fa-var-wpexplorer: \f2de; +$fa-var-dyalog: \f399; +$fa-var-bity: \f37a; +$fa-var-stackpath: \f842; +$fa-var-buysellads: \f20d; +$fa-var-first-order: \f2b0; +$fa-var-modx: \f285; +$fa-var-guilded: \e07e; +$fa-var-vnv: \f40b; +$fa-var-square-js: \f3b9; +$fa-var-js-square: \f3b9; +$fa-var-microsoft: \f3ca; +$fa-var-qq: \f1d6; +$fa-var-orcid: \f8d2; +$fa-var-java: \f4e4; +$fa-var-invision: \f7b0; +$fa-var-creative-commons-pd-alt: \f4ed; +$fa-var-centercode: \f380; +$fa-var-glide-g: \f2a6; +$fa-var-drupal: \f1a9; +$fa-var-jxl: \e67b; +$fa-var-dart-lang: \e693; +$fa-var-hire-a-helper: \f3b0; +$fa-var-creative-commons-by: \f4e7; +$fa-var-unity: \e049; +$fa-var-whmcs: \f40d; +$fa-var-rocketchat: \f3e8; +$fa-var-vk: \f189; +$fa-var-untappd: \f405; +$fa-var-mailchimp: \f59e; +$fa-var-css3-alt: \f38b; +$fa-var-square-reddit: \f1a2; +$fa-var-reddit-square: \f1a2; +$fa-var-vimeo-v: \f27d; +$fa-var-contao: \f26d; +$fa-var-square-font-awesome: \e5ad; +$fa-var-deskpro: \f38f; +$fa-var-brave: \e63c; +$fa-var-sistrix: \f3ee; +$fa-var-square-instagram: \e055; +$fa-var-instagram-square: \e055; +$fa-var-battle-net: \f835; +$fa-var-the-red-yeti: \f69d; +$fa-var-square-hacker-news: \f3af; +$fa-var-hacker-news-square: \f3af; +$fa-var-edge: \f282; +$fa-var-threads: \e618; +$fa-var-napster: \f3d2; +$fa-var-square-snapchat: \f2ad; +$fa-var-snapchat-square: \f2ad; +$fa-var-google-plus-g: \f0d5; +$fa-var-artstation: \f77a; +$fa-var-markdown: \f60f; +$fa-var-sourcetree: \f7d3; +$fa-var-google-plus: \f2b3; +$fa-var-diaspora: \f791; +$fa-var-foursquare: \f180; +$fa-var-stack-overflow: \f16c; +$fa-var-github-alt: \f113; +$fa-var-phoenix-squadron: \f511; +$fa-var-pagelines: \f18c; +$fa-var-algolia: \f36c; +$fa-var-red-river: \f3e3; +$fa-var-creative-commons-sa: \f4ef; +$fa-var-safari: \f267; +$fa-var-google: \f1a0; +$fa-var-square-font-awesome-stroke: \f35c; +$fa-var-font-awesome-alt: \f35c; +$fa-var-atlassian: \f77b; +$fa-var-linkedin-in: \f0e1; +$fa-var-digital-ocean: \f391; +$fa-var-nimblr: \f5a8; +$fa-var-chromecast: \f838; +$fa-var-evernote: \f839; +$fa-var-hacker-news: \f1d4; +$fa-var-creative-commons-sampling: \f4f0; +$fa-var-adversal: \f36a; +$fa-var-creative-commons: \f25e; +$fa-var-watchman-monitoring: \e087; +$fa-var-fonticons: \f280; +$fa-var-weixin: \f1d7; +$fa-var-shirtsinbulk: \f214; +$fa-var-codepen: \f1cb; +$fa-var-git-alt: \f841; +$fa-var-lyft: \f3c3; +$fa-var-rev: \f5b2; +$fa-var-windows: \f17a; +$fa-var-wizards-of-the-coast: \f730; +$fa-var-square-viadeo: \f2aa; +$fa-var-viadeo-square: \f2aa; +$fa-var-meetup: \f2e0; +$fa-var-centos: \f789; +$fa-var-adn: \f170; +$fa-var-cloudsmith: \f384; +$fa-var-opensuse: \e62b; +$fa-var-pied-piper-alt: \f1a8; +$fa-var-square-dribbble: \f397; +$fa-var-dribbble-square: \f397; +$fa-var-codiepie: \f284; +$fa-var-node: \f419; +$fa-var-mix: \f3cb; +$fa-var-steam: \f1b6; +$fa-var-cc-apple-pay: \f416; +$fa-var-scribd: \f28a; +$fa-var-debian: \e60b; +$fa-var-openid: \f19b; +$fa-var-instalod: \e081; +$fa-var-files-pinwheel: \e69f; +$fa-var-expeditedssl: \f23e; +$fa-var-sellcast: \f2da; +$fa-var-square-twitter: \f081; +$fa-var-twitter-square: \f081; +$fa-var-r-project: \f4f7; +$fa-var-delicious: \f1a5; +$fa-var-freebsd: \f3a4; +$fa-var-vuejs: \f41f; +$fa-var-accusoft: \f369; +$fa-var-ioxhost: \f208; +$fa-var-fonticons-fi: \f3a2; +$fa-var-app-store: \f36f; +$fa-var-cc-mastercard: \f1f1; +$fa-var-itunes-note: \f3b5; +$fa-var-golang: \e40f; +$fa-var-kickstarter: \f3bb; +$fa-var-square-kickstarter: \f3bb; +$fa-var-grav: \f2d6; +$fa-var-weibo: \f18a; +$fa-var-uncharted: \e084; +$fa-var-firstdraft: \f3a1; +$fa-var-square-youtube: \f431; +$fa-var-youtube-square: \f431; +$fa-var-wikipedia-w: \f266; +$fa-var-wpressr: \f3e4; +$fa-var-rendact: \f3e4; +$fa-var-angellist: \f209; +$fa-var-galactic-republic: \f50c; +$fa-var-nfc-directional: \e530; +$fa-var-skype: \f17e; +$fa-var-joget: \f3b7; +$fa-var-fedora: \f798; +$fa-var-stripe-s: \f42a; +$fa-var-meta: \e49b; +$fa-var-laravel: \f3bd; +$fa-var-hotjar: \f3b1; +$fa-var-bluetooth-b: \f294; +$fa-var-square-letterboxd: \e62e; +$fa-var-sticker-mule: \f3f7; +$fa-var-creative-commons-zero: \f4f3; +$fa-var-hips: \f452; +$fa-var-css: \e6a2; +$fa-var-behance: \f1b4; +$fa-var-reddit: \f1a1; +$fa-var-discord: \f392; +$fa-var-chrome: \f268; +$fa-var-app-store-ios: \f370; +$fa-var-cc-discover: \f1f2; +$fa-var-wpbeginner: \f297; +$fa-var-confluence: \f78d; +$fa-var-shoelace: \e60c; +$fa-var-mdb: \f8ca; +$fa-var-dochub: \f394; +$fa-var-accessible-icon: \f368; +$fa-var-ebay: \f4f4; +$fa-var-amazon: \f270; +$fa-var-unsplash: \e07c; +$fa-var-yarn: \f7e3; +$fa-var-square-steam: \f1b7; +$fa-var-steam-square: \f1b7; +$fa-var-500px: \f26e; +$fa-var-square-vimeo: \f194; +$fa-var-vimeo-square: \f194; +$fa-var-asymmetrik: \f372; +$fa-var-font-awesome: \f2b4; +$fa-var-font-awesome-flag: \f2b4; +$fa-var-font-awesome-logo-full: \f2b4; +$fa-var-gratipay: \f184; +$fa-var-apple: \f179; +$fa-var-hive: \e07f; +$fa-var-gitkraken: \f3a6; +$fa-var-keybase: \f4f5; +$fa-var-apple-pay: \f415; +$fa-var-padlet: \e4a0; +$fa-var-amazon-pay: \f42c; +$fa-var-square-github: \f092; +$fa-var-github-square: \f092; +$fa-var-stumbleupon: \f1a4; +$fa-var-fedex: \f797; +$fa-var-phoenix-framework: \f3dc; +$fa-var-shopify: \e057; +$fa-var-neos: \f612; +$fa-var-square-threads: \e619; +$fa-var-hackerrank: \f5f7; +$fa-var-researchgate: \f4f8; +$fa-var-swift: \f8e1; +$fa-var-angular: \f420; +$fa-var-speakap: \f3f3; +$fa-var-angrycreative: \f36e; +$fa-var-y-combinator: \f23b; +$fa-var-empire: \f1d1; +$fa-var-envira: \f299; +$fa-var-google-scholar: \e63b; +$fa-var-square-gitlab: \e5ae; +$fa-var-gitlab-square: \e5ae; +$fa-var-studiovinari: \f3f8; +$fa-var-pied-piper: \f2ae; +$fa-var-wordpress: \f19a; +$fa-var-product-hunt: \f288; +$fa-var-firefox: \f269; +$fa-var-linode: \f2b8; +$fa-var-goodreads: \f3a8; +$fa-var-square-odnoklassniki: \f264; +$fa-var-odnoklassniki-square: \f264; +$fa-var-jsfiddle: \f1cc; +$fa-var-sith: \f512; +$fa-var-themeisle: \f2b2; +$fa-var-page4: \f3d7; +$fa-var-hashnode: \e499; +$fa-var-react: \f41b; +$fa-var-cc-paypal: \f1f4; +$fa-var-squarespace: \f5be; +$fa-var-cc-stripe: \f1f5; +$fa-var-creative-commons-share: \f4f2; +$fa-var-bitcoin: \f379; +$fa-var-keycdn: \f3ba; +$fa-var-opera: \f26a; +$fa-var-itch-io: \f83a; +$fa-var-umbraco: \f8e8; +$fa-var-galactic-senate: \f50d; +$fa-var-ubuntu: \f7df; +$fa-var-draft2digital: \f396; +$fa-var-stripe: \f429; +$fa-var-houzz: \f27c; +$fa-var-gg: \f260; +$fa-var-dhl: \f790; +$fa-var-square-pinterest: \f0d3; +$fa-var-pinterest-square: \f0d3; +$fa-var-xing: \f168; +$fa-var-blackberry: \f37b; +$fa-var-creative-commons-pd: \f4ec; +$fa-var-playstation: \f3df; +$fa-var-quinscape: \f459; +$fa-var-less: \f41d; +$fa-var-blogger-b: \f37d; +$fa-var-opencart: \f23d; +$fa-var-vine: \f1ca; +$fa-var-signal-messenger: \e663; +$fa-var-paypal: \f1ed; +$fa-var-gitlab: \f296; +$fa-var-typo3: \f42b; +$fa-var-reddit-alien: \f281; +$fa-var-yahoo: \f19e; +$fa-var-dailymotion: \e052; +$fa-var-affiliatetheme: \f36b; +$fa-var-pied-piper-pp: \f1a7; +$fa-var-bootstrap: \f836; +$fa-var-odnoklassniki: \f263; +$fa-var-nfc-symbol: \e531; +$fa-var-mintbit: \e62f; +$fa-var-ethereum: \f42e; +$fa-var-speaker-deck: \f83c; +$fa-var-creative-commons-nc-eu: \f4e9; +$fa-var-patreon: \f3d9; +$fa-var-avianex: \f374; +$fa-var-ello: \f5f1; +$fa-var-gofore: \f3a7; +$fa-var-bimobject: \f378; +$fa-var-brave-reverse: \e63d; +$fa-var-facebook-f: \f39e; +$fa-var-square-google-plus: \f0d4; +$fa-var-google-plus-square: \f0d4; +$fa-var-web-awesome: \e682; +$fa-var-mandalorian: \f50f; +$fa-var-first-order-alt: \f50a; +$fa-var-osi: \f41a; +$fa-var-google-wallet: \f1ee; +$fa-var-d-and-d-beyond: \f6ca; +$fa-var-periscope: \f3da; +$fa-var-fulcrum: \f50b; +$fa-var-cloudscale: \f383; +$fa-var-forumbee: \f211; +$fa-var-mizuni: \f3cc; +$fa-var-schlix: \f3ea; +$fa-var-square-xing: \f169; +$fa-var-xing-square: \f169; +$fa-var-bandcamp: \f2d5; +$fa-var-wpforms: \f298; +$fa-var-cloudversify: \f385; +$fa-var-usps: \f7e1; +$fa-var-megaport: \f5a3; +$fa-var-magento: \f3c4; +$fa-var-spotify: \f1bc; +$fa-var-optin-monster: \f23c; +$fa-var-fly: \f417; +$fa-var-square-bluesky: \e6a3; +$fa-var-aviato: \f421; +$fa-var-itunes: \f3b4; +$fa-var-cuttlefish: \f38c; +$fa-var-blogger: \f37c; +$fa-var-flickr: \f16e; +$fa-var-viber: \f409; +$fa-var-soundcloud: \f1be; +$fa-var-digg: \f1a6; +$fa-var-tencent-weibo: \f1d5; +$fa-var-letterboxd: \e62d; +$fa-var-symfony: \f83d; +$fa-var-maxcdn: \f136; +$fa-var-etsy: \f2d7; +$fa-var-facebook-messenger: \f39f; +$fa-var-audible: \f373; +$fa-var-think-peaks: \f731; +$fa-var-bilibili: \e3d9; +$fa-var-erlang: \f39d; +$fa-var-x-twitter: \e61b; +$fa-var-cotton-bureau: \f89e; +$fa-var-dashcube: \f210; +$fa-var-42-group: \e080; +$fa-var-innosoft: \e080; +$fa-var-stack-exchange: \f18d; +$fa-var-elementor: \f430; +$fa-var-square-pied-piper: \e01e; +$fa-var-pied-piper-square: \e01e; +$fa-var-creative-commons-nd: \f4eb; +$fa-var-palfed: \f3d8; +$fa-var-superpowers: \f2dd; +$fa-var-resolving: \f3e7; +$fa-var-xbox: \f412; +$fa-var-square-web-awesome-stroke: \e684; +$fa-var-searchengin: \f3eb; +$fa-var-tiktok: \e07b; +$fa-var-square-facebook: \f082; +$fa-var-facebook-square: \f082; +$fa-var-renren: \f18b; +$fa-var-linux: \f17c; +$fa-var-glide: \f2a5; +$fa-var-linkedin: \f08c; +$fa-var-hubspot: \f3b2; +$fa-var-deploydog: \f38e; +$fa-var-twitch: \f1e8; +$fa-var-flutter: \e694; +$fa-var-ravelry: \f2d9; +$fa-var-mixer: \e056; +$fa-var-square-lastfm: \f203; +$fa-var-lastfm-square: \f203; +$fa-var-vimeo: \f40a; +$fa-var-mendeley: \f7b3; +$fa-var-uniregistry: \f404; +$fa-var-figma: \f799; +$fa-var-creative-commons-remix: \f4ee; +$fa-var-cc-amazon-pay: \f42d; +$fa-var-dropbox: \f16b; +$fa-var-instagram: \f16d; +$fa-var-cmplid: \e360; +$fa-var-upwork: \e641; +$fa-var-facebook: \f09a; +$fa-var-gripfire: \f3ac; +$fa-var-jedi-order: \f50e; +$fa-var-uikit: \f403; +$fa-var-fort-awesome-alt: \f3a3; +$fa-var-phabricator: \f3db; +$fa-var-ussunnah: \f407; +$fa-var-earlybirds: \f39a; +$fa-var-trade-federation: \f513; +$fa-var-autoprefixer: \f41c; +$fa-var-whatsapp: \f232; +$fa-var-square-upwork: \e67c; +$fa-var-slideshare: \f1e7; +$fa-var-google-play: \f3ab; +$fa-var-viadeo: \f2a9; +$fa-var-line: \f3c0; +$fa-var-google-drive: \f3aa; +$fa-var-servicestack: \f3ec; +$fa-var-simplybuilt: \f215; +$fa-var-bitbucket: \f171; +$fa-var-imdb: \f2d8; +$fa-var-deezer: \e077; +$fa-var-raspberry-pi: \f7bb; +$fa-var-jira: \f7b1; +$fa-var-docker: \f395; +$fa-var-screenpal: \e570; +$fa-var-bluetooth: \f293; +$fa-var-gitter: \f426; +$fa-var-d-and-d: \f38d; +$fa-var-microblog: \e01a; +$fa-var-cc-diners-club: \f24c; +$fa-var-gg-circle: \f261; +$fa-var-pied-piper-hat: \f4e5; +$fa-var-kickstarter-k: \f3bc; +$fa-var-yandex: \f413; +$fa-var-readme: \f4d5; +$fa-var-html5: \f13b; +$fa-var-sellsy: \f213; +$fa-var-square-web-awesome: \e683; +$fa-var-sass: \f41e; +$fa-var-wirsindhandwerk: \e2d0; +$fa-var-wsh: \e2d0; +$fa-var-buromobelexperte: \f37f; +$fa-var-salesforce: \f83b; +$fa-var-octopus-deploy: \e082; +$fa-var-medapps: \f3c6; +$fa-var-ns8: \f3d5; +$fa-var-pinterest-p: \f231; +$fa-var-apper: \f371; +$fa-var-fort-awesome: \f286; +$fa-var-waze: \f83f; +$fa-var-bluesky: \e671; +$fa-var-cc-jcb: \f24b; +$fa-var-snapchat: \f2ab; +$fa-var-snapchat-ghost: \f2ab; +$fa-var-fantasy-flight-games: \f6dc; +$fa-var-rust: \e07a; +$fa-var-wix: \f5cf; +$fa-var-square-behance: \f1b5; +$fa-var-behance-square: \f1b5; +$fa-var-supple: \f3f9; +$fa-var-webflow: \e65c; +$fa-var-rebel: \f1d0; +$fa-var-css3: \f13c; +$fa-var-staylinked: \f3f5; +$fa-var-kaggle: \f5fa; +$fa-var-space-awesome: \e5ac; +$fa-var-deviantart: \f1bd; +$fa-var-cpanel: \f388; +$fa-var-goodreads-g: \f3a9; +$fa-var-square-git: \f1d2; +$fa-var-git-square: \f1d2; +$fa-var-square-tumblr: \f174; +$fa-var-tumblr-square: \f174; +$fa-var-trello: \f181; +$fa-var-creative-commons-nc-jp: \f4ea; +$fa-var-get-pocket: \f265; +$fa-var-perbyte: \e083; +$fa-var-grunt: \f3ad; +$fa-var-weebly: \f5cc; +$fa-var-connectdevelop: \f20e; +$fa-var-leanpub: \f212; +$fa-var-black-tie: \f27e; +$fa-var-themeco: \f5c6; +$fa-var-python: \f3e2; +$fa-var-android: \f17b; +$fa-var-bots: \e340; +$fa-var-free-code-camp: \f2c5; +$fa-var-hornbill: \f592; +$fa-var-js: \f3b8; +$fa-var-ideal: \e013; +$fa-var-git: \f1d3; +$fa-var-dev: \f6cc; +$fa-var-sketch: \f7c6; +$fa-var-yandex-international: \f414; +$fa-var-cc-amex: \f1f3; +$fa-var-uber: \f402; +$fa-var-github: \f09b; +$fa-var-php: \f457; +$fa-var-alipay: \f642; +$fa-var-youtube: \f167; +$fa-var-skyatlas: \f216; +$fa-var-firefox-browser: \e007; +$fa-var-replyd: \f3e6; +$fa-var-suse: \f7d6; +$fa-var-jenkins: \f3b6; +$fa-var-twitter: \f099; +$fa-var-rockrms: \f3e9; +$fa-var-pinterest: \f0d2; +$fa-var-buffer: \f837; +$fa-var-npm: \f3d4; +$fa-var-yammer: \f840; +$fa-var-btc: \f15a; +$fa-var-dribbble: \f17d; +$fa-var-stumbleupon-circle: \f1a3; +$fa-var-internet-explorer: \f26b; +$fa-var-stubber: \e5c7; +$fa-var-telegram: \f2c6; +$fa-var-telegram-plane: \f2c6; +$fa-var-old-republic: \f510; +$fa-var-odysee: \e5c6; +$fa-var-square-whatsapp: \f40c; +$fa-var-whatsapp-square: \f40c; +$fa-var-node-js: \f3d3; +$fa-var-edge-legacy: \e078; +$fa-var-slack: \f198; +$fa-var-slack-hash: \f198; +$fa-var-medrt: \f3c8; +$fa-var-usb: \f287; +$fa-var-tumblr: \f173; +$fa-var-vaadin: \f408; +$fa-var-quora: \f2c4; +$fa-var-square-x-twitter: \e61a; +$fa-var-reacteurope: \f75d; +$fa-var-medium: \f23a; +$fa-var-medium-m: \f23a; +$fa-var-amilia: \f36d; +$fa-var-mixcloud: \f289; +$fa-var-flipboard: \f44d; +$fa-var-viacoin: \f237; +$fa-var-critical-role: \f6c9; +$fa-var-sitrox: \e44a; +$fa-var-discourse: \f393; +$fa-var-joomla: \f1aa; +$fa-var-mastodon: \f4f6; +$fa-var-airbnb: \f834; +$fa-var-wolf-pack-battalion: \f514; +$fa-var-buy-n-large: \f8a6; +$fa-var-gulp: \f3ae; +$fa-var-creative-commons-sampling-plus: \f4f1; +$fa-var-strava: \f428; +$fa-var-ember: \f423; +$fa-var-canadian-maple-leaf: \f785; +$fa-var-teamspeak: \f4f9; +$fa-var-pushed: \f3e1; +$fa-var-wordpress-simple: \f411; +$fa-var-nutritionix: \f3d6; +$fa-var-wodu: \e088; +$fa-var-google-pay: \e079; +$fa-var-intercom: \f7af; +$fa-var-zhihu: \f63f; +$fa-var-korvue: \f42f; +$fa-var-pix: \e43a; +$fa-var-steam-symbol: \f3f6; + +$fa-icons: ( + "0": $fa-var-0, + "1": $fa-var-1, + "2": $fa-var-2, + "3": $fa-var-3, + "4": $fa-var-4, + "5": $fa-var-5, + "6": $fa-var-6, + "7": $fa-var-7, + "8": $fa-var-8, + "9": $fa-var-9, + "fill-drip": $fa-var-fill-drip, + "arrows-to-circle": $fa-var-arrows-to-circle, + "circle-chevron-right": $fa-var-circle-chevron-right, + "chevron-circle-right": $fa-var-chevron-circle-right, + "at": $fa-var-at, + "trash-can": $fa-var-trash-can, + "trash-alt": $fa-var-trash-alt, + "text-height": $fa-var-text-height, + "user-xmark": $fa-var-user-xmark, + "user-times": $fa-var-user-times, + "stethoscope": $fa-var-stethoscope, + "message": $fa-var-message, + "comment-alt": $fa-var-comment-alt, + "info": $fa-var-info, + "down-left-and-up-right-to-center": $fa-var-down-left-and-up-right-to-center, + "compress-alt": $fa-var-compress-alt, + "explosion": $fa-var-explosion, + "file-lines": $fa-var-file-lines, + "file-alt": $fa-var-file-alt, + "file-text": $fa-var-file-text, + "wave-square": $fa-var-wave-square, + "ring": $fa-var-ring, + "building-un": $fa-var-building-un, + "dice-three": $fa-var-dice-three, + "calendar-days": $fa-var-calendar-days, + "calendar-alt": $fa-var-calendar-alt, + "anchor-circle-check": $fa-var-anchor-circle-check, + "building-circle-arrow-right": $fa-var-building-circle-arrow-right, + "volleyball": $fa-var-volleyball, + "volleyball-ball": $fa-var-volleyball-ball, + "arrows-up-to-line": $fa-var-arrows-up-to-line, + "sort-down": $fa-var-sort-down, + "sort-desc": $fa-var-sort-desc, + "circle-minus": $fa-var-circle-minus, + "minus-circle": $fa-var-minus-circle, + "door-open": $fa-var-door-open, + "right-from-bracket": $fa-var-right-from-bracket, + "sign-out-alt": $fa-var-sign-out-alt, + "atom": $fa-var-atom, + "soap": $fa-var-soap, + "icons": $fa-var-icons, + "heart-music-camera-bolt": $fa-var-heart-music-camera-bolt, + "microphone-lines-slash": $fa-var-microphone-lines-slash, + "microphone-alt-slash": $fa-var-microphone-alt-slash, + "bridge-circle-check": $fa-var-bridge-circle-check, + "pump-medical": $fa-var-pump-medical, + "fingerprint": $fa-var-fingerprint, + "hand-point-right": $fa-var-hand-point-right, + "magnifying-glass-location": $fa-var-magnifying-glass-location, + "search-location": $fa-var-search-location, + "forward-step": $fa-var-forward-step, + "step-forward": $fa-var-step-forward, + "face-smile-beam": $fa-var-face-smile-beam, + "smile-beam": $fa-var-smile-beam, + "flag-checkered": $fa-var-flag-checkered, + "football": $fa-var-football, + "football-ball": $fa-var-football-ball, + "school-circle-exclamation": $fa-var-school-circle-exclamation, + "crop": $fa-var-crop, + "angles-down": $fa-var-angles-down, + "angle-double-down": $fa-var-angle-double-down, + "users-rectangle": $fa-var-users-rectangle, + "people-roof": $fa-var-people-roof, + "people-line": $fa-var-people-line, + "beer-mug-empty": $fa-var-beer-mug-empty, + "beer": $fa-var-beer, + "diagram-predecessor": $fa-var-diagram-predecessor, + "arrow-up-long": $fa-var-arrow-up-long, + "long-arrow-up": $fa-var-long-arrow-up, + "fire-flame-simple": $fa-var-fire-flame-simple, + "burn": $fa-var-burn, + "person": $fa-var-person, + "male": $fa-var-male, + "laptop": $fa-var-laptop, + "file-csv": $fa-var-file-csv, + "menorah": $fa-var-menorah, + "truck-plane": $fa-var-truck-plane, + "record-vinyl": $fa-var-record-vinyl, + "face-grin-stars": $fa-var-face-grin-stars, + "grin-stars": $fa-var-grin-stars, + "bong": $fa-var-bong, + "spaghetti-monster-flying": $fa-var-spaghetti-monster-flying, + "pastafarianism": $fa-var-pastafarianism, + "arrow-down-up-across-line": $fa-var-arrow-down-up-across-line, + "spoon": $fa-var-spoon, + "utensil-spoon": $fa-var-utensil-spoon, + "jar-wheat": $fa-var-jar-wheat, + "envelopes-bulk": $fa-var-envelopes-bulk, + "mail-bulk": $fa-var-mail-bulk, + "file-circle-exclamation": $fa-var-file-circle-exclamation, + "circle-h": $fa-var-circle-h, + "hospital-symbol": $fa-var-hospital-symbol, + "pager": $fa-var-pager, + "address-book": $fa-var-address-book, + "contact-book": $fa-var-contact-book, + "strikethrough": $fa-var-strikethrough, + "k": $fa-var-k, + "landmark-flag": $fa-var-landmark-flag, + "pencil": $fa-var-pencil, + "pencil-alt": $fa-var-pencil-alt, + "backward": $fa-var-backward, + "caret-right": $fa-var-caret-right, + "comments": $fa-var-comments, + "paste": $fa-var-paste, + "file-clipboard": $fa-var-file-clipboard, + "code-pull-request": $fa-var-code-pull-request, + "clipboard-list": $fa-var-clipboard-list, + "truck-ramp-box": $fa-var-truck-ramp-box, + "truck-loading": $fa-var-truck-loading, + "user-check": $fa-var-user-check, + "vial-virus": $fa-var-vial-virus, + "sheet-plastic": $fa-var-sheet-plastic, + "blog": $fa-var-blog, + "user-ninja": $fa-var-user-ninja, + "person-arrow-up-from-line": $fa-var-person-arrow-up-from-line, + "scroll-torah": $fa-var-scroll-torah, + "torah": $fa-var-torah, + "broom-ball": $fa-var-broom-ball, + "quidditch": $fa-var-quidditch, + "quidditch-broom-ball": $fa-var-quidditch-broom-ball, + "toggle-off": $fa-var-toggle-off, + "box-archive": $fa-var-box-archive, + "archive": $fa-var-archive, + "person-drowning": $fa-var-person-drowning, + "arrow-down-9-1": $fa-var-arrow-down-9-1, + "sort-numeric-desc": $fa-var-sort-numeric-desc, + "sort-numeric-down-alt": $fa-var-sort-numeric-down-alt, + "face-grin-tongue-squint": $fa-var-face-grin-tongue-squint, + "grin-tongue-squint": $fa-var-grin-tongue-squint, + "spray-can": $fa-var-spray-can, + "truck-monster": $fa-var-truck-monster, + "w": $fa-var-w, + "earth-africa": $fa-var-earth-africa, + "globe-africa": $fa-var-globe-africa, + "rainbow": $fa-var-rainbow, + "circle-notch": $fa-var-circle-notch, + "tablet-screen-button": $fa-var-tablet-screen-button, + "tablet-alt": $fa-var-tablet-alt, + "paw": $fa-var-paw, + "cloud": $fa-var-cloud, + "trowel-bricks": $fa-var-trowel-bricks, + "face-flushed": $fa-var-face-flushed, + "flushed": $fa-var-flushed, + "hospital-user": $fa-var-hospital-user, + "tent-arrow-left-right": $fa-var-tent-arrow-left-right, + "gavel": $fa-var-gavel, + "legal": $fa-var-legal, + "binoculars": $fa-var-binoculars, + "microphone-slash": $fa-var-microphone-slash, + "box-tissue": $fa-var-box-tissue, + "motorcycle": $fa-var-motorcycle, + "bell-concierge": $fa-var-bell-concierge, + "concierge-bell": $fa-var-concierge-bell, + "pen-ruler": $fa-var-pen-ruler, + "pencil-ruler": $fa-var-pencil-ruler, + "people-arrows": $fa-var-people-arrows, + "people-arrows-left-right": $fa-var-people-arrows-left-right, + "mars-and-venus-burst": $fa-var-mars-and-venus-burst, + "square-caret-right": $fa-var-square-caret-right, + "caret-square-right": $fa-var-caret-square-right, + "scissors": $fa-var-scissors, + "cut": $fa-var-cut, + "sun-plant-wilt": $fa-var-sun-plant-wilt, + "toilets-portable": $fa-var-toilets-portable, + "hockey-puck": $fa-var-hockey-puck, + "table": $fa-var-table, + "magnifying-glass-arrow-right": $fa-var-magnifying-glass-arrow-right, + "tachograph-digital": $fa-var-tachograph-digital, + "digital-tachograph": $fa-var-digital-tachograph, + "users-slash": $fa-var-users-slash, + "clover": $fa-var-clover, + "reply": $fa-var-reply, + "mail-reply": $fa-var-mail-reply, + "star-and-crescent": $fa-var-star-and-crescent, + "house-fire": $fa-var-house-fire, + "square-minus": $fa-var-square-minus, + "minus-square": $fa-var-minus-square, + "helicopter": $fa-var-helicopter, + "compass": $fa-var-compass, + "square-caret-down": $fa-var-square-caret-down, + "caret-square-down": $fa-var-caret-square-down, + "file-circle-question": $fa-var-file-circle-question, + "laptop-code": $fa-var-laptop-code, + "swatchbook": $fa-var-swatchbook, + "prescription-bottle": $fa-var-prescription-bottle, + "bars": $fa-var-bars, + "navicon": $fa-var-navicon, + "people-group": $fa-var-people-group, + "hourglass-end": $fa-var-hourglass-end, + "hourglass-3": $fa-var-hourglass-3, + "heart-crack": $fa-var-heart-crack, + "heart-broken": $fa-var-heart-broken, + "square-up-right": $fa-var-square-up-right, + "external-link-square-alt": $fa-var-external-link-square-alt, + "face-kiss-beam": $fa-var-face-kiss-beam, + "kiss-beam": $fa-var-kiss-beam, + "film": $fa-var-film, + "ruler-horizontal": $fa-var-ruler-horizontal, + "people-robbery": $fa-var-people-robbery, + "lightbulb": $fa-var-lightbulb, + "caret-left": $fa-var-caret-left, + "circle-exclamation": $fa-var-circle-exclamation, + "exclamation-circle": $fa-var-exclamation-circle, + "school-circle-xmark": $fa-var-school-circle-xmark, + "arrow-right-from-bracket": $fa-var-arrow-right-from-bracket, + "sign-out": $fa-var-sign-out, + "circle-chevron-down": $fa-var-circle-chevron-down, + "chevron-circle-down": $fa-var-chevron-circle-down, + "unlock-keyhole": $fa-var-unlock-keyhole, + "unlock-alt": $fa-var-unlock-alt, + "cloud-showers-heavy": $fa-var-cloud-showers-heavy, + "headphones-simple": $fa-var-headphones-simple, + "headphones-alt": $fa-var-headphones-alt, + "sitemap": $fa-var-sitemap, + "circle-dollar-to-slot": $fa-var-circle-dollar-to-slot, + "donate": $fa-var-donate, + "memory": $fa-var-memory, + "road-spikes": $fa-var-road-spikes, + "fire-burner": $fa-var-fire-burner, + "flag": $fa-var-flag, + "hanukiah": $fa-var-hanukiah, + "feather": $fa-var-feather, + "volume-low": $fa-var-volume-low, + "volume-down": $fa-var-volume-down, + "comment-slash": $fa-var-comment-slash, + "cloud-sun-rain": $fa-var-cloud-sun-rain, + "compress": $fa-var-compress, + "wheat-awn": $fa-var-wheat-awn, + "wheat-alt": $fa-var-wheat-alt, + "ankh": $fa-var-ankh, + "hands-holding-child": $fa-var-hands-holding-child, + "asterisk": $fa-var-asterisk, + "square-check": $fa-var-square-check, + "check-square": $fa-var-check-square, + "peseta-sign": $fa-var-peseta-sign, + "heading": $fa-var-heading, + "header": $fa-var-header, + "ghost": $fa-var-ghost, + "list": $fa-var-list, + "list-squares": $fa-var-list-squares, + "square-phone-flip": $fa-var-square-phone-flip, + "phone-square-alt": $fa-var-phone-square-alt, + "cart-plus": $fa-var-cart-plus, + "gamepad": $fa-var-gamepad, + "circle-dot": $fa-var-circle-dot, + "dot-circle": $fa-var-dot-circle, + "face-dizzy": $fa-var-face-dizzy, + "dizzy": $fa-var-dizzy, + "egg": $fa-var-egg, + "house-medical-circle-xmark": $fa-var-house-medical-circle-xmark, + "campground": $fa-var-campground, + "folder-plus": $fa-var-folder-plus, + "futbol": $fa-var-futbol, + "futbol-ball": $fa-var-futbol-ball, + "soccer-ball": $fa-var-soccer-ball, + "paintbrush": $fa-var-paintbrush, + "paint-brush": $fa-var-paint-brush, + "lock": $fa-var-lock, + "gas-pump": $fa-var-gas-pump, + "hot-tub-person": $fa-var-hot-tub-person, + "hot-tub": $fa-var-hot-tub, + "map-location": $fa-var-map-location, + "map-marked": $fa-var-map-marked, + "house-flood-water": $fa-var-house-flood-water, + "tree": $fa-var-tree, + "bridge-lock": $fa-var-bridge-lock, + "sack-dollar": $fa-var-sack-dollar, + "pen-to-square": $fa-var-pen-to-square, + "edit": $fa-var-edit, + "car-side": $fa-var-car-side, + "share-nodes": $fa-var-share-nodes, + "share-alt": $fa-var-share-alt, + "heart-circle-minus": $fa-var-heart-circle-minus, + "hourglass-half": $fa-var-hourglass-half, + "hourglass-2": $fa-var-hourglass-2, + "microscope": $fa-var-microscope, + "sink": $fa-var-sink, + "bag-shopping": $fa-var-bag-shopping, + "shopping-bag": $fa-var-shopping-bag, + "arrow-down-z-a": $fa-var-arrow-down-z-a, + "sort-alpha-desc": $fa-var-sort-alpha-desc, + "sort-alpha-down-alt": $fa-var-sort-alpha-down-alt, + "mitten": $fa-var-mitten, + "person-rays": $fa-var-person-rays, + "users": $fa-var-users, + "eye-slash": $fa-var-eye-slash, + "flask-vial": $fa-var-flask-vial, + "hand": $fa-var-hand, + "hand-paper": $fa-var-hand-paper, + "om": $fa-var-om, + "worm": $fa-var-worm, + "house-circle-xmark": $fa-var-house-circle-xmark, + "plug": $fa-var-plug, + "chevron-up": $fa-var-chevron-up, + "hand-spock": $fa-var-hand-spock, + "stopwatch": $fa-var-stopwatch, + "face-kiss": $fa-var-face-kiss, + "kiss": $fa-var-kiss, + "bridge-circle-xmark": $fa-var-bridge-circle-xmark, + "face-grin-tongue": $fa-var-face-grin-tongue, + "grin-tongue": $fa-var-grin-tongue, + "chess-bishop": $fa-var-chess-bishop, + "face-grin-wink": $fa-var-face-grin-wink, + "grin-wink": $fa-var-grin-wink, + "ear-deaf": $fa-var-ear-deaf, + "deaf": $fa-var-deaf, + "deafness": $fa-var-deafness, + "hard-of-hearing": $fa-var-hard-of-hearing, + "road-circle-check": $fa-var-road-circle-check, + "dice-five": $fa-var-dice-five, + "square-rss": $fa-var-square-rss, + "rss-square": $fa-var-rss-square, + "land-mine-on": $fa-var-land-mine-on, + "i-cursor": $fa-var-i-cursor, + "stamp": $fa-var-stamp, + "stairs": $fa-var-stairs, + "i": $fa-var-i, + "hryvnia-sign": $fa-var-hryvnia-sign, + "hryvnia": $fa-var-hryvnia, + "pills": $fa-var-pills, + "face-grin-wide": $fa-var-face-grin-wide, + "grin-alt": $fa-var-grin-alt, + "tooth": $fa-var-tooth, + "v": $fa-var-v, + "bangladeshi-taka-sign": $fa-var-bangladeshi-taka-sign, + "bicycle": $fa-var-bicycle, + "staff-snake": $fa-var-staff-snake, + "rod-asclepius": $fa-var-rod-asclepius, + "rod-snake": $fa-var-rod-snake, + "staff-aesculapius": $fa-var-staff-aesculapius, + "head-side-cough-slash": $fa-var-head-side-cough-slash, + "truck-medical": $fa-var-truck-medical, + "ambulance": $fa-var-ambulance, + "wheat-awn-circle-exclamation": $fa-var-wheat-awn-circle-exclamation, + "snowman": $fa-var-snowman, + "mortar-pestle": $fa-var-mortar-pestle, + "road-barrier": $fa-var-road-barrier, + "school": $fa-var-school, + "igloo": $fa-var-igloo, + "joint": $fa-var-joint, + "angle-right": $fa-var-angle-right, + "horse": $fa-var-horse, + "q": $fa-var-q, + "g": $fa-var-g, + "notes-medical": $fa-var-notes-medical, + "temperature-half": $fa-var-temperature-half, + "temperature-2": $fa-var-temperature-2, + "thermometer-2": $fa-var-thermometer-2, + "thermometer-half": $fa-var-thermometer-half, + "dong-sign": $fa-var-dong-sign, + "capsules": $fa-var-capsules, + "poo-storm": $fa-var-poo-storm, + "poo-bolt": $fa-var-poo-bolt, + "face-frown-open": $fa-var-face-frown-open, + "frown-open": $fa-var-frown-open, + "hand-point-up": $fa-var-hand-point-up, + "money-bill": $fa-var-money-bill, + "bookmark": $fa-var-bookmark, + "align-justify": $fa-var-align-justify, + "umbrella-beach": $fa-var-umbrella-beach, + "helmet-un": $fa-var-helmet-un, + "bullseye": $fa-var-bullseye, + "bacon": $fa-var-bacon, + "hand-point-down": $fa-var-hand-point-down, + "arrow-up-from-bracket": $fa-var-arrow-up-from-bracket, + "folder": $fa-var-folder, + "folder-blank": $fa-var-folder-blank, + "file-waveform": $fa-var-file-waveform, + "file-medical-alt": $fa-var-file-medical-alt, + "radiation": $fa-var-radiation, + "chart-simple": $fa-var-chart-simple, + "mars-stroke": $fa-var-mars-stroke, + "vial": $fa-var-vial, + "gauge": $fa-var-gauge, + "dashboard": $fa-var-dashboard, + "gauge-med": $fa-var-gauge-med, + "tachometer-alt-average": $fa-var-tachometer-alt-average, + "wand-magic-sparkles": $fa-var-wand-magic-sparkles, + "magic-wand-sparkles": $fa-var-magic-wand-sparkles, + "e": $fa-var-e, + "pen-clip": $fa-var-pen-clip, + "pen-alt": $fa-var-pen-alt, + "bridge-circle-exclamation": $fa-var-bridge-circle-exclamation, + "user": $fa-var-user, + "school-circle-check": $fa-var-school-circle-check, + "dumpster": $fa-var-dumpster, + "van-shuttle": $fa-var-van-shuttle, + "shuttle-van": $fa-var-shuttle-van, + "building-user": $fa-var-building-user, + "square-caret-left": $fa-var-square-caret-left, + "caret-square-left": $fa-var-caret-square-left, + "highlighter": $fa-var-highlighter, + "key": $fa-var-key, + "bullhorn": $fa-var-bullhorn, + "globe": $fa-var-globe, + "synagogue": $fa-var-synagogue, + "person-half-dress": $fa-var-person-half-dress, + "road-bridge": $fa-var-road-bridge, + "location-arrow": $fa-var-location-arrow, + "c": $fa-var-c, + "tablet-button": $fa-var-tablet-button, + "building-lock": $fa-var-building-lock, + "pizza-slice": $fa-var-pizza-slice, + "money-bill-wave": $fa-var-money-bill-wave, + "chart-area": $fa-var-chart-area, + "area-chart": $fa-var-area-chart, + "house-flag": $fa-var-house-flag, + "person-circle-minus": $fa-var-person-circle-minus, + "ban": $fa-var-ban, + "cancel": $fa-var-cancel, + "camera-rotate": $fa-var-camera-rotate, + "spray-can-sparkles": $fa-var-spray-can-sparkles, + "air-freshener": $fa-var-air-freshener, + "star": $fa-var-star, + "repeat": $fa-var-repeat, + "cross": $fa-var-cross, + "box": $fa-var-box, + "venus-mars": $fa-var-venus-mars, + "arrow-pointer": $fa-var-arrow-pointer, + "mouse-pointer": $fa-var-mouse-pointer, + "maximize": $fa-var-maximize, + "expand-arrows-alt": $fa-var-expand-arrows-alt, + "charging-station": $fa-var-charging-station, + "shapes": $fa-var-shapes, + "triangle-circle-square": $fa-var-triangle-circle-square, + "shuffle": $fa-var-shuffle, + "random": $fa-var-random, + "person-running": $fa-var-person-running, + "running": $fa-var-running, + "mobile-retro": $fa-var-mobile-retro, + "grip-lines-vertical": $fa-var-grip-lines-vertical, + "spider": $fa-var-spider, + "hands-bound": $fa-var-hands-bound, + "file-invoice-dollar": $fa-var-file-invoice-dollar, + "plane-circle-exclamation": $fa-var-plane-circle-exclamation, + "x-ray": $fa-var-x-ray, + "spell-check": $fa-var-spell-check, + "slash": $fa-var-slash, + "computer-mouse": $fa-var-computer-mouse, + "mouse": $fa-var-mouse, + "arrow-right-to-bracket": $fa-var-arrow-right-to-bracket, + "sign-in": $fa-var-sign-in, + "shop-slash": $fa-var-shop-slash, + "store-alt-slash": $fa-var-store-alt-slash, + "server": $fa-var-server, + "virus-covid-slash": $fa-var-virus-covid-slash, + "shop-lock": $fa-var-shop-lock, + "hourglass-start": $fa-var-hourglass-start, + "hourglass-1": $fa-var-hourglass-1, + "blender-phone": $fa-var-blender-phone, + "building-wheat": $fa-var-building-wheat, + "person-breastfeeding": $fa-var-person-breastfeeding, + "right-to-bracket": $fa-var-right-to-bracket, + "sign-in-alt": $fa-var-sign-in-alt, + "venus": $fa-var-venus, + "passport": $fa-var-passport, + "thumbtack-slash": $fa-var-thumbtack-slash, + "thumb-tack-slash": $fa-var-thumb-tack-slash, + "heart-pulse": $fa-var-heart-pulse, + "heartbeat": $fa-var-heartbeat, + "people-carry-box": $fa-var-people-carry-box, + "people-carry": $fa-var-people-carry, + "temperature-high": $fa-var-temperature-high, + "microchip": $fa-var-microchip, + "crown": $fa-var-crown, + "weight-hanging": $fa-var-weight-hanging, + "xmarks-lines": $fa-var-xmarks-lines, + "file-prescription": $fa-var-file-prescription, + "weight-scale": $fa-var-weight-scale, + "weight": $fa-var-weight, + "user-group": $fa-var-user-group, + "user-friends": $fa-var-user-friends, + "arrow-up-a-z": $fa-var-arrow-up-a-z, + "sort-alpha-up": $fa-var-sort-alpha-up, + "chess-knight": $fa-var-chess-knight, + "face-laugh-squint": $fa-var-face-laugh-squint, + "laugh-squint": $fa-var-laugh-squint, + "wheelchair": $fa-var-wheelchair, + "circle-arrow-up": $fa-var-circle-arrow-up, + "arrow-circle-up": $fa-var-arrow-circle-up, + "toggle-on": $fa-var-toggle-on, + "person-walking": $fa-var-person-walking, + "walking": $fa-var-walking, + "l": $fa-var-l, + "fire": $fa-var-fire, + "bed-pulse": $fa-var-bed-pulse, + "procedures": $fa-var-procedures, + "shuttle-space": $fa-var-shuttle-space, + "space-shuttle": $fa-var-space-shuttle, + "face-laugh": $fa-var-face-laugh, + "laugh": $fa-var-laugh, + "folder-open": $fa-var-folder-open, + "heart-circle-plus": $fa-var-heart-circle-plus, + "code-fork": $fa-var-code-fork, + "city": $fa-var-city, + "microphone-lines": $fa-var-microphone-lines, + "microphone-alt": $fa-var-microphone-alt, + "pepper-hot": $fa-var-pepper-hot, + "unlock": $fa-var-unlock, + "colon-sign": $fa-var-colon-sign, + "headset": $fa-var-headset, + "store-slash": $fa-var-store-slash, + "road-circle-xmark": $fa-var-road-circle-xmark, + "user-minus": $fa-var-user-minus, + "mars-stroke-up": $fa-var-mars-stroke-up, + "mars-stroke-v": $fa-var-mars-stroke-v, + "champagne-glasses": $fa-var-champagne-glasses, + "glass-cheers": $fa-var-glass-cheers, + "clipboard": $fa-var-clipboard, + "house-circle-exclamation": $fa-var-house-circle-exclamation, + "file-arrow-up": $fa-var-file-arrow-up, + "file-upload": $fa-var-file-upload, + "wifi": $fa-var-wifi, + "wifi-3": $fa-var-wifi-3, + "wifi-strong": $fa-var-wifi-strong, + "bath": $fa-var-bath, + "bathtub": $fa-var-bathtub, + "underline": $fa-var-underline, + "user-pen": $fa-var-user-pen, + "user-edit": $fa-var-user-edit, + "signature": $fa-var-signature, + "stroopwafel": $fa-var-stroopwafel, + "bold": $fa-var-bold, + "anchor-lock": $fa-var-anchor-lock, + "building-ngo": $fa-var-building-ngo, + "manat-sign": $fa-var-manat-sign, + "not-equal": $fa-var-not-equal, + "border-top-left": $fa-var-border-top-left, + "border-style": $fa-var-border-style, + "map-location-dot": $fa-var-map-location-dot, + "map-marked-alt": $fa-var-map-marked-alt, + "jedi": $fa-var-jedi, + "square-poll-vertical": $fa-var-square-poll-vertical, + "poll": $fa-var-poll, + "mug-hot": $fa-var-mug-hot, + "car-battery": $fa-var-car-battery, + "battery-car": $fa-var-battery-car, + "gift": $fa-var-gift, + "dice-two": $fa-var-dice-two, + "chess-queen": $fa-var-chess-queen, + "glasses": $fa-var-glasses, + "chess-board": $fa-var-chess-board, + "building-circle-check": $fa-var-building-circle-check, + "person-chalkboard": $fa-var-person-chalkboard, + "mars-stroke-right": $fa-var-mars-stroke-right, + "mars-stroke-h": $fa-var-mars-stroke-h, + "hand-back-fist": $fa-var-hand-back-fist, + "hand-rock": $fa-var-hand-rock, + "square-caret-up": $fa-var-square-caret-up, + "caret-square-up": $fa-var-caret-square-up, + "cloud-showers-water": $fa-var-cloud-showers-water, + "chart-bar": $fa-var-chart-bar, + "bar-chart": $fa-var-bar-chart, + "hands-bubbles": $fa-var-hands-bubbles, + "hands-wash": $fa-var-hands-wash, + "less-than-equal": $fa-var-less-than-equal, + "train": $fa-var-train, + "eye-low-vision": $fa-var-eye-low-vision, + "low-vision": $fa-var-low-vision, + "crow": $fa-var-crow, + "sailboat": $fa-var-sailboat, + "window-restore": $fa-var-window-restore, + "square-plus": $fa-var-square-plus, + "plus-square": $fa-var-plus-square, + "torii-gate": $fa-var-torii-gate, + "frog": $fa-var-frog, + "bucket": $fa-var-bucket, + "image": $fa-var-image, + "microphone": $fa-var-microphone, + "cow": $fa-var-cow, + "caret-up": $fa-var-caret-up, + "screwdriver": $fa-var-screwdriver, + "folder-closed": $fa-var-folder-closed, + "house-tsunami": $fa-var-house-tsunami, + "square-nfi": $fa-var-square-nfi, + "arrow-up-from-ground-water": $fa-var-arrow-up-from-ground-water, + "martini-glass": $fa-var-martini-glass, + "glass-martini-alt": $fa-var-glass-martini-alt, + "square-binary": $fa-var-square-binary, + "rotate-left": $fa-var-rotate-left, + "rotate-back": $fa-var-rotate-back, + "rotate-backward": $fa-var-rotate-backward, + "undo-alt": $fa-var-undo-alt, + "table-columns": $fa-var-table-columns, + "columns": $fa-var-columns, + "lemon": $fa-var-lemon, + "head-side-mask": $fa-var-head-side-mask, + "handshake": $fa-var-handshake, + "gem": $fa-var-gem, + "dolly": $fa-var-dolly, + "dolly-box": $fa-var-dolly-box, + "smoking": $fa-var-smoking, + "minimize": $fa-var-minimize, + "compress-arrows-alt": $fa-var-compress-arrows-alt, + "monument": $fa-var-monument, + "snowplow": $fa-var-snowplow, + "angles-right": $fa-var-angles-right, + "angle-double-right": $fa-var-angle-double-right, + "cannabis": $fa-var-cannabis, + "circle-play": $fa-var-circle-play, + "play-circle": $fa-var-play-circle, + "tablets": $fa-var-tablets, + "ethernet": $fa-var-ethernet, + "euro-sign": $fa-var-euro-sign, + "eur": $fa-var-eur, + "euro": $fa-var-euro, + "chair": $fa-var-chair, + "circle-check": $fa-var-circle-check, + "check-circle": $fa-var-check-circle, + "circle-stop": $fa-var-circle-stop, + "stop-circle": $fa-var-stop-circle, + "compass-drafting": $fa-var-compass-drafting, + "drafting-compass": $fa-var-drafting-compass, + "plate-wheat": $fa-var-plate-wheat, + "icicles": $fa-var-icicles, + "person-shelter": $fa-var-person-shelter, + "neuter": $fa-var-neuter, + "id-badge": $fa-var-id-badge, + "marker": $fa-var-marker, + "face-laugh-beam": $fa-var-face-laugh-beam, + "laugh-beam": $fa-var-laugh-beam, + "helicopter-symbol": $fa-var-helicopter-symbol, + "universal-access": $fa-var-universal-access, + "circle-chevron-up": $fa-var-circle-chevron-up, + "chevron-circle-up": $fa-var-chevron-circle-up, + "lari-sign": $fa-var-lari-sign, + "volcano": $fa-var-volcano, + "person-walking-dashed-line-arrow-right": $fa-var-person-walking-dashed-line-arrow-right, + "sterling-sign": $fa-var-sterling-sign, + "gbp": $fa-var-gbp, + "pound-sign": $fa-var-pound-sign, + "viruses": $fa-var-viruses, + "square-person-confined": $fa-var-square-person-confined, + "user-tie": $fa-var-user-tie, + "arrow-down-long": $fa-var-arrow-down-long, + "long-arrow-down": $fa-var-long-arrow-down, + "tent-arrow-down-to-line": $fa-var-tent-arrow-down-to-line, + "certificate": $fa-var-certificate, + "reply-all": $fa-var-reply-all, + "mail-reply-all": $fa-var-mail-reply-all, + "suitcase": $fa-var-suitcase, + "person-skating": $fa-var-person-skating, + "skating": $fa-var-skating, + "filter-circle-dollar": $fa-var-filter-circle-dollar, + "funnel-dollar": $fa-var-funnel-dollar, + "camera-retro": $fa-var-camera-retro, + "circle-arrow-down": $fa-var-circle-arrow-down, + "arrow-circle-down": $fa-var-arrow-circle-down, + "file-import": $fa-var-file-import, + "arrow-right-to-file": $fa-var-arrow-right-to-file, + "square-arrow-up-right": $fa-var-square-arrow-up-right, + "external-link-square": $fa-var-external-link-square, + "box-open": $fa-var-box-open, + "scroll": $fa-var-scroll, + "spa": $fa-var-spa, + "location-pin-lock": $fa-var-location-pin-lock, + "pause": $fa-var-pause, + "hill-avalanche": $fa-var-hill-avalanche, + "temperature-empty": $fa-var-temperature-empty, + "temperature-0": $fa-var-temperature-0, + "thermometer-0": $fa-var-thermometer-0, + "thermometer-empty": $fa-var-thermometer-empty, + "bomb": $fa-var-bomb, + "registered": $fa-var-registered, + "address-card": $fa-var-address-card, + "contact-card": $fa-var-contact-card, + "vcard": $fa-var-vcard, + "scale-unbalanced-flip": $fa-var-scale-unbalanced-flip, + "balance-scale-right": $fa-var-balance-scale-right, + "subscript": $fa-var-subscript, + "diamond-turn-right": $fa-var-diamond-turn-right, + "directions": $fa-var-directions, + "burst": $fa-var-burst, + "house-laptop": $fa-var-house-laptop, + "laptop-house": $fa-var-laptop-house, + "face-tired": $fa-var-face-tired, + "tired": $fa-var-tired, + "money-bills": $fa-var-money-bills, + "smog": $fa-var-smog, + "crutch": $fa-var-crutch, + "cloud-arrow-up": $fa-var-cloud-arrow-up, + "cloud-upload": $fa-var-cloud-upload, + "cloud-upload-alt": $fa-var-cloud-upload-alt, + "palette": $fa-var-palette, + "arrows-turn-right": $fa-var-arrows-turn-right, + "vest": $fa-var-vest, + "ferry": $fa-var-ferry, + "arrows-down-to-people": $fa-var-arrows-down-to-people, + "seedling": $fa-var-seedling, + "sprout": $fa-var-sprout, + "left-right": $fa-var-left-right, + "arrows-alt-h": $fa-var-arrows-alt-h, + "boxes-packing": $fa-var-boxes-packing, + "circle-arrow-left": $fa-var-circle-arrow-left, + "arrow-circle-left": $fa-var-arrow-circle-left, + "group-arrows-rotate": $fa-var-group-arrows-rotate, + "bowl-food": $fa-var-bowl-food, + "candy-cane": $fa-var-candy-cane, + "arrow-down-wide-short": $fa-var-arrow-down-wide-short, + "sort-amount-asc": $fa-var-sort-amount-asc, + "sort-amount-down": $fa-var-sort-amount-down, + "cloud-bolt": $fa-var-cloud-bolt, + "thunderstorm": $fa-var-thunderstorm, + "text-slash": $fa-var-text-slash, + "remove-format": $fa-var-remove-format, + "face-smile-wink": $fa-var-face-smile-wink, + "smile-wink": $fa-var-smile-wink, + "file-word": $fa-var-file-word, + "file-powerpoint": $fa-var-file-powerpoint, + "arrows-left-right": $fa-var-arrows-left-right, + "arrows-h": $fa-var-arrows-h, + "house-lock": $fa-var-house-lock, + "cloud-arrow-down": $fa-var-cloud-arrow-down, + "cloud-download": $fa-var-cloud-download, + "cloud-download-alt": $fa-var-cloud-download-alt, + "children": $fa-var-children, + "chalkboard": $fa-var-chalkboard, + "blackboard": $fa-var-blackboard, + "user-large-slash": $fa-var-user-large-slash, + "user-alt-slash": $fa-var-user-alt-slash, + "envelope-open": $fa-var-envelope-open, + "handshake-simple-slash": $fa-var-handshake-simple-slash, + "handshake-alt-slash": $fa-var-handshake-alt-slash, + "mattress-pillow": $fa-var-mattress-pillow, + "guarani-sign": $fa-var-guarani-sign, + "arrows-rotate": $fa-var-arrows-rotate, + "refresh": $fa-var-refresh, + "sync": $fa-var-sync, + "fire-extinguisher": $fa-var-fire-extinguisher, + "cruzeiro-sign": $fa-var-cruzeiro-sign, + "greater-than-equal": $fa-var-greater-than-equal, + "shield-halved": $fa-var-shield-halved, + "shield-alt": $fa-var-shield-alt, + "book-atlas": $fa-var-book-atlas, + "atlas": $fa-var-atlas, + "virus": $fa-var-virus, + "envelope-circle-check": $fa-var-envelope-circle-check, + "layer-group": $fa-var-layer-group, + "arrows-to-dot": $fa-var-arrows-to-dot, + "archway": $fa-var-archway, + "heart-circle-check": $fa-var-heart-circle-check, + "house-chimney-crack": $fa-var-house-chimney-crack, + "house-damage": $fa-var-house-damage, + "file-zipper": $fa-var-file-zipper, + "file-archive": $fa-var-file-archive, + "square": $fa-var-square, + "martini-glass-empty": $fa-var-martini-glass-empty, + "glass-martini": $fa-var-glass-martini, + "couch": $fa-var-couch, + "cedi-sign": $fa-var-cedi-sign, + "italic": $fa-var-italic, + "table-cells-column-lock": $fa-var-table-cells-column-lock, + "church": $fa-var-church, + "comments-dollar": $fa-var-comments-dollar, + "democrat": $fa-var-democrat, + "z": $fa-var-z, + "person-skiing": $fa-var-person-skiing, + "skiing": $fa-var-skiing, + "road-lock": $fa-var-road-lock, + "a": $fa-var-a, + "temperature-arrow-down": $fa-var-temperature-arrow-down, + "temperature-down": $fa-var-temperature-down, + "feather-pointed": $fa-var-feather-pointed, + "feather-alt": $fa-var-feather-alt, + "p": $fa-var-p, + "snowflake": $fa-var-snowflake, + "newspaper": $fa-var-newspaper, + "rectangle-ad": $fa-var-rectangle-ad, + "ad": $fa-var-ad, + "circle-arrow-right": $fa-var-circle-arrow-right, + "arrow-circle-right": $fa-var-arrow-circle-right, + "filter-circle-xmark": $fa-var-filter-circle-xmark, + "locust": $fa-var-locust, + "sort": $fa-var-sort, + "unsorted": $fa-var-unsorted, + "list-ol": $fa-var-list-ol, + "list-1-2": $fa-var-list-1-2, + "list-numeric": $fa-var-list-numeric, + "person-dress-burst": $fa-var-person-dress-burst, + "money-check-dollar": $fa-var-money-check-dollar, + "money-check-alt": $fa-var-money-check-alt, + "vector-square": $fa-var-vector-square, + "bread-slice": $fa-var-bread-slice, + "language": $fa-var-language, + "face-kiss-wink-heart": $fa-var-face-kiss-wink-heart, + "kiss-wink-heart": $fa-var-kiss-wink-heart, + "filter": $fa-var-filter, + "question": $fa-var-question, + "file-signature": $fa-var-file-signature, + "up-down-left-right": $fa-var-up-down-left-right, + "arrows-alt": $fa-var-arrows-alt, + "house-chimney-user": $fa-var-house-chimney-user, + "hand-holding-heart": $fa-var-hand-holding-heart, + "puzzle-piece": $fa-var-puzzle-piece, + "money-check": $fa-var-money-check, + "star-half-stroke": $fa-var-star-half-stroke, + "star-half-alt": $fa-var-star-half-alt, + "code": $fa-var-code, + "whiskey-glass": $fa-var-whiskey-glass, + "glass-whiskey": $fa-var-glass-whiskey, + "building-circle-exclamation": $fa-var-building-circle-exclamation, + "magnifying-glass-chart": $fa-var-magnifying-glass-chart, + "arrow-up-right-from-square": $fa-var-arrow-up-right-from-square, + "external-link": $fa-var-external-link, + "cubes-stacked": $fa-var-cubes-stacked, + "won-sign": $fa-var-won-sign, + "krw": $fa-var-krw, + "won": $fa-var-won, + "virus-covid": $fa-var-virus-covid, + "austral-sign": $fa-var-austral-sign, + "f": $fa-var-f, + "leaf": $fa-var-leaf, + "road": $fa-var-road, + "taxi": $fa-var-taxi, + "cab": $fa-var-cab, + "person-circle-plus": $fa-var-person-circle-plus, + "chart-pie": $fa-var-chart-pie, + "pie-chart": $fa-var-pie-chart, + "bolt-lightning": $fa-var-bolt-lightning, + "sack-xmark": $fa-var-sack-xmark, + "file-excel": $fa-var-file-excel, + "file-contract": $fa-var-file-contract, + "fish-fins": $fa-var-fish-fins, + "building-flag": $fa-var-building-flag, + "face-grin-beam": $fa-var-face-grin-beam, + "grin-beam": $fa-var-grin-beam, + "object-ungroup": $fa-var-object-ungroup, + "poop": $fa-var-poop, + "location-pin": $fa-var-location-pin, + "map-marker": $fa-var-map-marker, + "kaaba": $fa-var-kaaba, + "toilet-paper": $fa-var-toilet-paper, + "helmet-safety": $fa-var-helmet-safety, + "hard-hat": $fa-var-hard-hat, + "hat-hard": $fa-var-hat-hard, + "eject": $fa-var-eject, + "circle-right": $fa-var-circle-right, + "arrow-alt-circle-right": $fa-var-arrow-alt-circle-right, + "plane-circle-check": $fa-var-plane-circle-check, + "face-rolling-eyes": $fa-var-face-rolling-eyes, + "meh-rolling-eyes": $fa-var-meh-rolling-eyes, + "object-group": $fa-var-object-group, + "chart-line": $fa-var-chart-line, + "line-chart": $fa-var-line-chart, + "mask-ventilator": $fa-var-mask-ventilator, + "arrow-right": $fa-var-arrow-right, + "signs-post": $fa-var-signs-post, + "map-signs": $fa-var-map-signs, + "cash-register": $fa-var-cash-register, + "person-circle-question": $fa-var-person-circle-question, + "h": $fa-var-h, + "tarp": $fa-var-tarp, + "screwdriver-wrench": $fa-var-screwdriver-wrench, + "tools": $fa-var-tools, + "arrows-to-eye": $fa-var-arrows-to-eye, + "plug-circle-bolt": $fa-var-plug-circle-bolt, + "heart": $fa-var-heart, + "mars-and-venus": $fa-var-mars-and-venus, + "house-user": $fa-var-house-user, + "home-user": $fa-var-home-user, + "dumpster-fire": $fa-var-dumpster-fire, + "house-crack": $fa-var-house-crack, + "martini-glass-citrus": $fa-var-martini-glass-citrus, + "cocktail": $fa-var-cocktail, + "face-surprise": $fa-var-face-surprise, + "surprise": $fa-var-surprise, + "bottle-water": $fa-var-bottle-water, + "circle-pause": $fa-var-circle-pause, + "pause-circle": $fa-var-pause-circle, + "toilet-paper-slash": $fa-var-toilet-paper-slash, + "apple-whole": $fa-var-apple-whole, + "apple-alt": $fa-var-apple-alt, + "kitchen-set": $fa-var-kitchen-set, + "r": $fa-var-r, + "temperature-quarter": $fa-var-temperature-quarter, + "temperature-1": $fa-var-temperature-1, + "thermometer-1": $fa-var-thermometer-1, + "thermometer-quarter": $fa-var-thermometer-quarter, + "cube": $fa-var-cube, + "bitcoin-sign": $fa-var-bitcoin-sign, + "shield-dog": $fa-var-shield-dog, + "solar-panel": $fa-var-solar-panel, + "lock-open": $fa-var-lock-open, + "elevator": $fa-var-elevator, + "money-bill-transfer": $fa-var-money-bill-transfer, + "money-bill-trend-up": $fa-var-money-bill-trend-up, + "house-flood-water-circle-arrow-right": $fa-var-house-flood-water-circle-arrow-right, + "square-poll-horizontal": $fa-var-square-poll-horizontal, + "poll-h": $fa-var-poll-h, + "circle": $fa-var-circle, + "backward-fast": $fa-var-backward-fast, + "fast-backward": $fa-var-fast-backward, + "recycle": $fa-var-recycle, + "user-astronaut": $fa-var-user-astronaut, + "plane-slash": $fa-var-plane-slash, + "trademark": $fa-var-trademark, + "basketball": $fa-var-basketball, + "basketball-ball": $fa-var-basketball-ball, + "satellite-dish": $fa-var-satellite-dish, + "circle-up": $fa-var-circle-up, + "arrow-alt-circle-up": $fa-var-arrow-alt-circle-up, + "mobile-screen-button": $fa-var-mobile-screen-button, + "mobile-alt": $fa-var-mobile-alt, + "volume-high": $fa-var-volume-high, + "volume-up": $fa-var-volume-up, + "users-rays": $fa-var-users-rays, + "wallet": $fa-var-wallet, + "clipboard-check": $fa-var-clipboard-check, + "file-audio": $fa-var-file-audio, + "burger": $fa-var-burger, + "hamburger": $fa-var-hamburger, + "wrench": $fa-var-wrench, + "bugs": $fa-var-bugs, + "rupee-sign": $fa-var-rupee-sign, + "rupee": $fa-var-rupee, + "file-image": $fa-var-file-image, + "circle-question": $fa-var-circle-question, + "question-circle": $fa-var-question-circle, + "plane-departure": $fa-var-plane-departure, + "handshake-slash": $fa-var-handshake-slash, + "book-bookmark": $fa-var-book-bookmark, + "code-branch": $fa-var-code-branch, + "hat-cowboy": $fa-var-hat-cowboy, + "bridge": $fa-var-bridge, + "phone-flip": $fa-var-phone-flip, + "phone-alt": $fa-var-phone-alt, + "truck-front": $fa-var-truck-front, + "cat": $fa-var-cat, + "anchor-circle-exclamation": $fa-var-anchor-circle-exclamation, + "truck-field": $fa-var-truck-field, + "route": $fa-var-route, + "clipboard-question": $fa-var-clipboard-question, + "panorama": $fa-var-panorama, + "comment-medical": $fa-var-comment-medical, + "teeth-open": $fa-var-teeth-open, + "file-circle-minus": $fa-var-file-circle-minus, + "tags": $fa-var-tags, + "wine-glass": $fa-var-wine-glass, + "forward-fast": $fa-var-forward-fast, + "fast-forward": $fa-var-fast-forward, + "face-meh-blank": $fa-var-face-meh-blank, + "meh-blank": $fa-var-meh-blank, + "square-parking": $fa-var-square-parking, + "parking": $fa-var-parking, + "house-signal": $fa-var-house-signal, + "bars-progress": $fa-var-bars-progress, + "tasks-alt": $fa-var-tasks-alt, + "faucet-drip": $fa-var-faucet-drip, + "cart-flatbed": $fa-var-cart-flatbed, + "dolly-flatbed": $fa-var-dolly-flatbed, + "ban-smoking": $fa-var-ban-smoking, + "smoking-ban": $fa-var-smoking-ban, + "terminal": $fa-var-terminal, + "mobile-button": $fa-var-mobile-button, + "house-medical-flag": $fa-var-house-medical-flag, + "basket-shopping": $fa-var-basket-shopping, + "shopping-basket": $fa-var-shopping-basket, + "tape": $fa-var-tape, + "bus-simple": $fa-var-bus-simple, + "bus-alt": $fa-var-bus-alt, + "eye": $fa-var-eye, + "face-sad-cry": $fa-var-face-sad-cry, + "sad-cry": $fa-var-sad-cry, + "audio-description": $fa-var-audio-description, + "person-military-to-person": $fa-var-person-military-to-person, + "file-shield": $fa-var-file-shield, + "user-slash": $fa-var-user-slash, + "pen": $fa-var-pen, + "tower-observation": $fa-var-tower-observation, + "file-code": $fa-var-file-code, + "signal": $fa-var-signal, + "signal-5": $fa-var-signal-5, + "signal-perfect": $fa-var-signal-perfect, + "bus": $fa-var-bus, + "heart-circle-xmark": $fa-var-heart-circle-xmark, + "house-chimney": $fa-var-house-chimney, + "home-lg": $fa-var-home-lg, + "window-maximize": $fa-var-window-maximize, + "face-frown": $fa-var-face-frown, + "frown": $fa-var-frown, + "prescription": $fa-var-prescription, + "shop": $fa-var-shop, + "store-alt": $fa-var-store-alt, + "floppy-disk": $fa-var-floppy-disk, + "save": $fa-var-save, + "vihara": $fa-var-vihara, + "scale-unbalanced": $fa-var-scale-unbalanced, + "balance-scale-left": $fa-var-balance-scale-left, + "sort-up": $fa-var-sort-up, + "sort-asc": $fa-var-sort-asc, + "comment-dots": $fa-var-comment-dots, + "commenting": $fa-var-commenting, + "plant-wilt": $fa-var-plant-wilt, + "diamond": $fa-var-diamond, + "face-grin-squint": $fa-var-face-grin-squint, + "grin-squint": $fa-var-grin-squint, + "hand-holding-dollar": $fa-var-hand-holding-dollar, + "hand-holding-usd": $fa-var-hand-holding-usd, + "chart-diagram": $fa-var-chart-diagram, + "bacterium": $fa-var-bacterium, + "hand-pointer": $fa-var-hand-pointer, + "drum-steelpan": $fa-var-drum-steelpan, + "hand-scissors": $fa-var-hand-scissors, + "hands-praying": $fa-var-hands-praying, + "praying-hands": $fa-var-praying-hands, + "arrow-rotate-right": $fa-var-arrow-rotate-right, + "arrow-right-rotate": $fa-var-arrow-right-rotate, + "arrow-rotate-forward": $fa-var-arrow-rotate-forward, + "redo": $fa-var-redo, + "biohazard": $fa-var-biohazard, + "location-crosshairs": $fa-var-location-crosshairs, + "location": $fa-var-location, + "mars-double": $fa-var-mars-double, + "child-dress": $fa-var-child-dress, + "users-between-lines": $fa-var-users-between-lines, + "lungs-virus": $fa-var-lungs-virus, + "face-grin-tears": $fa-var-face-grin-tears, + "grin-tears": $fa-var-grin-tears, + "phone": $fa-var-phone, + "calendar-xmark": $fa-var-calendar-xmark, + "calendar-times": $fa-var-calendar-times, + "child-reaching": $fa-var-child-reaching, + "head-side-virus": $fa-var-head-side-virus, + "user-gear": $fa-var-user-gear, + "user-cog": $fa-var-user-cog, + "arrow-up-1-9": $fa-var-arrow-up-1-9, + "sort-numeric-up": $fa-var-sort-numeric-up, + "door-closed": $fa-var-door-closed, + "shield-virus": $fa-var-shield-virus, + "dice-six": $fa-var-dice-six, + "mosquito-net": $fa-var-mosquito-net, + "file-fragment": $fa-var-file-fragment, + "bridge-water": $fa-var-bridge-water, + "person-booth": $fa-var-person-booth, + "text-width": $fa-var-text-width, + "hat-wizard": $fa-var-hat-wizard, + "pen-fancy": $fa-var-pen-fancy, + "person-digging": $fa-var-person-digging, + "digging": $fa-var-digging, + "trash": $fa-var-trash, + "gauge-simple": $fa-var-gauge-simple, + "gauge-simple-med": $fa-var-gauge-simple-med, + "tachometer-average": $fa-var-tachometer-average, + "book-medical": $fa-var-book-medical, + "poo": $fa-var-poo, + "quote-right": $fa-var-quote-right, + "quote-right-alt": $fa-var-quote-right-alt, + "shirt": $fa-var-shirt, + "t-shirt": $fa-var-t-shirt, + "tshirt": $fa-var-tshirt, + "cubes": $fa-var-cubes, + "divide": $fa-var-divide, + "tenge-sign": $fa-var-tenge-sign, + "tenge": $fa-var-tenge, + "headphones": $fa-var-headphones, + "hands-holding": $fa-var-hands-holding, + "hands-clapping": $fa-var-hands-clapping, + "republican": $fa-var-republican, + "arrow-left": $fa-var-arrow-left, + "person-circle-xmark": $fa-var-person-circle-xmark, + "ruler": $fa-var-ruler, + "align-left": $fa-var-align-left, + "dice-d6": $fa-var-dice-d6, + "restroom": $fa-var-restroom, + "j": $fa-var-j, + "users-viewfinder": $fa-var-users-viewfinder, + "file-video": $fa-var-file-video, + "up-right-from-square": $fa-var-up-right-from-square, + "external-link-alt": $fa-var-external-link-alt, + "table-cells": $fa-var-table-cells, + "th": $fa-var-th, + "file-pdf": $fa-var-file-pdf, + "book-bible": $fa-var-book-bible, + "bible": $fa-var-bible, + "o": $fa-var-o, + "suitcase-medical": $fa-var-suitcase-medical, + "medkit": $fa-var-medkit, + "user-secret": $fa-var-user-secret, + "otter": $fa-var-otter, + "person-dress": $fa-var-person-dress, + "female": $fa-var-female, + "comment-dollar": $fa-var-comment-dollar, + "business-time": $fa-var-business-time, + "briefcase-clock": $fa-var-briefcase-clock, + "table-cells-large": $fa-var-table-cells-large, + "th-large": $fa-var-th-large, + "book-tanakh": $fa-var-book-tanakh, + "tanakh": $fa-var-tanakh, + "phone-volume": $fa-var-phone-volume, + "volume-control-phone": $fa-var-volume-control-phone, + "hat-cowboy-side": $fa-var-hat-cowboy-side, + "clipboard-user": $fa-var-clipboard-user, + "child": $fa-var-child, + "lira-sign": $fa-var-lira-sign, + "satellite": $fa-var-satellite, + "plane-lock": $fa-var-plane-lock, + "tag": $fa-var-tag, + "comment": $fa-var-comment, + "cake-candles": $fa-var-cake-candles, + "birthday-cake": $fa-var-birthday-cake, + "cake": $fa-var-cake, + "envelope": $fa-var-envelope, + "angles-up": $fa-var-angles-up, + "angle-double-up": $fa-var-angle-double-up, + "paperclip": $fa-var-paperclip, + "arrow-right-to-city": $fa-var-arrow-right-to-city, + "ribbon": $fa-var-ribbon, + "lungs": $fa-var-lungs, + "arrow-up-9-1": $fa-var-arrow-up-9-1, + "sort-numeric-up-alt": $fa-var-sort-numeric-up-alt, + "litecoin-sign": $fa-var-litecoin-sign, + "border-none": $fa-var-border-none, + "circle-nodes": $fa-var-circle-nodes, + "parachute-box": $fa-var-parachute-box, + "indent": $fa-var-indent, + "truck-field-un": $fa-var-truck-field-un, + "hourglass": $fa-var-hourglass, + "hourglass-empty": $fa-var-hourglass-empty, + "mountain": $fa-var-mountain, + "user-doctor": $fa-var-user-doctor, + "user-md": $fa-var-user-md, + "circle-info": $fa-var-circle-info, + "info-circle": $fa-var-info-circle, + "cloud-meatball": $fa-var-cloud-meatball, + "camera": $fa-var-camera, + "camera-alt": $fa-var-camera-alt, + "square-virus": $fa-var-square-virus, + "meteor": $fa-var-meteor, + "car-on": $fa-var-car-on, + "sleigh": $fa-var-sleigh, + "arrow-down-1-9": $fa-var-arrow-down-1-9, + "sort-numeric-asc": $fa-var-sort-numeric-asc, + "sort-numeric-down": $fa-var-sort-numeric-down, + "hand-holding-droplet": $fa-var-hand-holding-droplet, + "hand-holding-water": $fa-var-hand-holding-water, + "water": $fa-var-water, + "calendar-check": $fa-var-calendar-check, + "braille": $fa-var-braille, + "prescription-bottle-medical": $fa-var-prescription-bottle-medical, + "prescription-bottle-alt": $fa-var-prescription-bottle-alt, + "landmark": $fa-var-landmark, + "truck": $fa-var-truck, + "crosshairs": $fa-var-crosshairs, + "person-cane": $fa-var-person-cane, + "tent": $fa-var-tent, + "vest-patches": $fa-var-vest-patches, + "check-double": $fa-var-check-double, + "arrow-down-a-z": $fa-var-arrow-down-a-z, + "sort-alpha-asc": $fa-var-sort-alpha-asc, + "sort-alpha-down": $fa-var-sort-alpha-down, + "money-bill-wheat": $fa-var-money-bill-wheat, + "cookie": $fa-var-cookie, + "arrow-rotate-left": $fa-var-arrow-rotate-left, + "arrow-left-rotate": $fa-var-arrow-left-rotate, + "arrow-rotate-back": $fa-var-arrow-rotate-back, + "arrow-rotate-backward": $fa-var-arrow-rotate-backward, + "undo": $fa-var-undo, + "hard-drive": $fa-var-hard-drive, + "hdd": $fa-var-hdd, + "face-grin-squint-tears": $fa-var-face-grin-squint-tears, + "grin-squint-tears": $fa-var-grin-squint-tears, + "dumbbell": $fa-var-dumbbell, + "rectangle-list": $fa-var-rectangle-list, + "list-alt": $fa-var-list-alt, + "tarp-droplet": $fa-var-tarp-droplet, + "house-medical-circle-check": $fa-var-house-medical-circle-check, + "person-skiing-nordic": $fa-var-person-skiing-nordic, + "skiing-nordic": $fa-var-skiing-nordic, + "calendar-plus": $fa-var-calendar-plus, + "plane-arrival": $fa-var-plane-arrival, + "circle-left": $fa-var-circle-left, + "arrow-alt-circle-left": $fa-var-arrow-alt-circle-left, + "train-subway": $fa-var-train-subway, + "subway": $fa-var-subway, + "chart-gantt": $fa-var-chart-gantt, + "indian-rupee-sign": $fa-var-indian-rupee-sign, + "indian-rupee": $fa-var-indian-rupee, + "inr": $fa-var-inr, + "crop-simple": $fa-var-crop-simple, + "crop-alt": $fa-var-crop-alt, + "money-bill-1": $fa-var-money-bill-1, + "money-bill-alt": $fa-var-money-bill-alt, + "left-long": $fa-var-left-long, + "long-arrow-alt-left": $fa-var-long-arrow-alt-left, + "dna": $fa-var-dna, + "virus-slash": $fa-var-virus-slash, + "minus": $fa-var-minus, + "subtract": $fa-var-subtract, + "chess": $fa-var-chess, + "arrow-left-long": $fa-var-arrow-left-long, + "long-arrow-left": $fa-var-long-arrow-left, + "plug-circle-check": $fa-var-plug-circle-check, + "street-view": $fa-var-street-view, + "franc-sign": $fa-var-franc-sign, + "volume-off": $fa-var-volume-off, + "hands-asl-interpreting": $fa-var-hands-asl-interpreting, + "american-sign-language-interpreting": $fa-var-american-sign-language-interpreting, + "asl-interpreting": $fa-var-asl-interpreting, + "hands-american-sign-language-interpreting": $fa-var-hands-american-sign-language-interpreting, + "gear": $fa-var-gear, + "cog": $fa-var-cog, + "droplet-slash": $fa-var-droplet-slash, + "tint-slash": $fa-var-tint-slash, + "mosque": $fa-var-mosque, + "mosquito": $fa-var-mosquito, + "star-of-david": $fa-var-star-of-david, + "person-military-rifle": $fa-var-person-military-rifle, + "cart-shopping": $fa-var-cart-shopping, + "shopping-cart": $fa-var-shopping-cart, + "vials": $fa-var-vials, + "plug-circle-plus": $fa-var-plug-circle-plus, + "place-of-worship": $fa-var-place-of-worship, + "grip-vertical": $fa-var-grip-vertical, + "hexagon-nodes": $fa-var-hexagon-nodes, + "arrow-turn-up": $fa-var-arrow-turn-up, + "level-up": $fa-var-level-up, + "u": $fa-var-u, + "square-root-variable": $fa-var-square-root-variable, + "square-root-alt": $fa-var-square-root-alt, + "clock": $fa-var-clock, + "clock-four": $fa-var-clock-four, + "backward-step": $fa-var-backward-step, + "step-backward": $fa-var-step-backward, + "pallet": $fa-var-pallet, + "faucet": $fa-var-faucet, + "baseball-bat-ball": $fa-var-baseball-bat-ball, + "s": $fa-var-s, + "timeline": $fa-var-timeline, + "keyboard": $fa-var-keyboard, + "caret-down": $fa-var-caret-down, + "house-chimney-medical": $fa-var-house-chimney-medical, + "clinic-medical": $fa-var-clinic-medical, + "temperature-three-quarters": $fa-var-temperature-three-quarters, + "temperature-3": $fa-var-temperature-3, + "thermometer-3": $fa-var-thermometer-3, + "thermometer-three-quarters": $fa-var-thermometer-three-quarters, + "mobile-screen": $fa-var-mobile-screen, + "mobile-android-alt": $fa-var-mobile-android-alt, + "plane-up": $fa-var-plane-up, + "piggy-bank": $fa-var-piggy-bank, + "battery-half": $fa-var-battery-half, + "battery-3": $fa-var-battery-3, + "mountain-city": $fa-var-mountain-city, + "coins": $fa-var-coins, + "khanda": $fa-var-khanda, + "sliders": $fa-var-sliders, + "sliders-h": $fa-var-sliders-h, + "folder-tree": $fa-var-folder-tree, + "network-wired": $fa-var-network-wired, + "map-pin": $fa-var-map-pin, + "hamsa": $fa-var-hamsa, + "cent-sign": $fa-var-cent-sign, + "flask": $fa-var-flask, + "person-pregnant": $fa-var-person-pregnant, + "wand-sparkles": $fa-var-wand-sparkles, + "ellipsis-vertical": $fa-var-ellipsis-vertical, + "ellipsis-v": $fa-var-ellipsis-v, + "ticket": $fa-var-ticket, + "power-off": $fa-var-power-off, + "right-long": $fa-var-right-long, + "long-arrow-alt-right": $fa-var-long-arrow-alt-right, + "flag-usa": $fa-var-flag-usa, + "laptop-file": $fa-var-laptop-file, + "tty": $fa-var-tty, + "teletype": $fa-var-teletype, + "diagram-next": $fa-var-diagram-next, + "person-rifle": $fa-var-person-rifle, + "house-medical-circle-exclamation": $fa-var-house-medical-circle-exclamation, + "closed-captioning": $fa-var-closed-captioning, + "person-hiking": $fa-var-person-hiking, + "hiking": $fa-var-hiking, + "venus-double": $fa-var-venus-double, + "images": $fa-var-images, + "calculator": $fa-var-calculator, + "people-pulling": $fa-var-people-pulling, + "n": $fa-var-n, + "cable-car": $fa-var-cable-car, + "tram": $fa-var-tram, + "cloud-rain": $fa-var-cloud-rain, + "building-circle-xmark": $fa-var-building-circle-xmark, + "ship": $fa-var-ship, + "arrows-down-to-line": $fa-var-arrows-down-to-line, + "download": $fa-var-download, + "face-grin": $fa-var-face-grin, + "grin": $fa-var-grin, + "delete-left": $fa-var-delete-left, + "backspace": $fa-var-backspace, + "eye-dropper": $fa-var-eye-dropper, + "eye-dropper-empty": $fa-var-eye-dropper-empty, + "eyedropper": $fa-var-eyedropper, + "file-circle-check": $fa-var-file-circle-check, + "forward": $fa-var-forward, + "mobile": $fa-var-mobile, + "mobile-android": $fa-var-mobile-android, + "mobile-phone": $fa-var-mobile-phone, + "face-meh": $fa-var-face-meh, + "meh": $fa-var-meh, + "align-center": $fa-var-align-center, + "book-skull": $fa-var-book-skull, + "book-dead": $fa-var-book-dead, + "id-card": $fa-var-id-card, + "drivers-license": $fa-var-drivers-license, + "outdent": $fa-var-outdent, + "dedent": $fa-var-dedent, + "heart-circle-exclamation": $fa-var-heart-circle-exclamation, + "house": $fa-var-house, + "home": $fa-var-home, + "home-alt": $fa-var-home-alt, + "home-lg-alt": $fa-var-home-lg-alt, + "calendar-week": $fa-var-calendar-week, + "laptop-medical": $fa-var-laptop-medical, + "b": $fa-var-b, + "file-medical": $fa-var-file-medical, + "dice-one": $fa-var-dice-one, + "kiwi-bird": $fa-var-kiwi-bird, + "arrow-right-arrow-left": $fa-var-arrow-right-arrow-left, + "exchange": $fa-var-exchange, + "rotate-right": $fa-var-rotate-right, + "redo-alt": $fa-var-redo-alt, + "rotate-forward": $fa-var-rotate-forward, + "utensils": $fa-var-utensils, + "cutlery": $fa-var-cutlery, + "arrow-up-wide-short": $fa-var-arrow-up-wide-short, + "sort-amount-up": $fa-var-sort-amount-up, + "mill-sign": $fa-var-mill-sign, + "bowl-rice": $fa-var-bowl-rice, + "skull": $fa-var-skull, + "tower-broadcast": $fa-var-tower-broadcast, + "broadcast-tower": $fa-var-broadcast-tower, + "truck-pickup": $fa-var-truck-pickup, + "up-long": $fa-var-up-long, + "long-arrow-alt-up": $fa-var-long-arrow-alt-up, + "stop": $fa-var-stop, + "code-merge": $fa-var-code-merge, + "upload": $fa-var-upload, + "hurricane": $fa-var-hurricane, + "mound": $fa-var-mound, + "toilet-portable": $fa-var-toilet-portable, + "compact-disc": $fa-var-compact-disc, + "file-arrow-down": $fa-var-file-arrow-down, + "file-download": $fa-var-file-download, + "caravan": $fa-var-caravan, + "shield-cat": $fa-var-shield-cat, + "bolt": $fa-var-bolt, + "zap": $fa-var-zap, + "glass-water": $fa-var-glass-water, + "oil-well": $fa-var-oil-well, + "vault": $fa-var-vault, + "mars": $fa-var-mars, + "toilet": $fa-var-toilet, + "plane-circle-xmark": $fa-var-plane-circle-xmark, + "yen-sign": $fa-var-yen-sign, + "cny": $fa-var-cny, + "jpy": $fa-var-jpy, + "rmb": $fa-var-rmb, + "yen": $fa-var-yen, + "ruble-sign": $fa-var-ruble-sign, + "rouble": $fa-var-rouble, + "rub": $fa-var-rub, + "ruble": $fa-var-ruble, + "sun": $fa-var-sun, + "guitar": $fa-var-guitar, + "face-laugh-wink": $fa-var-face-laugh-wink, + "laugh-wink": $fa-var-laugh-wink, + "horse-head": $fa-var-horse-head, + "bore-hole": $fa-var-bore-hole, + "industry": $fa-var-industry, + "circle-down": $fa-var-circle-down, + "arrow-alt-circle-down": $fa-var-arrow-alt-circle-down, + "arrows-turn-to-dots": $fa-var-arrows-turn-to-dots, + "florin-sign": $fa-var-florin-sign, + "arrow-down-short-wide": $fa-var-arrow-down-short-wide, + "sort-amount-desc": $fa-var-sort-amount-desc, + "sort-amount-down-alt": $fa-var-sort-amount-down-alt, + "less-than": $fa-var-less-than, + "angle-down": $fa-var-angle-down, + "car-tunnel": $fa-var-car-tunnel, + "head-side-cough": $fa-var-head-side-cough, + "grip-lines": $fa-var-grip-lines, + "thumbs-down": $fa-var-thumbs-down, + "user-lock": $fa-var-user-lock, + "arrow-right-long": $fa-var-arrow-right-long, + "long-arrow-right": $fa-var-long-arrow-right, + "anchor-circle-xmark": $fa-var-anchor-circle-xmark, + "ellipsis": $fa-var-ellipsis, + "ellipsis-h": $fa-var-ellipsis-h, + "chess-pawn": $fa-var-chess-pawn, + "kit-medical": $fa-var-kit-medical, + "first-aid": $fa-var-first-aid, + "person-through-window": $fa-var-person-through-window, + "toolbox": $fa-var-toolbox, + "hands-holding-circle": $fa-var-hands-holding-circle, + "bug": $fa-var-bug, + "credit-card": $fa-var-credit-card, + "credit-card-alt": $fa-var-credit-card-alt, + "car": $fa-var-car, + "automobile": $fa-var-automobile, + "hand-holding-hand": $fa-var-hand-holding-hand, + "book-open-reader": $fa-var-book-open-reader, + "book-reader": $fa-var-book-reader, + "mountain-sun": $fa-var-mountain-sun, + "arrows-left-right-to-line": $fa-var-arrows-left-right-to-line, + "dice-d20": $fa-var-dice-d20, + "truck-droplet": $fa-var-truck-droplet, + "file-circle-xmark": $fa-var-file-circle-xmark, + "temperature-arrow-up": $fa-var-temperature-arrow-up, + "temperature-up": $fa-var-temperature-up, + "medal": $fa-var-medal, + "bed": $fa-var-bed, + "square-h": $fa-var-square-h, + "h-square": $fa-var-h-square, + "podcast": $fa-var-podcast, + "temperature-full": $fa-var-temperature-full, + "temperature-4": $fa-var-temperature-4, + "thermometer-4": $fa-var-thermometer-4, + "thermometer-full": $fa-var-thermometer-full, + "bell": $fa-var-bell, + "superscript": $fa-var-superscript, + "plug-circle-xmark": $fa-var-plug-circle-xmark, + "star-of-life": $fa-var-star-of-life, + "phone-slash": $fa-var-phone-slash, + "paint-roller": $fa-var-paint-roller, + "handshake-angle": $fa-var-handshake-angle, + "hands-helping": $fa-var-hands-helping, + "location-dot": $fa-var-location-dot, + "map-marker-alt": $fa-var-map-marker-alt, + "file": $fa-var-file, + "greater-than": $fa-var-greater-than, + "person-swimming": $fa-var-person-swimming, + "swimmer": $fa-var-swimmer, + "arrow-down": $fa-var-arrow-down, + "droplet": $fa-var-droplet, + "tint": $fa-var-tint, + "eraser": $fa-var-eraser, + "earth-americas": $fa-var-earth-americas, + "earth": $fa-var-earth, + "earth-america": $fa-var-earth-america, + "globe-americas": $fa-var-globe-americas, + "person-burst": $fa-var-person-burst, + "dove": $fa-var-dove, + "battery-empty": $fa-var-battery-empty, + "battery-0": $fa-var-battery-0, + "socks": $fa-var-socks, + "inbox": $fa-var-inbox, + "section": $fa-var-section, + "gauge-high": $fa-var-gauge-high, + "tachometer-alt": $fa-var-tachometer-alt, + "tachometer-alt-fast": $fa-var-tachometer-alt-fast, + "envelope-open-text": $fa-var-envelope-open-text, + "hospital": $fa-var-hospital, + "hospital-alt": $fa-var-hospital-alt, + "hospital-wide": $fa-var-hospital-wide, + "wine-bottle": $fa-var-wine-bottle, + "chess-rook": $fa-var-chess-rook, + "bars-staggered": $fa-var-bars-staggered, + "reorder": $fa-var-reorder, + "stream": $fa-var-stream, + "dharmachakra": $fa-var-dharmachakra, + "hotdog": $fa-var-hotdog, + "person-walking-with-cane": $fa-var-person-walking-with-cane, + "blind": $fa-var-blind, + "drum": $fa-var-drum, + "ice-cream": $fa-var-ice-cream, + "heart-circle-bolt": $fa-var-heart-circle-bolt, + "fax": $fa-var-fax, + "paragraph": $fa-var-paragraph, + "check-to-slot": $fa-var-check-to-slot, + "vote-yea": $fa-var-vote-yea, + "star-half": $fa-var-star-half, + "boxes-stacked": $fa-var-boxes-stacked, + "boxes": $fa-var-boxes, + "boxes-alt": $fa-var-boxes-alt, + "link": $fa-var-link, + "chain": $fa-var-chain, + "ear-listen": $fa-var-ear-listen, + "assistive-listening-systems": $fa-var-assistive-listening-systems, + "tree-city": $fa-var-tree-city, + "play": $fa-var-play, + "font": $fa-var-font, + "table-cells-row-lock": $fa-var-table-cells-row-lock, + "rupiah-sign": $fa-var-rupiah-sign, + "magnifying-glass": $fa-var-magnifying-glass, + "search": $fa-var-search, + "table-tennis-paddle-ball": $fa-var-table-tennis-paddle-ball, + "ping-pong-paddle-ball": $fa-var-ping-pong-paddle-ball, + "table-tennis": $fa-var-table-tennis, + "person-dots-from-line": $fa-var-person-dots-from-line, + "diagnoses": $fa-var-diagnoses, + "trash-can-arrow-up": $fa-var-trash-can-arrow-up, + "trash-restore-alt": $fa-var-trash-restore-alt, + "naira-sign": $fa-var-naira-sign, + "cart-arrow-down": $fa-var-cart-arrow-down, + "walkie-talkie": $fa-var-walkie-talkie, + "file-pen": $fa-var-file-pen, + "file-edit": $fa-var-file-edit, + "receipt": $fa-var-receipt, + "square-pen": $fa-var-square-pen, + "pen-square": $fa-var-pen-square, + "pencil-square": $fa-var-pencil-square, + "suitcase-rolling": $fa-var-suitcase-rolling, + "person-circle-exclamation": $fa-var-person-circle-exclamation, + "chevron-down": $fa-var-chevron-down, + "battery-full": $fa-var-battery-full, + "battery": $fa-var-battery, + "battery-5": $fa-var-battery-5, + "skull-crossbones": $fa-var-skull-crossbones, + "code-compare": $fa-var-code-compare, + "list-ul": $fa-var-list-ul, + "list-dots": $fa-var-list-dots, + "school-lock": $fa-var-school-lock, + "tower-cell": $fa-var-tower-cell, + "down-long": $fa-var-down-long, + "long-arrow-alt-down": $fa-var-long-arrow-alt-down, + "ranking-star": $fa-var-ranking-star, + "chess-king": $fa-var-chess-king, + "person-harassing": $fa-var-person-harassing, + "brazilian-real-sign": $fa-var-brazilian-real-sign, + "landmark-dome": $fa-var-landmark-dome, + "landmark-alt": $fa-var-landmark-alt, + "arrow-up": $fa-var-arrow-up, + "tv": $fa-var-tv, + "television": $fa-var-television, + "tv-alt": $fa-var-tv-alt, + "shrimp": $fa-var-shrimp, + "list-check": $fa-var-list-check, + "tasks": $fa-var-tasks, + "jug-detergent": $fa-var-jug-detergent, + "circle-user": $fa-var-circle-user, + "user-circle": $fa-var-user-circle, + "user-shield": $fa-var-user-shield, + "wind": $fa-var-wind, + "car-burst": $fa-var-car-burst, + "car-crash": $fa-var-car-crash, + "y": $fa-var-y, + "person-snowboarding": $fa-var-person-snowboarding, + "snowboarding": $fa-var-snowboarding, + "truck-fast": $fa-var-truck-fast, + "shipping-fast": $fa-var-shipping-fast, + "fish": $fa-var-fish, + "user-graduate": $fa-var-user-graduate, + "circle-half-stroke": $fa-var-circle-half-stroke, + "adjust": $fa-var-adjust, + "clapperboard": $fa-var-clapperboard, + "circle-radiation": $fa-var-circle-radiation, + "radiation-alt": $fa-var-radiation-alt, + "baseball": $fa-var-baseball, + "baseball-ball": $fa-var-baseball-ball, + "jet-fighter-up": $fa-var-jet-fighter-up, + "diagram-project": $fa-var-diagram-project, + "project-diagram": $fa-var-project-diagram, + "copy": $fa-var-copy, + "volume-xmark": $fa-var-volume-xmark, + "volume-mute": $fa-var-volume-mute, + "volume-times": $fa-var-volume-times, + "hand-sparkles": $fa-var-hand-sparkles, + "grip": $fa-var-grip, + "grip-horizontal": $fa-var-grip-horizontal, + "share-from-square": $fa-var-share-from-square, + "share-square": $fa-var-share-square, + "child-combatant": $fa-var-child-combatant, + "child-rifle": $fa-var-child-rifle, + "gun": $fa-var-gun, + "square-phone": $fa-var-square-phone, + "phone-square": $fa-var-phone-square, + "plus": $fa-var-plus, + "add": $fa-var-add, + "expand": $fa-var-expand, + "computer": $fa-var-computer, + "xmark": $fa-var-xmark, + "close": $fa-var-close, + "multiply": $fa-var-multiply, + "remove": $fa-var-remove, + "times": $fa-var-times, + "arrows-up-down-left-right": $fa-var-arrows-up-down-left-right, + "arrows": $fa-var-arrows, + "chalkboard-user": $fa-var-chalkboard-user, + "chalkboard-teacher": $fa-var-chalkboard-teacher, + "peso-sign": $fa-var-peso-sign, + "building-shield": $fa-var-building-shield, + "baby": $fa-var-baby, + "users-line": $fa-var-users-line, + "quote-left": $fa-var-quote-left, + "quote-left-alt": $fa-var-quote-left-alt, + "tractor": $fa-var-tractor, + "trash-arrow-up": $fa-var-trash-arrow-up, + "trash-restore": $fa-var-trash-restore, + "arrow-down-up-lock": $fa-var-arrow-down-up-lock, + "lines-leaning": $fa-var-lines-leaning, + "ruler-combined": $fa-var-ruler-combined, + "copyright": $fa-var-copyright, + "equals": $fa-var-equals, + "blender": $fa-var-blender, + "teeth": $fa-var-teeth, + "shekel-sign": $fa-var-shekel-sign, + "ils": $fa-var-ils, + "shekel": $fa-var-shekel, + "sheqel": $fa-var-sheqel, + "sheqel-sign": $fa-var-sheqel-sign, + "map": $fa-var-map, + "rocket": $fa-var-rocket, + "photo-film": $fa-var-photo-film, + "photo-video": $fa-var-photo-video, + "folder-minus": $fa-var-folder-minus, + "hexagon-nodes-bolt": $fa-var-hexagon-nodes-bolt, + "store": $fa-var-store, + "arrow-trend-up": $fa-var-arrow-trend-up, + "plug-circle-minus": $fa-var-plug-circle-minus, + "sign-hanging": $fa-var-sign-hanging, + "sign": $fa-var-sign, + "bezier-curve": $fa-var-bezier-curve, + "bell-slash": $fa-var-bell-slash, + "tablet": $fa-var-tablet, + "tablet-android": $fa-var-tablet-android, + "school-flag": $fa-var-school-flag, + "fill": $fa-var-fill, + "angle-up": $fa-var-angle-up, + "drumstick-bite": $fa-var-drumstick-bite, + "holly-berry": $fa-var-holly-berry, + "chevron-left": $fa-var-chevron-left, + "bacteria": $fa-var-bacteria, + "hand-lizard": $fa-var-hand-lizard, + "notdef": $fa-var-notdef, + "disease": $fa-var-disease, + "briefcase-medical": $fa-var-briefcase-medical, + "genderless": $fa-var-genderless, + "chevron-right": $fa-var-chevron-right, + "retweet": $fa-var-retweet, + "car-rear": $fa-var-car-rear, + "car-alt": $fa-var-car-alt, + "pump-soap": $fa-var-pump-soap, + "video-slash": $fa-var-video-slash, + "battery-quarter": $fa-var-battery-quarter, + "battery-2": $fa-var-battery-2, + "radio": $fa-var-radio, + "baby-carriage": $fa-var-baby-carriage, + "carriage-baby": $fa-var-carriage-baby, + "traffic-light": $fa-var-traffic-light, + "thermometer": $fa-var-thermometer, + "vr-cardboard": $fa-var-vr-cardboard, + "hand-middle-finger": $fa-var-hand-middle-finger, + "percent": $fa-var-percent, + "percentage": $fa-var-percentage, + "truck-moving": $fa-var-truck-moving, + "glass-water-droplet": $fa-var-glass-water-droplet, + "display": $fa-var-display, + "face-smile": $fa-var-face-smile, + "smile": $fa-var-smile, + "thumbtack": $fa-var-thumbtack, + "thumb-tack": $fa-var-thumb-tack, + "trophy": $fa-var-trophy, + "person-praying": $fa-var-person-praying, + "pray": $fa-var-pray, + "hammer": $fa-var-hammer, + "hand-peace": $fa-var-hand-peace, + "rotate": $fa-var-rotate, + "sync-alt": $fa-var-sync-alt, + "spinner": $fa-var-spinner, + "robot": $fa-var-robot, + "peace": $fa-var-peace, + "gears": $fa-var-gears, + "cogs": $fa-var-cogs, + "warehouse": $fa-var-warehouse, + "arrow-up-right-dots": $fa-var-arrow-up-right-dots, + "splotch": $fa-var-splotch, + "face-grin-hearts": $fa-var-face-grin-hearts, + "grin-hearts": $fa-var-grin-hearts, + "dice-four": $fa-var-dice-four, + "sim-card": $fa-var-sim-card, + "transgender": $fa-var-transgender, + "transgender-alt": $fa-var-transgender-alt, + "mercury": $fa-var-mercury, + "arrow-turn-down": $fa-var-arrow-turn-down, + "level-down": $fa-var-level-down, + "person-falling-burst": $fa-var-person-falling-burst, + "award": $fa-var-award, + "ticket-simple": $fa-var-ticket-simple, + "ticket-alt": $fa-var-ticket-alt, + "building": $fa-var-building, + "angles-left": $fa-var-angles-left, + "angle-double-left": $fa-var-angle-double-left, + "qrcode": $fa-var-qrcode, + "clock-rotate-left": $fa-var-clock-rotate-left, + "history": $fa-var-history, + "face-grin-beam-sweat": $fa-var-face-grin-beam-sweat, + "grin-beam-sweat": $fa-var-grin-beam-sweat, + "file-export": $fa-var-file-export, + "arrow-right-from-file": $fa-var-arrow-right-from-file, + "shield": $fa-var-shield, + "shield-blank": $fa-var-shield-blank, + "arrow-up-short-wide": $fa-var-arrow-up-short-wide, + "sort-amount-up-alt": $fa-var-sort-amount-up-alt, + "comment-nodes": $fa-var-comment-nodes, + "house-medical": $fa-var-house-medical, + "golf-ball-tee": $fa-var-golf-ball-tee, + "golf-ball": $fa-var-golf-ball, + "circle-chevron-left": $fa-var-circle-chevron-left, + "chevron-circle-left": $fa-var-chevron-circle-left, + "house-chimney-window": $fa-var-house-chimney-window, + "pen-nib": $fa-var-pen-nib, + "tent-arrow-turn-left": $fa-var-tent-arrow-turn-left, + "tents": $fa-var-tents, + "wand-magic": $fa-var-wand-magic, + "magic": $fa-var-magic, + "dog": $fa-var-dog, + "carrot": $fa-var-carrot, + "moon": $fa-var-moon, + "wine-glass-empty": $fa-var-wine-glass-empty, + "wine-glass-alt": $fa-var-wine-glass-alt, + "cheese": $fa-var-cheese, + "yin-yang": $fa-var-yin-yang, + "music": $fa-var-music, + "code-commit": $fa-var-code-commit, + "temperature-low": $fa-var-temperature-low, + "person-biking": $fa-var-person-biking, + "biking": $fa-var-biking, + "broom": $fa-var-broom, + "shield-heart": $fa-var-shield-heart, + "gopuram": $fa-var-gopuram, + "earth-oceania": $fa-var-earth-oceania, + "globe-oceania": $fa-var-globe-oceania, + "square-xmark": $fa-var-square-xmark, + "times-square": $fa-var-times-square, + "xmark-square": $fa-var-xmark-square, + "hashtag": $fa-var-hashtag, + "up-right-and-down-left-from-center": $fa-var-up-right-and-down-left-from-center, + "expand-alt": $fa-var-expand-alt, + "oil-can": $fa-var-oil-can, + "t": $fa-var-t, + "hippo": $fa-var-hippo, + "chart-column": $fa-var-chart-column, + "infinity": $fa-var-infinity, + "vial-circle-check": $fa-var-vial-circle-check, + "person-arrow-down-to-line": $fa-var-person-arrow-down-to-line, + "voicemail": $fa-var-voicemail, + "fan": $fa-var-fan, + "person-walking-luggage": $fa-var-person-walking-luggage, + "up-down": $fa-var-up-down, + "arrows-alt-v": $fa-var-arrows-alt-v, + "cloud-moon-rain": $fa-var-cloud-moon-rain, + "calendar": $fa-var-calendar, + "trailer": $fa-var-trailer, + "bahai": $fa-var-bahai, + "haykal": $fa-var-haykal, + "sd-card": $fa-var-sd-card, + "dragon": $fa-var-dragon, + "shoe-prints": $fa-var-shoe-prints, + "circle-plus": $fa-var-circle-plus, + "plus-circle": $fa-var-plus-circle, + "face-grin-tongue-wink": $fa-var-face-grin-tongue-wink, + "grin-tongue-wink": $fa-var-grin-tongue-wink, + "hand-holding": $fa-var-hand-holding, + "plug-circle-exclamation": $fa-var-plug-circle-exclamation, + "link-slash": $fa-var-link-slash, + "chain-broken": $fa-var-chain-broken, + "chain-slash": $fa-var-chain-slash, + "unlink": $fa-var-unlink, + "clone": $fa-var-clone, + "person-walking-arrow-loop-left": $fa-var-person-walking-arrow-loop-left, + "arrow-up-z-a": $fa-var-arrow-up-z-a, + "sort-alpha-up-alt": $fa-var-sort-alpha-up-alt, + "fire-flame-curved": $fa-var-fire-flame-curved, + "fire-alt": $fa-var-fire-alt, + "tornado": $fa-var-tornado, + "file-circle-plus": $fa-var-file-circle-plus, + "book-quran": $fa-var-book-quran, + "quran": $fa-var-quran, + "anchor": $fa-var-anchor, + "border-all": $fa-var-border-all, + "face-angry": $fa-var-face-angry, + "angry": $fa-var-angry, + "cookie-bite": $fa-var-cookie-bite, + "arrow-trend-down": $fa-var-arrow-trend-down, + "rss": $fa-var-rss, + "feed": $fa-var-feed, + "draw-polygon": $fa-var-draw-polygon, + "scale-balanced": $fa-var-scale-balanced, + "balance-scale": $fa-var-balance-scale, + "gauge-simple-high": $fa-var-gauge-simple-high, + "tachometer": $fa-var-tachometer, + "tachometer-fast": $fa-var-tachometer-fast, + "shower": $fa-var-shower, + "desktop": $fa-var-desktop, + "desktop-alt": $fa-var-desktop-alt, + "m": $fa-var-m, + "table-list": $fa-var-table-list, + "th-list": $fa-var-th-list, + "comment-sms": $fa-var-comment-sms, + "sms": $fa-var-sms, + "book": $fa-var-book, + "user-plus": $fa-var-user-plus, + "check": $fa-var-check, + "battery-three-quarters": $fa-var-battery-three-quarters, + "battery-4": $fa-var-battery-4, + "house-circle-check": $fa-var-house-circle-check, + "angle-left": $fa-var-angle-left, + "diagram-successor": $fa-var-diagram-successor, + "truck-arrow-right": $fa-var-truck-arrow-right, + "arrows-split-up-and-left": $fa-var-arrows-split-up-and-left, + "hand-fist": $fa-var-hand-fist, + "fist-raised": $fa-var-fist-raised, + "cloud-moon": $fa-var-cloud-moon, + "briefcase": $fa-var-briefcase, + "person-falling": $fa-var-person-falling, + "image-portrait": $fa-var-image-portrait, + "portrait": $fa-var-portrait, + "user-tag": $fa-var-user-tag, + "rug": $fa-var-rug, + "earth-europe": $fa-var-earth-europe, + "globe-europe": $fa-var-globe-europe, + "cart-flatbed-suitcase": $fa-var-cart-flatbed-suitcase, + "luggage-cart": $fa-var-luggage-cart, + "rectangle-xmark": $fa-var-rectangle-xmark, + "rectangle-times": $fa-var-rectangle-times, + "times-rectangle": $fa-var-times-rectangle, + "window-close": $fa-var-window-close, + "baht-sign": $fa-var-baht-sign, + "book-open": $fa-var-book-open, + "book-journal-whills": $fa-var-book-journal-whills, + "journal-whills": $fa-var-journal-whills, + "handcuffs": $fa-var-handcuffs, + "triangle-exclamation": $fa-var-triangle-exclamation, + "exclamation-triangle": $fa-var-exclamation-triangle, + "warning": $fa-var-warning, + "database": $fa-var-database, + "share": $fa-var-share, + "mail-forward": $fa-var-mail-forward, + "bottle-droplet": $fa-var-bottle-droplet, + "mask-face": $fa-var-mask-face, + "hill-rockslide": $fa-var-hill-rockslide, + "right-left": $fa-var-right-left, + "exchange-alt": $fa-var-exchange-alt, + "paper-plane": $fa-var-paper-plane, + "road-circle-exclamation": $fa-var-road-circle-exclamation, + "dungeon": $fa-var-dungeon, + "align-right": $fa-var-align-right, + "money-bill-1-wave": $fa-var-money-bill-1-wave, + "money-bill-wave-alt": $fa-var-money-bill-wave-alt, + "life-ring": $fa-var-life-ring, + "hands": $fa-var-hands, + "sign-language": $fa-var-sign-language, + "signing": $fa-var-signing, + "calendar-day": $fa-var-calendar-day, + "water-ladder": $fa-var-water-ladder, + "ladder-water": $fa-var-ladder-water, + "swimming-pool": $fa-var-swimming-pool, + "arrows-up-down": $fa-var-arrows-up-down, + "arrows-v": $fa-var-arrows-v, + "face-grimace": $fa-var-face-grimace, + "grimace": $fa-var-grimace, + "wheelchair-move": $fa-var-wheelchair-move, + "wheelchair-alt": $fa-var-wheelchair-alt, + "turn-down": $fa-var-turn-down, + "level-down-alt": $fa-var-level-down-alt, + "person-walking-arrow-right": $fa-var-person-walking-arrow-right, + "square-envelope": $fa-var-square-envelope, + "envelope-square": $fa-var-envelope-square, + "dice": $fa-var-dice, + "bowling-ball": $fa-var-bowling-ball, + "brain": $fa-var-brain, + "bandage": $fa-var-bandage, + "band-aid": $fa-var-band-aid, + "calendar-minus": $fa-var-calendar-minus, + "circle-xmark": $fa-var-circle-xmark, + "times-circle": $fa-var-times-circle, + "xmark-circle": $fa-var-xmark-circle, + "gifts": $fa-var-gifts, + "hotel": $fa-var-hotel, + "earth-asia": $fa-var-earth-asia, + "globe-asia": $fa-var-globe-asia, + "id-card-clip": $fa-var-id-card-clip, + "id-card-alt": $fa-var-id-card-alt, + "magnifying-glass-plus": $fa-var-magnifying-glass-plus, + "search-plus": $fa-var-search-plus, + "thumbs-up": $fa-var-thumbs-up, + "user-clock": $fa-var-user-clock, + "hand-dots": $fa-var-hand-dots, + "allergies": $fa-var-allergies, + "file-invoice": $fa-var-file-invoice, + "window-minimize": $fa-var-window-minimize, + "mug-saucer": $fa-var-mug-saucer, + "coffee": $fa-var-coffee, + "brush": $fa-var-brush, + "file-half-dashed": $fa-var-file-half-dashed, + "mask": $fa-var-mask, + "magnifying-glass-minus": $fa-var-magnifying-glass-minus, + "search-minus": $fa-var-search-minus, + "ruler-vertical": $fa-var-ruler-vertical, + "user-large": $fa-var-user-large, + "user-alt": $fa-var-user-alt, + "train-tram": $fa-var-train-tram, + "user-nurse": $fa-var-user-nurse, + "syringe": $fa-var-syringe, + "cloud-sun": $fa-var-cloud-sun, + "stopwatch-20": $fa-var-stopwatch-20, + "square-full": $fa-var-square-full, + "magnet": $fa-var-magnet, + "jar": $fa-var-jar, + "note-sticky": $fa-var-note-sticky, + "sticky-note": $fa-var-sticky-note, + "bug-slash": $fa-var-bug-slash, + "arrow-up-from-water-pump": $fa-var-arrow-up-from-water-pump, + "bone": $fa-var-bone, + "table-cells-row-unlock": $fa-var-table-cells-row-unlock, + "user-injured": $fa-var-user-injured, + "face-sad-tear": $fa-var-face-sad-tear, + "sad-tear": $fa-var-sad-tear, + "plane": $fa-var-plane, + "tent-arrows-down": $fa-var-tent-arrows-down, + "exclamation": $fa-var-exclamation, + "arrows-spin": $fa-var-arrows-spin, + "print": $fa-var-print, + "turkish-lira-sign": $fa-var-turkish-lira-sign, + "try": $fa-var-try, + "turkish-lira": $fa-var-turkish-lira, + "dollar-sign": $fa-var-dollar-sign, + "dollar": $fa-var-dollar, + "usd": $fa-var-usd, + "x": $fa-var-x, + "magnifying-glass-dollar": $fa-var-magnifying-glass-dollar, + "search-dollar": $fa-var-search-dollar, + "users-gear": $fa-var-users-gear, + "users-cog": $fa-var-users-cog, + "person-military-pointing": $fa-var-person-military-pointing, + "building-columns": $fa-var-building-columns, + "bank": $fa-var-bank, + "institution": $fa-var-institution, + "museum": $fa-var-museum, + "university": $fa-var-university, + "umbrella": $fa-var-umbrella, + "trowel": $fa-var-trowel, + "d": $fa-var-d, + "stapler": $fa-var-stapler, + "masks-theater": $fa-var-masks-theater, + "theater-masks": $fa-var-theater-masks, + "kip-sign": $fa-var-kip-sign, + "hand-point-left": $fa-var-hand-point-left, + "handshake-simple": $fa-var-handshake-simple, + "handshake-alt": $fa-var-handshake-alt, + "jet-fighter": $fa-var-jet-fighter, + "fighter-jet": $fa-var-fighter-jet, + "square-share-nodes": $fa-var-square-share-nodes, + "share-alt-square": $fa-var-share-alt-square, + "barcode": $fa-var-barcode, + "plus-minus": $fa-var-plus-minus, + "video": $fa-var-video, + "video-camera": $fa-var-video-camera, + "graduation-cap": $fa-var-graduation-cap, + "mortar-board": $fa-var-mortar-board, + "hand-holding-medical": $fa-var-hand-holding-medical, + "person-circle-check": $fa-var-person-circle-check, + "turn-up": $fa-var-turn-up, + "level-up-alt": $fa-var-level-up-alt, +); + +$fa-brand-icons: ( + "monero": $fa-var-monero, + "hooli": $fa-var-hooli, + "yelp": $fa-var-yelp, + "cc-visa": $fa-var-cc-visa, + "lastfm": $fa-var-lastfm, + "shopware": $fa-var-shopware, + "creative-commons-nc": $fa-var-creative-commons-nc, + "aws": $fa-var-aws, + "redhat": $fa-var-redhat, + "yoast": $fa-var-yoast, + "cloudflare": $fa-var-cloudflare, + "ups": $fa-var-ups, + "pixiv": $fa-var-pixiv, + "wpexplorer": $fa-var-wpexplorer, + "dyalog": $fa-var-dyalog, + "bity": $fa-var-bity, + "stackpath": $fa-var-stackpath, + "buysellads": $fa-var-buysellads, + "first-order": $fa-var-first-order, + "modx": $fa-var-modx, + "guilded": $fa-var-guilded, + "vnv": $fa-var-vnv, + "square-js": $fa-var-square-js, + "js-square": $fa-var-js-square, + "microsoft": $fa-var-microsoft, + "qq": $fa-var-qq, + "orcid": $fa-var-orcid, + "java": $fa-var-java, + "invision": $fa-var-invision, + "creative-commons-pd-alt": $fa-var-creative-commons-pd-alt, + "centercode": $fa-var-centercode, + "glide-g": $fa-var-glide-g, + "drupal": $fa-var-drupal, + "jxl": $fa-var-jxl, + "dart-lang": $fa-var-dart-lang, + "hire-a-helper": $fa-var-hire-a-helper, + "creative-commons-by": $fa-var-creative-commons-by, + "unity": $fa-var-unity, + "whmcs": $fa-var-whmcs, + "rocketchat": $fa-var-rocketchat, + "vk": $fa-var-vk, + "untappd": $fa-var-untappd, + "mailchimp": $fa-var-mailchimp, + "css3-alt": $fa-var-css3-alt, + "square-reddit": $fa-var-square-reddit, + "reddit-square": $fa-var-reddit-square, + "vimeo-v": $fa-var-vimeo-v, + "contao": $fa-var-contao, + "square-font-awesome": $fa-var-square-font-awesome, + "deskpro": $fa-var-deskpro, + "brave": $fa-var-brave, + "sistrix": $fa-var-sistrix, + "square-instagram": $fa-var-square-instagram, + "instagram-square": $fa-var-instagram-square, + "battle-net": $fa-var-battle-net, + "the-red-yeti": $fa-var-the-red-yeti, + "square-hacker-news": $fa-var-square-hacker-news, + "hacker-news-square": $fa-var-hacker-news-square, + "edge": $fa-var-edge, + "threads": $fa-var-threads, + "napster": $fa-var-napster, + "square-snapchat": $fa-var-square-snapchat, + "snapchat-square": $fa-var-snapchat-square, + "google-plus-g": $fa-var-google-plus-g, + "artstation": $fa-var-artstation, + "markdown": $fa-var-markdown, + "sourcetree": $fa-var-sourcetree, + "google-plus": $fa-var-google-plus, + "diaspora": $fa-var-diaspora, + "foursquare": $fa-var-foursquare, + "stack-overflow": $fa-var-stack-overflow, + "github-alt": $fa-var-github-alt, + "phoenix-squadron": $fa-var-phoenix-squadron, + "pagelines": $fa-var-pagelines, + "algolia": $fa-var-algolia, + "red-river": $fa-var-red-river, + "creative-commons-sa": $fa-var-creative-commons-sa, + "safari": $fa-var-safari, + "google": $fa-var-google, + "square-font-awesome-stroke": $fa-var-square-font-awesome-stroke, + "font-awesome-alt": $fa-var-font-awesome-alt, + "atlassian": $fa-var-atlassian, + "linkedin-in": $fa-var-linkedin-in, + "digital-ocean": $fa-var-digital-ocean, + "nimblr": $fa-var-nimblr, + "chromecast": $fa-var-chromecast, + "evernote": $fa-var-evernote, + "hacker-news": $fa-var-hacker-news, + "creative-commons-sampling": $fa-var-creative-commons-sampling, + "adversal": $fa-var-adversal, + "creative-commons": $fa-var-creative-commons, + "watchman-monitoring": $fa-var-watchman-monitoring, + "fonticons": $fa-var-fonticons, + "weixin": $fa-var-weixin, + "shirtsinbulk": $fa-var-shirtsinbulk, + "codepen": $fa-var-codepen, + "git-alt": $fa-var-git-alt, + "lyft": $fa-var-lyft, + "rev": $fa-var-rev, + "windows": $fa-var-windows, + "wizards-of-the-coast": $fa-var-wizards-of-the-coast, + "square-viadeo": $fa-var-square-viadeo, + "viadeo-square": $fa-var-viadeo-square, + "meetup": $fa-var-meetup, + "centos": $fa-var-centos, + "adn": $fa-var-adn, + "cloudsmith": $fa-var-cloudsmith, + "opensuse": $fa-var-opensuse, + "pied-piper-alt": $fa-var-pied-piper-alt, + "square-dribbble": $fa-var-square-dribbble, + "dribbble-square": $fa-var-dribbble-square, + "codiepie": $fa-var-codiepie, + "node": $fa-var-node, + "mix": $fa-var-mix, + "steam": $fa-var-steam, + "cc-apple-pay": $fa-var-cc-apple-pay, + "scribd": $fa-var-scribd, + "debian": $fa-var-debian, + "openid": $fa-var-openid, + "instalod": $fa-var-instalod, + "files-pinwheel": $fa-var-files-pinwheel, + "expeditedssl": $fa-var-expeditedssl, + "sellcast": $fa-var-sellcast, + "square-twitter": $fa-var-square-twitter, + "twitter-square": $fa-var-twitter-square, + "r-project": $fa-var-r-project, + "delicious": $fa-var-delicious, + "freebsd": $fa-var-freebsd, + "vuejs": $fa-var-vuejs, + "accusoft": $fa-var-accusoft, + "ioxhost": $fa-var-ioxhost, + "fonticons-fi": $fa-var-fonticons-fi, + "app-store": $fa-var-app-store, + "cc-mastercard": $fa-var-cc-mastercard, + "itunes-note": $fa-var-itunes-note, + "golang": $fa-var-golang, + "kickstarter": $fa-var-kickstarter, + "square-kickstarter": $fa-var-square-kickstarter, + "grav": $fa-var-grav, + "weibo": $fa-var-weibo, + "uncharted": $fa-var-uncharted, + "firstdraft": $fa-var-firstdraft, + "square-youtube": $fa-var-square-youtube, + "youtube-square": $fa-var-youtube-square, + "wikipedia-w": $fa-var-wikipedia-w, + "wpressr": $fa-var-wpressr, + "rendact": $fa-var-rendact, + "angellist": $fa-var-angellist, + "galactic-republic": $fa-var-galactic-republic, + "nfc-directional": $fa-var-nfc-directional, + "skype": $fa-var-skype, + "joget": $fa-var-joget, + "fedora": $fa-var-fedora, + "stripe-s": $fa-var-stripe-s, + "meta": $fa-var-meta, + "laravel": $fa-var-laravel, + "hotjar": $fa-var-hotjar, + "bluetooth-b": $fa-var-bluetooth-b, + "square-letterboxd": $fa-var-square-letterboxd, + "sticker-mule": $fa-var-sticker-mule, + "creative-commons-zero": $fa-var-creative-commons-zero, + "hips": $fa-var-hips, + "css": $fa-var-css, + "behance": $fa-var-behance, + "reddit": $fa-var-reddit, + "discord": $fa-var-discord, + "chrome": $fa-var-chrome, + "app-store-ios": $fa-var-app-store-ios, + "cc-discover": $fa-var-cc-discover, + "wpbeginner": $fa-var-wpbeginner, + "confluence": $fa-var-confluence, + "shoelace": $fa-var-shoelace, + "mdb": $fa-var-mdb, + "dochub": $fa-var-dochub, + "accessible-icon": $fa-var-accessible-icon, + "ebay": $fa-var-ebay, + "amazon": $fa-var-amazon, + "unsplash": $fa-var-unsplash, + "yarn": $fa-var-yarn, + "square-steam": $fa-var-square-steam, + "steam-square": $fa-var-steam-square, + "500px": $fa-var-500px, + "square-vimeo": $fa-var-square-vimeo, + "vimeo-square": $fa-var-vimeo-square, + "asymmetrik": $fa-var-asymmetrik, + "font-awesome": $fa-var-font-awesome, + "font-awesome-flag": $fa-var-font-awesome-flag, + "font-awesome-logo-full": $fa-var-font-awesome-logo-full, + "gratipay": $fa-var-gratipay, + "apple": $fa-var-apple, + "hive": $fa-var-hive, + "gitkraken": $fa-var-gitkraken, + "keybase": $fa-var-keybase, + "apple-pay": $fa-var-apple-pay, + "padlet": $fa-var-padlet, + "amazon-pay": $fa-var-amazon-pay, + "square-github": $fa-var-square-github, + "github-square": $fa-var-github-square, + "stumbleupon": $fa-var-stumbleupon, + "fedex": $fa-var-fedex, + "phoenix-framework": $fa-var-phoenix-framework, + "shopify": $fa-var-shopify, + "neos": $fa-var-neos, + "square-threads": $fa-var-square-threads, + "hackerrank": $fa-var-hackerrank, + "researchgate": $fa-var-researchgate, + "swift": $fa-var-swift, + "angular": $fa-var-angular, + "speakap": $fa-var-speakap, + "angrycreative": $fa-var-angrycreative, + "y-combinator": $fa-var-y-combinator, + "empire": $fa-var-empire, + "envira": $fa-var-envira, + "google-scholar": $fa-var-google-scholar, + "square-gitlab": $fa-var-square-gitlab, + "gitlab-square": $fa-var-gitlab-square, + "studiovinari": $fa-var-studiovinari, + "pied-piper": $fa-var-pied-piper, + "wordpress": $fa-var-wordpress, + "product-hunt": $fa-var-product-hunt, + "firefox": $fa-var-firefox, + "linode": $fa-var-linode, + "goodreads": $fa-var-goodreads, + "square-odnoklassniki": $fa-var-square-odnoklassniki, + "odnoklassniki-square": $fa-var-odnoklassniki-square, + "jsfiddle": $fa-var-jsfiddle, + "sith": $fa-var-sith, + "themeisle": $fa-var-themeisle, + "page4": $fa-var-page4, + "hashnode": $fa-var-hashnode, + "react": $fa-var-react, + "cc-paypal": $fa-var-cc-paypal, + "squarespace": $fa-var-squarespace, + "cc-stripe": $fa-var-cc-stripe, + "creative-commons-share": $fa-var-creative-commons-share, + "bitcoin": $fa-var-bitcoin, + "keycdn": $fa-var-keycdn, + "opera": $fa-var-opera, + "itch-io": $fa-var-itch-io, + "umbraco": $fa-var-umbraco, + "galactic-senate": $fa-var-galactic-senate, + "ubuntu": $fa-var-ubuntu, + "draft2digital": $fa-var-draft2digital, + "stripe": $fa-var-stripe, + "houzz": $fa-var-houzz, + "gg": $fa-var-gg, + "dhl": $fa-var-dhl, + "square-pinterest": $fa-var-square-pinterest, + "pinterest-square": $fa-var-pinterest-square, + "xing": $fa-var-xing, + "blackberry": $fa-var-blackberry, + "creative-commons-pd": $fa-var-creative-commons-pd, + "playstation": $fa-var-playstation, + "quinscape": $fa-var-quinscape, + "less": $fa-var-less, + "blogger-b": $fa-var-blogger-b, + "opencart": $fa-var-opencart, + "vine": $fa-var-vine, + "signal-messenger": $fa-var-signal-messenger, + "paypal": $fa-var-paypal, + "gitlab": $fa-var-gitlab, + "typo3": $fa-var-typo3, + "reddit-alien": $fa-var-reddit-alien, + "yahoo": $fa-var-yahoo, + "dailymotion": $fa-var-dailymotion, + "affiliatetheme": $fa-var-affiliatetheme, + "pied-piper-pp": $fa-var-pied-piper-pp, + "bootstrap": $fa-var-bootstrap, + "odnoklassniki": $fa-var-odnoklassniki, + "nfc-symbol": $fa-var-nfc-symbol, + "mintbit": $fa-var-mintbit, + "ethereum": $fa-var-ethereum, + "speaker-deck": $fa-var-speaker-deck, + "creative-commons-nc-eu": $fa-var-creative-commons-nc-eu, + "patreon": $fa-var-patreon, + "avianex": $fa-var-avianex, + "ello": $fa-var-ello, + "gofore": $fa-var-gofore, + "bimobject": $fa-var-bimobject, + "brave-reverse": $fa-var-brave-reverse, + "facebook-f": $fa-var-facebook-f, + "square-google-plus": $fa-var-square-google-plus, + "google-plus-square": $fa-var-google-plus-square, + "web-awesome": $fa-var-web-awesome, + "mandalorian": $fa-var-mandalorian, + "first-order-alt": $fa-var-first-order-alt, + "osi": $fa-var-osi, + "google-wallet": $fa-var-google-wallet, + "d-and-d-beyond": $fa-var-d-and-d-beyond, + "periscope": $fa-var-periscope, + "fulcrum": $fa-var-fulcrum, + "cloudscale": $fa-var-cloudscale, + "forumbee": $fa-var-forumbee, + "mizuni": $fa-var-mizuni, + "schlix": $fa-var-schlix, + "square-xing": $fa-var-square-xing, + "xing-square": $fa-var-xing-square, + "bandcamp": $fa-var-bandcamp, + "wpforms": $fa-var-wpforms, + "cloudversify": $fa-var-cloudversify, + "usps": $fa-var-usps, + "megaport": $fa-var-megaport, + "magento": $fa-var-magento, + "spotify": $fa-var-spotify, + "optin-monster": $fa-var-optin-monster, + "fly": $fa-var-fly, + "square-bluesky": $fa-var-square-bluesky, + "aviato": $fa-var-aviato, + "itunes": $fa-var-itunes, + "cuttlefish": $fa-var-cuttlefish, + "blogger": $fa-var-blogger, + "flickr": $fa-var-flickr, + "viber": $fa-var-viber, + "soundcloud": $fa-var-soundcloud, + "digg": $fa-var-digg, + "tencent-weibo": $fa-var-tencent-weibo, + "letterboxd": $fa-var-letterboxd, + "symfony": $fa-var-symfony, + "maxcdn": $fa-var-maxcdn, + "etsy": $fa-var-etsy, + "facebook-messenger": $fa-var-facebook-messenger, + "audible": $fa-var-audible, + "think-peaks": $fa-var-think-peaks, + "bilibili": $fa-var-bilibili, + "erlang": $fa-var-erlang, + "x-twitter": $fa-var-x-twitter, + "cotton-bureau": $fa-var-cotton-bureau, + "dashcube": $fa-var-dashcube, + "42-group": $fa-var-42-group, + "innosoft": $fa-var-innosoft, + "stack-exchange": $fa-var-stack-exchange, + "elementor": $fa-var-elementor, + "square-pied-piper": $fa-var-square-pied-piper, + "pied-piper-square": $fa-var-pied-piper-square, + "creative-commons-nd": $fa-var-creative-commons-nd, + "palfed": $fa-var-palfed, + "superpowers": $fa-var-superpowers, + "resolving": $fa-var-resolving, + "xbox": $fa-var-xbox, + "square-web-awesome-stroke": $fa-var-square-web-awesome-stroke, + "searchengin": $fa-var-searchengin, + "tiktok": $fa-var-tiktok, + "square-facebook": $fa-var-square-facebook, + "facebook-square": $fa-var-facebook-square, + "renren": $fa-var-renren, + "linux": $fa-var-linux, + "glide": $fa-var-glide, + "linkedin": $fa-var-linkedin, + "hubspot": $fa-var-hubspot, + "deploydog": $fa-var-deploydog, + "twitch": $fa-var-twitch, + "flutter": $fa-var-flutter, + "ravelry": $fa-var-ravelry, + "mixer": $fa-var-mixer, + "square-lastfm": $fa-var-square-lastfm, + "lastfm-square": $fa-var-lastfm-square, + "vimeo": $fa-var-vimeo, + "mendeley": $fa-var-mendeley, + "uniregistry": $fa-var-uniregistry, + "figma": $fa-var-figma, + "creative-commons-remix": $fa-var-creative-commons-remix, + "cc-amazon-pay": $fa-var-cc-amazon-pay, + "dropbox": $fa-var-dropbox, + "instagram": $fa-var-instagram, + "cmplid": $fa-var-cmplid, + "upwork": $fa-var-upwork, + "facebook": $fa-var-facebook, + "gripfire": $fa-var-gripfire, + "jedi-order": $fa-var-jedi-order, + "uikit": $fa-var-uikit, + "fort-awesome-alt": $fa-var-fort-awesome-alt, + "phabricator": $fa-var-phabricator, + "ussunnah": $fa-var-ussunnah, + "earlybirds": $fa-var-earlybirds, + "trade-federation": $fa-var-trade-federation, + "autoprefixer": $fa-var-autoprefixer, + "whatsapp": $fa-var-whatsapp, + "square-upwork": $fa-var-square-upwork, + "slideshare": $fa-var-slideshare, + "google-play": $fa-var-google-play, + "viadeo": $fa-var-viadeo, + "line": $fa-var-line, + "google-drive": $fa-var-google-drive, + "servicestack": $fa-var-servicestack, + "simplybuilt": $fa-var-simplybuilt, + "bitbucket": $fa-var-bitbucket, + "imdb": $fa-var-imdb, + "deezer": $fa-var-deezer, + "raspberry-pi": $fa-var-raspberry-pi, + "jira": $fa-var-jira, + "docker": $fa-var-docker, + "screenpal": $fa-var-screenpal, + "bluetooth": $fa-var-bluetooth, + "gitter": $fa-var-gitter, + "d-and-d": $fa-var-d-and-d, + "microblog": $fa-var-microblog, + "cc-diners-club": $fa-var-cc-diners-club, + "gg-circle": $fa-var-gg-circle, + "pied-piper-hat": $fa-var-pied-piper-hat, + "kickstarter-k": $fa-var-kickstarter-k, + "yandex": $fa-var-yandex, + "readme": $fa-var-readme, + "html5": $fa-var-html5, + "sellsy": $fa-var-sellsy, + "square-web-awesome": $fa-var-square-web-awesome, + "sass": $fa-var-sass, + "wirsindhandwerk": $fa-var-wirsindhandwerk, + "wsh": $fa-var-wsh, + "buromobelexperte": $fa-var-buromobelexperte, + "salesforce": $fa-var-salesforce, + "octopus-deploy": $fa-var-octopus-deploy, + "medapps": $fa-var-medapps, + "ns8": $fa-var-ns8, + "pinterest-p": $fa-var-pinterest-p, + "apper": $fa-var-apper, + "fort-awesome": $fa-var-fort-awesome, + "waze": $fa-var-waze, + "bluesky": $fa-var-bluesky, + "cc-jcb": $fa-var-cc-jcb, + "snapchat": $fa-var-snapchat, + "snapchat-ghost": $fa-var-snapchat-ghost, + "fantasy-flight-games": $fa-var-fantasy-flight-games, + "rust": $fa-var-rust, + "wix": $fa-var-wix, + "square-behance": $fa-var-square-behance, + "behance-square": $fa-var-behance-square, + "supple": $fa-var-supple, + "webflow": $fa-var-webflow, + "rebel": $fa-var-rebel, + "css3": $fa-var-css3, + "staylinked": $fa-var-staylinked, + "kaggle": $fa-var-kaggle, + "space-awesome": $fa-var-space-awesome, + "deviantart": $fa-var-deviantart, + "cpanel": $fa-var-cpanel, + "goodreads-g": $fa-var-goodreads-g, + "square-git": $fa-var-square-git, + "git-square": $fa-var-git-square, + "square-tumblr": $fa-var-square-tumblr, + "tumblr-square": $fa-var-tumblr-square, + "trello": $fa-var-trello, + "creative-commons-nc-jp": $fa-var-creative-commons-nc-jp, + "get-pocket": $fa-var-get-pocket, + "perbyte": $fa-var-perbyte, + "grunt": $fa-var-grunt, + "weebly": $fa-var-weebly, + "connectdevelop": $fa-var-connectdevelop, + "leanpub": $fa-var-leanpub, + "black-tie": $fa-var-black-tie, + "themeco": $fa-var-themeco, + "python": $fa-var-python, + "android": $fa-var-android, + "bots": $fa-var-bots, + "free-code-camp": $fa-var-free-code-camp, + "hornbill": $fa-var-hornbill, + "js": $fa-var-js, + "ideal": $fa-var-ideal, + "git": $fa-var-git, + "dev": $fa-var-dev, + "sketch": $fa-var-sketch, + "yandex-international": $fa-var-yandex-international, + "cc-amex": $fa-var-cc-amex, + "uber": $fa-var-uber, + "github": $fa-var-github, + "php": $fa-var-php, + "alipay": $fa-var-alipay, + "youtube": $fa-var-youtube, + "skyatlas": $fa-var-skyatlas, + "firefox-browser": $fa-var-firefox-browser, + "replyd": $fa-var-replyd, + "suse": $fa-var-suse, + "jenkins": $fa-var-jenkins, + "twitter": $fa-var-twitter, + "rockrms": $fa-var-rockrms, + "pinterest": $fa-var-pinterest, + "buffer": $fa-var-buffer, + "npm": $fa-var-npm, + "yammer": $fa-var-yammer, + "btc": $fa-var-btc, + "dribbble": $fa-var-dribbble, + "stumbleupon-circle": $fa-var-stumbleupon-circle, + "internet-explorer": $fa-var-internet-explorer, + "stubber": $fa-var-stubber, + "telegram": $fa-var-telegram, + "telegram-plane": $fa-var-telegram-plane, + "old-republic": $fa-var-old-republic, + "odysee": $fa-var-odysee, + "square-whatsapp": $fa-var-square-whatsapp, + "whatsapp-square": $fa-var-whatsapp-square, + "node-js": $fa-var-node-js, + "edge-legacy": $fa-var-edge-legacy, + "slack": $fa-var-slack, + "slack-hash": $fa-var-slack-hash, + "medrt": $fa-var-medrt, + "usb": $fa-var-usb, + "tumblr": $fa-var-tumblr, + "vaadin": $fa-var-vaadin, + "quora": $fa-var-quora, + "square-x-twitter": $fa-var-square-x-twitter, + "reacteurope": $fa-var-reacteurope, + "medium": $fa-var-medium, + "medium-m": $fa-var-medium-m, + "amilia": $fa-var-amilia, + "mixcloud": $fa-var-mixcloud, + "flipboard": $fa-var-flipboard, + "viacoin": $fa-var-viacoin, + "critical-role": $fa-var-critical-role, + "sitrox": $fa-var-sitrox, + "discourse": $fa-var-discourse, + "joomla": $fa-var-joomla, + "mastodon": $fa-var-mastodon, + "airbnb": $fa-var-airbnb, + "wolf-pack-battalion": $fa-var-wolf-pack-battalion, + "buy-n-large": $fa-var-buy-n-large, + "gulp": $fa-var-gulp, + "creative-commons-sampling-plus": $fa-var-creative-commons-sampling-plus, + "strava": $fa-var-strava, + "ember": $fa-var-ember, + "canadian-maple-leaf": $fa-var-canadian-maple-leaf, + "teamspeak": $fa-var-teamspeak, + "pushed": $fa-var-pushed, + "wordpress-simple": $fa-var-wordpress-simple, + "nutritionix": $fa-var-nutritionix, + "wodu": $fa-var-wodu, + "google-pay": $fa-var-google-pay, + "intercom": $fa-var-intercom, + "zhihu": $fa-var-zhihu, + "korvue": $fa-var-korvue, + "pix": $fa-var-pix, + "steam-symbol": $fa-var-steam-symbol, +); diff --git a/src/sass/fontawesome/brands.scss b/src/sass/fontawesome/brands.scss new file mode 100644 index 0000000..f05b3fc --- /dev/null +++ b/src/sass/fontawesome/brands.scss @@ -0,0 +1,30 @@ +/*! + * Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2024 Fonticons, Inc. + */ +@import 'functions'; +@import 'variables'; + +:root, :host { + --#{$fa-css-prefix}-style-family-brands: 'Font Awesome 6 Brands'; + --#{$fa-css-prefix}-font-brands: normal 400 1em/1 'Font Awesome 6 Brands'; +} + +@font-face { + font-family: 'Font Awesome 6 Brands'; + font-style: normal; + font-weight: 400; + font-display: $fa-font-display; + src: url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'), + url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'); +} + +.fab, +.#{$fa-css-prefix}-brands { + font-weight: 400; +} + +@each $name, $icon in $fa-brand-icons { + .#{$fa-css-prefix}-#{$name} { #{$fa-icon-property}: unquote("\"#{ $icon }\""); } +} diff --git a/src/sass/fontawesome/fontawesome.scss b/src/sass/fontawesome/fontawesome.scss new file mode 100644 index 0000000..2a5b40a --- /dev/null +++ b/src/sass/fontawesome/fontawesome.scss @@ -0,0 +1,21 @@ +/*! + * Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2024 Fonticons, Inc. + */ +// Font Awesome core compile (Web Fonts-based) +// ------------------------- + +@import 'functions'; +@import 'variables'; +@import 'mixins'; +@import 'core'; +@import 'sizing'; +@import 'fixed-width'; +@import 'list'; +@import 'bordered-pulled'; +@import 'animated'; +@import 'rotated-flipped'; +@import 'stacked'; +@import 'icons'; +@import 'screen-reader'; diff --git a/src/sass/fontawesome/regular.scss b/src/sass/fontawesome/regular.scss new file mode 100644 index 0000000..4a15596 --- /dev/null +++ b/src/sass/fontawesome/regular.scss @@ -0,0 +1,27 @@ +/*! + * Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2024 Fonticons, Inc. + */ +@import 'functions'; +@import 'variables'; + +:root, :host { + --#{$fa-css-prefix}-style-family-classic: '#{ $fa-style-family }'; + --#{$fa-css-prefix}-font-regular: normal 400 1em/1 '#{ $fa-style-family }'; +} + + +@font-face { + font-family: 'Font Awesome 6 Free'; + font-style: normal; + font-weight: 400; + font-display: $fa-font-display; + src: url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'), + url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'); +} + +.far, +.#{$fa-css-prefix}-regular { + font-weight: 400; +} diff --git a/src/sass/fontawesome/solid.scss b/src/sass/fontawesome/solid.scss new file mode 100644 index 0000000..f673892 --- /dev/null +++ b/src/sass/fontawesome/solid.scss @@ -0,0 +1,27 @@ +/*! + * Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2024 Fonticons, Inc. + */ +@import 'functions'; +@import 'variables'; + +:root, :host { + --#{$fa-css-prefix}-style-family-classic: '#{ $fa-style-family }'; + --#{$fa-css-prefix}-font-solid: normal 900 1em/1 '#{ $fa-style-family }'; +} + + +@font-face { + font-family: 'Font Awesome 6 Free'; + font-style: normal; + font-weight: 900; + font-display: $fa-font-display; + src: url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'), + url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'); +} + +.fas, +.#{$fa-css-prefix}-solid { + font-weight: 900; +} diff --git a/src/sass/fontawesome/v4-shims.scss b/src/sass/fontawesome/v4-shims.scss new file mode 100644 index 0000000..448e25a --- /dev/null +++ b/src/sass/fontawesome/v4-shims.scss @@ -0,0 +1,11 @@ +/*! + * Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + * Copyright 2024 Fonticons, Inc. + */ +// V4 shims compile (Web Fonts-based) +// ------------------------- + +@import 'functions'; +@import 'variables'; +@import 'shims'; diff --git a/src/sass/fonts/Inter-Regular.woff2 b/src/sass/fonts/Inter-Regular.woff2 deleted file mode 100644 index 6c2b6893d593201d7c94e52687f78b2ef28b357e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 98868 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%0D(-D;tD2U3Vy$! zeS1?~lms}dmyW@*jrJE{Y@0piX+4btv zbgSEHv7D7kEIK?KkV8AWy;LQ^`TC0gz_S;++3 z>@kEVMt~3j_I94&lxw894RHSfzPh$72DL2D0ELtaecgdA$*mWt5QO4Ko1Nbmv9rB7 z|H|Xg>*i7o4Q3z=vV_o(XEb*uU86qJOuv<^V!AT?15xFoR72Y^q2F)>l`@2JFamqa zIMw0sx*I$Y1}{d%7f3Kku>2E^z5PCXTfK-U+o*I_E$j8y(5woPfflYBu8F46j~NrV z;Ft8sTHLwwV73xi*X$sklAl0}NxS;L!QwGvtiaoJ+jJNXLKR!0e;fA!XLeatB*!5N zAO#Ysw9RCMq;LZR%76evKc$_{Sly=4Dd-w9Io>N-v|{|~ofL0Uj_F*1vvdqzCRJ?l zzZB*P_6R%;c|RZ%+#``JkmmYja-^jSsya`l9VblE4mBDe zj)@mOjUTRN`|4o#7C;Gx2h?^TV(B2!*lhlWm9d^6soa*0OG9L~!G&kOAobhU}SrSg$A zs#Ffzy0>z7SgpTTufKPaf1sa#fEm2w1Zf~x!Jq)w?#4zG$V(}kAPAqc76qzY3AQT_ zk+>qHwJDNzjii}QN4@1^AWxs+fIO6#OoZtIy5e^Ir%_#XGO;R-vD2lU?nw8}7{4R7 zV{VDwPOdwun)po%R_J(YjgLe#Qb224(i{(%>Ov@b-_&ShF>^_Hb43&QW6Gx7a+zx# zp<`#yK_?O6s(F#e{QI+yIx_e|BrMlCf;jit0oaj+7o>DEzE`yKN0;>(G4 z9?F;BN|JYMRO6>!_0{8@nI*vm&&X&K_`6&Ede|cb@a9{|3r~(XD55#Sm#zCZI zwa2N6iDe-Rj;Zklpizb&Q+eNyTbe7aqE#CvHU8#JeTq~y+VFwRP?hfXso(BA;o6iK7p^8j)T70hi|`?e&Qz{@Nf1%Yo3D*{Tv@CqzW`nQiGt-JS~<@G*jJw{Sy>_ z18B-+mZhH}2tJt&^Jw}OZ)Ez{RNw8JJCvcYG39VQM=sqpngUb7P_Ria|7*H zYDg+`SK#8qD>-{C-sto89{FviO@>N_|BgQ;dXwWHlvmK7Ka#11yRLF>&FBI_F?SZ8 z5!Z|i1ZOy%$KoJuWN~^A?I%3uyDVz(^%qbv|4fR!Gg8BG9>8<#0P7}5*5s$$0EjOc z=UAhw?4f*;8)I)z=qN_~p5I(|u=+9Pfb6dK=Z)0=MCWEfVeM1#S%YX-(Yz1K@OneM zwDMu+@}9TWGP#( z!U%X5Ek0GtM(|~e7+hOBr))r7snZx}d9!43iR@G4-~R1DT@hlIg?^K^N51%W`mNwo zO>sZWoyva2nyUL7>rg6iElxtI)MN6lO&e`zvmSD&Q;)KwuFBl$(mgt3Y+v+(_yY21 zD%8ID+8=?ZPScAHM;)U@EraiHo{;A+}in96JS=872K3(fdeqk{1nX~m5c($=f? zu4+~FEq2+!h={|eNv-K}w{6B}cQc!D!uwqu>{@|#8^^XRnoTJ05cirIG z4ifRKF40~awx^L8P1B3+F{K{nn%XDDa5tpOzWGRIKK(JXS=HR3b)&jt6rw@9KQ$lB zD}igU@MjM5y%E1(=d|(DDY~DgHT&Ad)a{#Fh&Du?)MhNTHdD*x%u$`MDO#k}?X<(j za$R0&^&(JsVob-|x#1;A@DwR}OrJWA2ycjy8)a)p@mh;n%Li|W(%WP)O}3ni#=_-N z1P6-^HMaRR8l^9jg@mB|8E8Z%AThBiFij_zXtc{|x6^lE4i6zA(_08iBP=#yIvN>* z^HQf$$}v1UV-y#F2reWM>1s24`{&#ozl3v=lKhCNg~Q%Tf{LA=OYO)+@LBvC8QUuScRz~-y?UdSd$eDl$77K2&yyq#S+WBkwg503!amUA^bzpQP*@C^WTt2duzxgQ zd*dpu9KxQvV6utmqDy}x0u7Zv1o9Zm=1y^~jd&X#5Q)P^gI1DuaVn%9xm(#FI1SP%u~{L8r8e2 zX`(X<^br;)L|Vm688H3PVv=92&Vj7}GfwVFcSK&Tj!A;8l4OouYFun5lu5;LpzvrU z$^9_?r2-Wd-|$F)z@i$-{tiV|KW|^OdzVs{04=9-G!w5lg~1?4W<+nZzhv_ba?!`2Tf zVgUxX>#0jW-?pN+81b-VnztLPJPC?Pr5s;{pp>oz8rTQ0-0D=(St=sJQW265vx7Ym z4};ApRf}%cS4b%|e>9O6vOiYEJWaaN&c5{4On6x{)lvA~Mwrgdq(1%H=?3S_%KROE zle$Fd8NXlmvtFFDw{hF8Zw;b=?Tk+YJilmo(p13g8!6MxoKNHc=4_7K^)+Skby zg6ZVsBtsOOco+Tb|4j`1qp|UY*criFZRFIS8u-sx`EkC{F;(53z<_i-g=9TSSzcG5 zWD=clG0mz|4w-UcTB=9uypH+0 z488Ph>W%-_Ugtg*38+<{XyIhC8LpcnuE44izSf8T-i z;Fn={fk6B{{2SM)zfp+*CK^XJAKdjpB@$6Ip;Ss0OC+P%bYEdKaF7jw{&k(e>gCnb z_U1sUNbfC{As%if(?%p?$ZN85GN!aSL0~fo+)A)qvMEJ}6-HoU%la@#{TREg3D5^D zH6(J=q|%%~18NLMtGiaL2$r{@=?dI1$9{&4m=p#WuhL9fkTtfpW+ifM>jrj#KZ&@6?=c>X?Yski zCaO-OzCK!tAUwejjzO@2AjkThIoUdrS7cxwS|E4|ST0l=Sr2ZEY+BGn{2c&vu0FX& zy0-dzVpFP^L?U|=lr1dmx@VjxHv`qEpXx9PArRn@%Vex=tjC+5i;1!CY{gQ)M{yIkmizLBuG>1=!VWH?@)LK`a*g7lXFD zbb{n=6{YGDlh>D=aqYyD(sK<8n=hRH z3wxe^i4evp8jRjGjPBU@k~hEHc!gNHsVp#n&I%wCK2r)<% z&0@-+4VyG;d~@ae;iJ2cZ!j%e*!VtlFj1WdRT6bFRTFLVnprz8fBETU4dlP7=Y{+{uLDMBlD|#&E43O5ARXc;yz*a+3X55dzvgqx1G-^QyF$7a%swS1zPdL0@eZe>ZS~5ro3kLlM4@ z<~q8;FRs*&jz1QnuU^=nuCKPs8iZj!t+9c>U%ZULh;a=jn(`vQnAx8J)>F}_;?UsK zOQEQ+s2-Oye(M_55hE@1wJUjiWCa}sS#Al^B?GRKnR%Y>PE z29EFvxkwXt#=6vII9_^bkpJ=H>B$szJSU~xrf&ww5S%Px z2%$G#_g=#kAcju%GVtL`T50S7H8;HECB-VGQ&w{?%3`R7B;bQUO_2z(a~%Z_1RB zHH$Mf?(QE{klyw2`~dzxW>NanE5`l71iEy&&zr#~(y3P6!uzo5 z?IU}V-2Kr%ZTUF`;jqN{M;9Yt2K@u6rUQ*eq?G*w?W*Ic2L2QI=$AvT$i_QAyVBF$ znAnYIC2t7K?-(JyUkTrWMJ=Cb(BT?F>RT9910h0cl0s2^$*EQ*T0>gAw6)UV4wd%w ze2;Gns|{v5ewM*eP4Y>_NixxCdsOV7L?4k}uSZc)UBrxHq7x{n!kHFP{U^wQB@d0L z5Lox~Ak<&W?&ZVPSs5;&XOsgu_Db-7y~)WARLo7w(mYN33J5Amm?UwMw*c9;y4l_s zEYpeT2YhemQ1r@#jR)u6qM|6dE6sWw!TQc(f$IgS=v$PBZdTzG11U1Yf$qwAA%s*V zQwmpB62TXtYMaGr`K3RW!=1z$!z(eV>ZM~*v;xNy)UANTmov4EnQ%bc(h{S6D^#H# z$!R2)V&m~(e~8H*!VO0xDg$Mv-F_wzv(kHPYc3QE-pfsGCbFr#g8Fn%@V(hX2O&Jg zldmeb`7#7Vy*i+Yt7}VejnQ7QbiC$!$!)DXu@>`ZH;{rp8fEL991yF<9B?e;M5Xl}ZT) zJT6b9jOmaHAt7G1AlNf)OsmsSJgcAWGB|C4RHoHEi9^<|;z^v;HDh{YnbD&XnB8Wr z-gcNSf%lEG6cB+}4k(_4at;dW|6v7XUV8xKbO5(M=wY8-(k4Pr5b54Y_IlU}sX+md zg+LXJ>I-JIYB|3575V$jgCq+}Q-F?`({kB$@#H&HX%s+92W7K$vHL4YQ5GdDy|Sio ztwbLWB^OIq+~3U2kOjo6GZ-T>jMzyQxkj*x-wXO!;!%z zgG9K@XEDN9ir`0Nc@ZrhNK3}=dY)O0CELBCapiOe*8De+3>t$`$`VeF?fAdUECpI{|)pc{!$?$*-jkr6bJ;7EZMTHSJrUV&49SzwHq4nKV9j+So?e8d`^CD z9D)#H3NYjnk!BjUQ4rq?k-87cPV-Mi;pE7eTQqtG&HgtQr)ky!B|`e9tOc+~sLB)-3G0FNrm;rN1bfBC(VyQi_$p-9X%yKhT!9}k}C&U z*#Z)F#MP+KYV|IW4fRQ_MyvU1VRHjm0)k+Hh;YOIB^g155;TZXMp1huR;SULF-BxF z0Ck5u0Nml|Sq5|yrBNeL8t_@AL^`4z1@W469ieNV0te;6ch;Sw-%KcKyRWu*LW6>( zHmk22Ef$M)!={V{Bsq;|;th$#Afqwa4d+nuEuD`V9F}PhwEtF=N`@0^xP(RdjH+>I zuS$g+Zz`Bg%ukm6oxKx_>^SH_R1ekaEijhF5kA}Q!l?5XZf~>6nFRGwYYi_*%`pL& z@i7Gn*mNuD&3eZn$KA1*_9UM7!KAc1dw@AP6zPJ1Ip0Wq1Yns?nD9WI+mdH!^&JM8 zYsz2hb*!9B4)g!zEnQihIa+yVGUEh=Lt`*V8O%0v# zf+ALtr=gj<5P&I55EJ^^&w8It1wdYy;C2mmK^1qu01yHZQTqQT`S-K^FD)l5^_Q;! zh$e0VDMtU@slZO;8K-mC4$s?`3Tla*z$+E#SZd=5oxJtH2^$N;H;xcG%qn@8y;ar8 z;;TlUz*+L3iF=0?pXSvn5`dz1^5>z57mk8^{@v~rDc@8F{%5O{$wUkUBCHrnmo*ei zrs;IS*s^D-RFWBvE(eZ^c46>>Uq|K^3cZU;%Ybo1sDZA(*3G9{4;=*js*oy*2mw(@ z43=hWsklS=2-K3X8u5!V+#xv_XpTuYEJlgkMHi5|RHTC%+P|XUnX+sM61kJMGp1!X zc3Zf#=0qsIQqbTm#Kz>kG+>=HJ0#S)TC)7W@dWa1s{-!>9bCo;HyN0qP~S~-$Hx99 z0frWK8uakBX;W#~9@lnOrr9M6DEf}tm>AeIXUB*~4C-4N)BHyZ=zp|)kp8RX^B=`^ zv}t-4PGfQ~qU><&wisCK5e9sD+~;yOTOt32!LWXh>&! z!rHa(S9@K0?c|H&-C5mFIM)nWr-(|Yel!~`{``TxYO?nyxAg*#ac1tK#hDiIfdT@Q z&U7h?QhShbik?q9fv5#(z9`^g>{=_ZQggnkX+{X5%APevE3oR_z0fFoUy9_&+}pYc zPy>j7>}|gD+>X}*90BoP!6=ZiT5(XH2VW`v(B_SBTosnG@Cy(&a(kuOMmOYrRURDI zc=4w<#o0|lU^?tKj@<-4i@Ij$FQWcid*Qq9%)$CV8#Hid{V(1n#6t1gwI~#yfU$>| za?d?@`z=@2<+DML>lw=a<4Q974{!bhQKV3@&A&6!o#lZKU}6{^jsmdz;t2RLIfS=@ z%WDki<=c{bCeo)Oehq!E3Y+a}vvG@PNvC?JJe(_l%)iuctHU8#l6v*#3XUAYKmEb~ zmK-XhWp5uu004Q0XW9%^Kk80-Fp}_(SrbInLJ$YP^vhu$@`IL+$pO9XJp15nRgPPg z_?$rgU7~$v|DH$q7z$O);E{uecYp#(s)Xs^{@-U#N`YX-%>C?QU(djtf7QSI&)H0w zbPJw$&^N3p<}0WFMDteO26gtVLzKlG%tHYu0V18_X_jfCDz#=!P8Gm*5l}z55YWeT z{Jh(#3bxn2g!d(lEtvSw)v{UgDzvJtxAw&)eDT^-MkzxO z`qw6Q5K#TgVcO{(4$=ODph(< ztvW~vwn$Zz&(lvm1VLaW2pd2GQ4J>@-O#9Wb~rD~?WZ%k79iD*V?EIcULy$Uk|&? zMP3{5WfdS$FoSWfAT^D&ok!R&7LA0#Z1?Y`sy0UVjCnIxo98Q7sMru~h0LWPauKc5 z!Z0+Ac>m}S8dl=8oW_9FV#SJ@j3&JnbZOLm)w^6yD4zc{(SkVmc8@e=mN#OR@8`8PcA>t=EVp+BZq0!sK4WS@HRRS<`57?_$qbXQv7LbS6VJY<3(4^i6Xon+TI)ZQqne`|k3!vDRQk^Fx)GuW@H zOIimW1JOH^)BN5zM!t;Wg3$3#TKzTwhI~uektkqd2oWSrpvT=*s@B1Jf;A}0$$tDL z;_UB5X27grTD}}BJC}3~-qZaR;OX8dm&7S_|2{VD{pOulqAdX=-}PdCptSPVHzznCH`%UQW*0ABVH(2%?YyJn{ZG@c0U z)51IJxt=OH=qo7L0~3#3{gT7*HylG_ihi4`INS3v`xm{GA*csVIAC&(kX5qoZ4zo% z#z|XoWQz3r7ZfRt5ckxCYSQF>TzO}OK~?py3fZ0zX5tkkQoOb#J;5Q_t>LhaknjWa zFxXtqC87XC zykx?DO-z~U6TZ%=w-rY+-7Hqlc^&sGqxXQJcEi8iTQ#0NAk@1kd$=6@hwD$`@FTn*8ysSEx*-v@KGWUYxy7y(B8qAK3IV;MEwbX0ssj>(y)Pt)1)1 zjwEie2v|}&R-vA~W@6z%j-2{olNK>|76-cFW&BaPYc#mq)`kbg%b2j(X-9)hRLm=L zLK0|HjT&Lg*W85-MaHw$8ktv|&v<1aXpY(XrdHO6jQ90|q)A~E_jj@Lr^)us(aqNl z_+r^Oi_qO0A?{-8K1ckUQtG&9F4`|QBTNhRZQi#wu`=sJQo z+icj~7g^KHu-fcB$XEZ(AEL-tq|Kdm<%kqEila_`Nqd&_;PN-Z!oEP>FmV}APIQeB z&&){%4k0Dl$v2h04~vb1*2(Emo@oTpvK6tBoR&_o*~2oulhg2W{))pfI!a%+=CDd= zCa;vxKIHr2Sv<-^AOG&>&xDTbebdWY_Q zZvJo){rS^gpgVG}!bGo@MT50-Q9nUJU^#-}YQ4e=@K+T4aQ2r4*QIv}B%;8J@QX9} zwcqL6_4p4stxxpJ`+53R_@I65C6{-~%t-pZy_PlKGqtwMKm4)^P#DXHj7a8B-t@nJ z82>&~^cyXc9=uvR*9YPkbw5QpPYBp~zUx22eZ5jqklSn8yTc)ezj!L%`;v~+e&zkZ zR`@7?%z2pRUoo#sKFqfPZlV0r9{DY^FBN&c4xMwpjf8hrxb}z$^ziC~HJ-(pWqt*@ zN(g5KyWr0V)E|w0NGX2EeVNgjV2Ww?R3J!UgRQ^Rj4Rwz&E7n9E$-YN&?)5qRM25r zyL}_a4&MnObZ>2Gz0FKBS;}akyw&IraX(M(iZS)08U%$(UsMj``4x?@)-lPukc|ZE zKC~|$KXf$tNykyDhsG6vxn^ARh1-^GW)Yx*RZu9LVXD4yly9tk0iT5Bt@Y3@QD;-< zm#SNhPlFg9jnQVO1?b#Pc0o~%zDNc(f~l=Ra%XSR4Tl%>l;s9Jj@tL^(vIGbM-n|Akuy?wj7#JbgZjNhJJY)7cB zP-Xpv<(uaI(a$Z8E1Kso__?%NvyV~hEuHa9Sv~5?CSDuc$Zg(4W7BhH-%-^;N5ITY zK%&2G_lpL4gu1nw3QmaZ;xIgqEb<>Uf_fcY&NVd*r=f%i!6cL@g;M6q+Qx90LV2T& zBMVkFRi<}yVt!CySfafa#-v#E`n8xcuNua*uxAWLA6&7-u~05!s|N)})$LQj@Wb-F zo2n+GAlVZK0r~<=WGrOi0g1x=q^lqw!^lt%FHgb`5j<+}lAO6DWJzxI@wBUDzH+tE zjW8#TJhenW&ZUXN<{J6K`cbjlBF=N;!+<;&t>%x{J1}mvQWaJqZp(AE!%K%6(CQdv_gC+aR3^>* z8#qPzsM5C46jY)Rv=woHwHJ{RXl*mBd4aLk6_9M5sofO5H~mGH(luPzeqfp6#j)gb9osM zab-eah0$NZC07d97iM0ZxqL5kRk6h0zffv=z`p3HCw1+0%D|7p?S)@A`8gnpLxBH` zcvKV&N)Zw+fC(s|dmtd}J=ui3r9cdGEXX}>NbJ8=%nLmqTSN&B;+LqAhZ$8ntGmXK3w>Z^N zxaUI*7?0tzXGjp^I=-2T&XIe_sT7$BgvXL)hf=s_UJN*gk+7$_hx3vvj&KJQ8R%Ra z5sU^+0wewlQU|fxy0DdQNcQHFR$vT(9Af~W1HOnK7#^5!2;sVn5;%+9bqD?zkUj?N z^IU1q@(_r(aYw-T5FOaHOq2%R$4Ig}1KO+zC?Aqvr9c<8AMH<~d z1IET{lJ)$`#r3au?&9;+zLaKX)iq;mb>ur$pyP#lATOX_E#T@rSQCphs#jHaX`f`v_x#R zjoRpA)S2=iU`W%6FOrZdHXrC%a?#*NP`o=44(CTK>;#NpiDn4rWUM8GKZCnXZ2WkkB&MRW9RHSd!G zFGgZj#-*&X%bOLsies30qmCgzz=&ZOdcnvHXW2hTMD-{3^w5FNZs ztO$w>7#`_QatJP&>StEmtesJr-KQP}%;h*Wkzy>!6=?!WEaTXb^%nE55OHRXM9V99=iCHL(Ivk0 zS=SbuO3TdWAwixe*8G6Iyjjc;#-DxtBs#n#m9o0d)TeUr9A2}LIgbPU zYp~3|_N`aiFa+b$BOOVr@Qf@xGQqN}11QeCS#7_l;^13*9ZyF1hfQ<~y+c4t5>*HcAeC&*p=$JGL!jSw_~?a}gt3Z=zK@ za5LuD%w+qv_ZoTV@Ju&0r*6I3@o0|DgTJHn!-Q8m0_HT+(3H+yeisUm35 zZtuo9ye4N;sZ>`R-9&(;wD+p1udEx;PqZ)o47{)XUy<0FNAka zn80Gu7=lKFP(wuMc{;HzS_C4(hLOE}p^Jr@b!xWPTrgCO^>P-`yM4=SzCan!iH31D zziV$tvs^(IS^JNT7+nI6SwTz}N`;JvP%@e+x0~4x;abHxX&HMx5W5s!1TTW8;Lk`Z z`)8w$8c)Q{*I@JbaYLCh=!pGG!Upv36o|hx8MSu2S>#qK+rpWx^{7BlNkb#t9gY-A zvs5Y^r%-L?Wvm#7Y0;c{(Q0P`OGVKFQndm#k9g;tsBg7kA$1e>lby01ualDv#>X5C z!{dmAwteol;yijyyMH_0U^m})GuCXA;z=0GMSEPv0+Kkoo+89+4;OFWV6wY`LjRyFPiLd*NQL6iZT)1nG z5`%2Dk4AUd_Jn?-dy!c3`6K=E)OjVk#ffdY<)Ll54Z7ZYMcmD+Am<0Im%){XqH%cBjUzs$KyBL2*;JYg z_BE@-5WL$?+^>R(FN+ZhWz2CNYqn?Cfp?eK%AeUb${)bis_fQSZRGF&n~caa^Lv zQCX3e3WVNsrFZ-}a2VXUn|UrU_vMLut))w*QV*#h5hO^29T%NT zEM|$y$*$V?&3l=aWWqUmCr)37HB7{$iSC8QCv@d0EDO;_tFU5NKP}aI5Vl=daAiYu zJ|+jy9bTQj3-;>=9x%Q7RB&Com$^ zGKEVHmKR3c2Aa%=nS&`P<=6N7t0-(lDWC&W2htHox~e_PpsnmVYLvXj(M4M@rI|J5 zwItQhK96PB{;)lN6GdgX9c%_}y6aZXNHb!EphU;P81WekvPgayL0@N|%w|>Wx^yne z$=FEPWo(a6t&o@S;+}MRSw*p7U}pC5(EY$bj)j)xI8 zA}@F>XAF>+Zp+VSr~eb8R1>}ULwQ8}x&E zNxvc08(HQ!>oI|cV7Rj=6BkK2MHL>wMO$?_8B~I04R-Y|2|dl%Xliw@SyNJ0+Pb;F z0T&d08DJx?OUZ5}aWV>y*4|BMI0O}F<_-7g7~C?*$Bjhd@I1N$H#aitmBpFIXVRpo z6kiQA`IRsPWwMpOmvJ^4FN&TgdI$|b-Ql4sm{(WMr>m~#T~O~&Ik(m#JXk5jz5CmV zEYS&+3m#iKx609hW+lozz{qjC-63eh^H`5 z6(9yMWzJceHUp)uiP8K~!)W3SYG)~eBhv7==&w?QiSVY+96e}kR(5r|Z7EzL-J(~+ z^7FjGkd-DW;7ci=sM@UJtldYQE=>)Nj1lY&R~rykP`9GY{UaGUoX#(YvCXGP!ET7) z%JBb-taAzy9qQV2+ox^Ywr$(CZR@mc+qP}nwr%&E??=^4O)gTEeUV%wwUeFoywA!7 zaKfpD#7aN8>G9BlA>Tsm(*JXY5#ITgx9*E_wa#jzANB~B)wzf&UfDn*mfa^C#;O65 zySCA!pTp}}3d_E%m1m};a~9=0^*Wz;exIg&H>TofYGkl)c{5fVTJGl3*~^I5V(8Zt zFiuLjy{t?s#+0fnW){DqbFqOhmDg#j$vB>Eu|4Y_IHXV?zf10{ns1tblAp^?6jYJ=?E$+y~D(x;9}lecm@^GNneWH5u|FI38& z?**8K2-_NWN3}+fdzs)MLz=C??nGDrs04*-jaTk;r!M#L@aID?>M15c&I)mna*_2w zKn3)*eJZ#Tdn_R+MMdfsh(rERuGboZrPY_SS3B#M_E8+2y!Yvab|@CbqhpSF`MUhy zmpjEjLW%}GG8MxjBrH=3&Gj;CiHgBB-mrhJxU!hek2j?owxa2xCa>X_yz?Hz=L+U< z5FDIs)AkB;g|x9r_c>4JLRE(xxFieWGQIpwi-wVTlUw=6xX6strH`uXjjYIzJ)ZWP zp9DH&n#>U0WZEyWtsT+3&vOA&%Z^AOI3Y@QGOr(XLG3%w&)R&Y9EebL1Ur(b&?Fjm z8eMnD=Xw#jvAHj(>^rN^&!(Ktk%WS2A=(hMI5Qkx9!G@r$@WbR;9G?W*yY^W<_k#F z^U>$T%@Tjt?evwH_gpvU)eMKs2gW6+0eg1By;H__NOkU984S81jAzB#I4RCh1;4zH z$r#oMRrn@^c3|T_$Wk7`Nd zlxhdnNOtjDr4R=t6JC+*TIKB}^bkfN7iNog4X@l2T1E%tcDTWDHx%3q6iyLlxjaA4 zx0#oO<=DVgjip2!Mklj`qyxHf6)yGXvdAx)V6mP}6iJbY7^9T+<()fNwl4AVoOa;B zq~>Nx!4ae_S#8mq=1;7~hH`7oYR7Ffh6}WWw_!NG!2+l(qTVJX}a=!?#7Kym8V?F+o5Jx)XMu&A_e=nKlenMLP zR4cvu?uQzlAbY{PI11?|TXsI%= z$+YoETlLBvTx5T*914{s6frdYzP%4nUb^< zo!LsSY(8h;k3gEX4+O1tbH(lcaIiNWN=L@`1N0^Lv-i*nTiUZJ(L4?9>^_e8K!4je z_7F!Ku#k^}IfDb%d~GiJ`@Tl&sox2;W?Nz7mc4=NX^1z+w5e3<)%9d*v@Ma_(>(L> z0Ngl`m@A3QjE8+)jk43k4O$8jb-vE@io~i3^;v*xQ^gl}wi@gjX3nKhqClZjEi1ky z(vr?Tz>4}9V9#Ke5O4Gpc8?SZ^eM*jAaexOa#eLJC0su zeZ|f3X8(Xju3lyz?|Kb1Xq|@dnHpb=!Gw8vQrDRng!(&%pos}m4Fk5$3jTC!Y>bIf zYl+08jgzTb=}T8FUk7H5%QmYUNS&W@flnBp#lF-Q<*Wb|`w+Z#w*bk_X!RFaJ&-RL zD2w?UUP`{k)FI|n@>_@E+UsFYVxQt(DRxn>mO~CqcIf-z!+#;wOAmF$FJWH+h#t3oMzyUZh(|yvrW|1SP7WdK;5zih0u7 zX^Lgm8=CrGS)Q)zX~N2`>lo+uy-$qyKAkS<1cI6y*7%w+Kc6l?O+ROdYe_)on(^|TNZ z03?7w9vwSCIN#zN=T#hc+Q=evbdfg5_CcmSYqGl>eSn_c|MQ3l+ch1Kjr$nuAErh^ zLQ&AD<6>B0L1XC_+FZW*{;+&07|MM0C~Lv|gOs-pBGZPN$SlDrdt!XST!3)i)e|{y zBE%~EN@5p`E46Ljjb`zFo6F|#VY@s4v(X{LX5EOo|4Xy$=piQYVtf>UlQs_SH&&8W zF-ZTKL7Mh=m77N0yLus_c$L&f-PLXvee$*&%k0?4{jj=6&bEMs-9Im|E%^gg)28tH zg?%rLDPr4sSIO=jMlAJ3{tz}j8sb>9(MMoFz8GEse$BD~zL~0N!MssGlAoNOizwx) z?E#fguqoQKw*t=_s*Uj2JZ;ULQ!PM;l-_JDXMY!JE6nl7$JVZJd3%*VtMHG2!M_$K}&tpnrhR!tT>sG6}r31$!wCmW*uqjGs+OA&PJV!1FCxmaO#LBuz z_J`TqUM=oo9)n3k!k(r{kqAk))d9sc(-)@Ir-46gp?|B{v&~O(MAhAshGvaUFxae4 zQ0O-Q7Bb7S5!7;QZLy7M`*YNCgm(L~e4e$e%vUt=wih~eRjF3qG$ilf-Td7&x*TC2 zE#0tO%*Fk>`t4}^yZt18SVxNHw(XPry^a`~x@7#)U)5@G0(;_y4)NT$lK5hyeyFt( zT+-SWZDXbPSI0K5XTTi@&zG?7D2_5%OtskQ;-COL$jeS(=AI}?%o)t&*=PU1AJb7Z z2ob~ZCG(4YHGBw|{(7B!IttgLaNj@oAzg4^SZaSGmO{txBl7T0sn!?h8&Jl^R(42w z2edci23#df{u)+^V{(y)E@sw zslhd`#k z6w6+b&3p}+?1^f96GZ(+wgeS6Xd{_t#7Hphs|ryr2PA#ScLyxlKtyK>^+H*)<-a)I zf4>J9AN%=Mcvc{AN&rBRbdkYxy%Fpi8&he$$fhi0tf*zLm$XN|3kXm>cPni?C{CK| zXxLagdDyIPr~&@!Z8dOe$Ob0ji9{^uIJj1I>z4r6a$eQX8l`Ykyj-K!cw$gx5WPP7 zyi^XtvE1i=AJ&k`I?4wI(=7k-Qdb5=j?}p3n=+fl5Znl}S8$sYGCFwuKtVEwu;!?F z)&qJdd|xD1?82qEn)^oeicBQbA)0PlUe5i%Af07bnquBv*gmpf-F{AkqlM$~@K&jf zTckb754r6_3JF4kVZ(N1P92C->ML+8pVX&IX1O+q;t_g}rg%-aiOpLZY+nK2UlVHE zJZxKUC-%bc{N@YdNh>!)wvon>8lEv~Btzs3H8NWIFd_|tAxbcDQCY~rrktuPpRrLU zVu7u6#qWopl9TPf_;VT3kypc``F&#l2UnBy_I!^{xv2`!+#+_qU|o($x3GNvOP43< z`N!q9srtk?EP)qEUolb4C_S&5R+J?s3z00@r%h1 zkaY?UTsXLrW41h*TGwB8Yhz(?5eMtVs3nSl?<>3n-1^l-g!Wm3$_N93przBeRBAI z8puHbuzmojCWH0FaJ+QSsXUS6e4dPME#&2nR}Ch@J8xcz#q&vzWd;cibMmI&OVMyi zjpdaR-K?NFW6^AhTbT)nOq+oTTb2_gltjQ|JQ-^#t}mvtu%%5Kj!$NAryzy?hH>D z)i4v~^zDXEo`MnWk`zIzyc1I6$Bv5KP7lz}(tQV>d|F~$BkMF~q!x=dCYEZ0J}!H8 zC?#i{yYt#0Tu-^1zi5Zw%+C)=p`ali<7FTn?!^d3RaY$eVItKXBX-pQQks99R=hx& zy%)t(RC}wuN>8mHUwU>GZB1?+TO0Lmq$QOiB60GUe_t8>1K%Wif+}u#6utxar(w(I zUlCln$G|MnN;X7#^XMh1+BsJV7Oh3oY0^J#ME^|NY9cLVbCNNPV%1W-+h@Rk-Q|v8 z)Hp_F&b6(ak7T>e(tLWU#XVVeWOApb7ekT@hYrMTr_G;Ncky~aRf7cAqG>)2iGg&p zxvfb;l}KxAmD?u$YR9-q?>H@OjOl+kD`T)+4=}hrV1>pNU-PCJuQ93~%^e<<^Aq75 z!9nw6LPCX=8;CfiISj+ASxu2bt}0UGq*^}1KZk57~{1(%XD)L zTi!%FsFnc3s^SC;R*F4Vn40`KSW|wVgBWpO2}B}e@iyNo^jiG*S=q2Ym#~Bl_L>vK zW@zHl@`}Tz%}zkGSzRPZU#6){zb0>FVVWT#LYHWT$rAoB9YMlnM?I?p2Hi^+pkx@r zE)2A#dQJF?<5}p2H+RKztJ4{=v2-;e`CB6LIz2#@a&Ak{iT^oZ_C z_bhw$n3SXY=T%xB<2qc(bA+6B)i>u-9#CcOEN)0@=%aVaZ)YX5ZObW~QU!-L zx=6l~7+z3WW5vsbmxcFR5Yye4;lBK@wq_`YR(pcH#bg3-^Px*iMv~-sP*n1o$6H8F zc)V-JSZQIeej6g?aHXu?vGhu<9*7N$rbu?>)XdEBy*br|Hw;%L->kF@>%=I!bBz+X z6dQ8IO3e*Mv2W~1^z;Ej>^_q?pHRP!iRN1?!COrzwV9DIf9sN-qk&+8a5wWOcJnJW|B=%aT`10*RNhcvUmB zp@NhA61EgtMKl?EURrd&#FMff2=l!R|^6aSm2J&lCi{a;MyoxR4+7qR2WsFdS#74P-!L6dY<6j))~!$1X;MNpTGaUz2v zkt=L*o&*@36Uaf|OJLm$R#X6Agyql6kn!&miM~*JMZawOlV4INF!Hi~fRC&!5~;cH z5#UpZO4+09gR@>{{^&wkTngwSw~pp5QJSVt#Z^b2frOT9dbB|InGy!{NTSIOhmc5e z{8FCp_({HF_iLLD0~P>qzsXVmrw%RO(3XROdsoJBqDu=^hn0ol{R>JJ+o+5dY^a zxkg(!s6vXHK%nHBrB;&5Z6EdFlmmbfY&)#Ti8SOlhHS4OR=DA#t4~;7r~QJKMS#sK zmbkKT`DfDt;bl7<(W18`O1PmE?zt;6rvH+*g7tY}mT0kb(MOo!Ba{X;&&!bTZ&G*l+vgKcmcQYP=m`hb-5Qxzkh!-c9oD`nYnK+>O@dAs=ak0!KF0%>jK)dbrO83wCT5&sT>&cERYwV$uH{1sZ_SHRK+F|J4#)0jMjdkZF zW;gxb>@2B6W_=}m7c?`TZQ1-U2wUXWoclP>7QetxB1@A_e&`qi02dUY)|qxFKha>oS}08G1nbj)_KX46%svl+PZ&2Kec%Ht%s7vqVcM49Io ztgx)QnWphX5`mHN77BYVWjc`&?So!H&a>b6me{qq+oz?gt>FTtQ%!y&@sFR3ZhM_xePmj;1T8BFObP=3?E>H%>CR9WS8~FrciGPux#_q>i zyvWo63(N?Jx<@LIH@OY5v&^sGYAKsyR-09D;o>4RRWZ`jlvTSmC`URLW$jJdB5ljd z_~I7aOkMSDT_!O2bnW)}e15Gmd3J{p2*l*trp&RF3rPzuz>MqZ9ENZi>_Y_Yv2a;M zMj}a#ya4dbhq=KRo_>Cb6N8uBsNwf>o=3CKtXwxCNgM6<>FPE}8M=zLgh}etcD*M9 zy3d>&VyfZK*Y?}3)9;^v^5o~i%kksw$4@(ySP#34xr63SoW-uHP2Q6R+t0OgXf-=J z%+vz)M%%|29&7zpWt9r;Lrz+Sa?9_OZJm18Mb}Tm1fEnl_=;+JAgO}JcXNn-`7-VD zYH>oPvL!YuudHt@2oNaUb6qj#KdjW+o3h>E-ZvFfp~gq z3IHIE7)2tXsOf(PB8dMTRXRPrdj)>0#)QoK)cil!nGlr}vdG%Mu>b>cq2jdqny_6a z90ve3WgnL82aHnniI#SQ>MV`8%mzl91VXmKh^ZLtaH0Z|a^FAaF4M0`WLEe?P}@K| zJ=p#Y7_Kc$zA0G5eB^yPts!^1HpUh_H&EO+Kp<~iB+m-JvIxO53ubDFsu_?%6uH3Q|r5y-Z1o9tJ% zh?jERuybj{?oBD9_WUy^qrG2Nc;<(&ir<8V~FDPY2 z+NkYd+G+wKw~vkUlr+nqtYdSHSmYK%v8q7TUO3?~o1=5Bc<`vlLr52VMPzdOCl!2% zCSNCG#4Td!o^)MW#&$5S@G@?_K9m^-+#u{d2l7u_yZ{$$jk)mxXAll&WnQMla;u1} zbzpphzK*jL%Vld{Glw-FQ*zNy7KtlGOICRUb_i%>6xU>P3DI#OFKqZaLrP*a_S21O zI-t=+I4{h*M5%`li7J(P($q^mxN|Ayohh+Mj;&iw z%?0<@S=mEtsfgX6Xe~3BM^0hUURmmDWzlqu2tF^Ilb<+4G!b(YmiJiw)U+O@wht$j-0(`u3fjNKN81nz>OvL|%x|sN&N>+KR{+7eo zw3f-O?x@xtp3j7~dlDKhgYo3c3kalp7W80d9`iGBV}-J5bpBpO&vRR;fVXVI@8&%D z82G4%chK0BWU%h1DBQf(h<3c4@c%LiW6j5X2< zKNpPtabI5q>%Pz!)Gd|3Z;LGsoz#QCKZ(QDeBKZ|-r1CW{AmvA_o>Sq7I_OF9A@7i zB6&Pu6U#Ll4af@5|KryP*9@Y_153t z2ZM`h3n4D96cEBH>>Nd4aoQHy(RR}ykl$%2{8fVqzV%0`uCslFiFYMr_5hPKd)a|B zciN#e=el`{{?kfpJ*(CS#i=_+W%`@*^%%;`b=SI|d(BOY8SZsZu*A;Kb|A|3uq0NW z3-zC7dD^+JF8~}C*KsZ^J~Rr~XH9W(w{?5>;(IAzu%DPnPKf(YVw5rfNLUJCJ1D+? zHhY>oHhRJ$AmG(N|M1^ZHU#k+2>3o*Z2ktMf*J^YI9U932vRHxXuzvsK;q;*#c|tV zB*3ddK;mt(qEB%nqJr;|eWarEI_3*%PW`NQ1f)OSi|76O?QdD`Ssv79`TN{JJEXYu zr_xV%_I3$zq`1Jy=;!hK(hb-dX|pGp=kquY_P*&$_P{)>*kNhO`V`BH!m)6daYMsz z6Urs?+zgaE34e!3Nl@%c$U-A29K&SHCoJ9@ouPz|p{zcsaWAi~lA_m-99z~BKYUdp zg;aHkHpsKnUDQhp*PmC(86iZ|1(?!A8yU=DFb+q88B8Fei>FLoS4_-&T!|Zq(s9nO z#*Bqnu^iXqWuqfB%Cqq14TTINnY?@rX#fvOL`Jx3@*7#WB=jt!D(Bi~E##)5&6uOA1yA!I4F0mc3dM}SAEe8G?XI^% zHMsOc+wNoSf_zQi6hP~;?^_&HeAE@Kvgf-Ghnk{;uXYR*UIIC{;ovuNbNB1JYQnE3f$jZ>ygXdDf9En9NhkOa80D(f@J`dt# z=TCe)`2q5p7+>v)b^mS120Lw4DlWeKL@tY%$kf3^jvY%eqmYK8_#vl?wG`}$@U8H!DbV$8U!EW7WKMX}U;9uS#f}J&0$j#i zN^_^0E6$2Gy1VgV3F3AHjYjx%ltS*|n(Jf|65n~Y#~sfz_N$CUjw|ud8m?C!lsB8? zQkZAhO&>pZf1~|l-zg{2FT)0qHO{*AQvMG5S7ex^*yI=`dABiKs}Q(#f};LFn{%Lgp@DA`fmTmN|D{CLe{M{A0Q*#@H1SYb0%fKlJs5g$lEDgLR5Ckhm46Y- zdpj_709||s0%+m3F;3fU2K3tlB@XtAE-srPtn}UqX*DK>v!ZcwwM{gR!MqfFcxL4f zt57YRIF~kf_TzeD%*uRL0y{pd%Tq(4^QrGKR%=2J)P&waq}0{nAc8XMdMqK?44j$~ zZO@1FXBTcJ^hT4JW8c|aNc89E$|nRg8xtRAK_}x*RWY1K{YYG+jglBwos$|~UvMX$ zF+Ho~7<8d)M&W(URhm(oY{GV5=i;D~$9H*xuI_xu{{2qjMS4D?{`f&WTDWcEw|&Qj z{vlhR&{Cgy5_4!@#)i8O;Ku>8=y9=XG{k+ ze3Q5!`{T>qb>_{849$UcKEU(wG{&2mhTw;+5yT~VMTo;vc%T=XK7FvbwU6`D1m}Fv zY2b4+Ij>{wjQw42`UQrwl4Un$v*6`DVqq~Xx3OZ-vXwGC{>}C=QX=;GR82XWhP=fk z2mRv#YyFAsTWK|AIsbXJPz3c;OS)&Rio~;}Vj>P+y%;k5dN!*J>YIY?2Fo!o=E;zM z#*h%s7D_!@fOtOPk#1&z`Rm$efiQ6x_Bq}2ERH*A*1KFCxX68*-A950QzY@v*(Nv4 z9CbGOx5V5nwYOEZfI4lL)%P%E;?Gl80by(OZW=*@R4twcd3|7lKa7q2UeIiA>}A9W zmbo}~AH3UnajN>0UmfyZg5IiKAmPvNuD9#99};&it*tUNKG7AJ3lZ>0*^tft153{P zB9_dnF6_5nW$?9YUJRhPGc)m;v~xKiPaSO_dVRwk3Pmch-l0cv&k9na#!VW3Kg59i zJc)d~u`S99twxjaa)OYQEQ~BhdQN>_)pBq5(gufiZJnHl?t2)FpCNO#G(o~M_9=EM zNl8$ac(Lg*<@LNT&I-nMqV{Ez7I-pIpm;%r==Oz5FX@xa?(^W#w1#azs`VOfrv(%d z_Wh8S-R_~?KQ}-(mGq&6b~IkNgrKUa%8IFwVgBqwg$mwP zvFm6r_Uv|ncL6v>LbBCt+ZPv}Zaomj7dei6S;3HUgCenN38hM<9cPA!?U`!N<~Pqz zIg_sw4wD`00K{AWmusU*UsxE0Y>T&|gd(zfk8L0z7$)%r&uxZcFLfZ}3IElQNR`0e zQwp>w3_gA!80;JRAQUS^9wXcxhK49(2xKtg^gJYhsNt-6mi=q9UA%_uzKC)$`l7;N zMu4%sfXXEj=k@X%&fIKxR+BL?Rpvq}OHPDS08lMbW6iX8AzpP5VOaiJs0@c`$h7W=Aq1Y`m~%-G{lj>Or`Ei*L9U& zp+A|Yy{CUqi%f5%V)qcpxf+VFAS-37~U&E)yy1gBihquy zSRmH8e>9cM3;(?%mJy>5M~KTU-fj)Y^)tyZxuoohk+W2j`QV4T;8pyE0^V@_aOk#= z_Iia}dpeN<`TG5Hb{izAFA&l%_nsQ-O#ljC(<`5UGK<{_a9@&5ZX&Oiz*7AkgzrI~ z4bNoUb5A}LLkJraa&6Sgju7`1{WE0N@9~}~fGE=T--(bZZKtPwGXHS~Ffb#Fp7SX= zlH6eX{+W->HM3(|D_Pm;pIQP_Td%q)avEO}F*H8@;mDfg#nSKgf9?#QE*>vm_)q4~ zEB_mp`@JRL5WfcjXlS<8w3k!ei^RiMIB)fK*5gsyT102QZcvAr$&-6Hjhv`pGHOsr z3wrzpNG6|Sp+j`L%^kj16%IUQ+0Z#Mn_Df7)VaLHg{HON6hA5sr{A%5Z9gkVRu&0Z z-T;iNN^RK~kYB%J4=P`e3*ht5uY^pA^Wp?dgxX&G3KGEpfY1nHm*!q(JigQKAEj4 zmKsSWv6$HOA&HE%au4djnLcXtb1WpMV%_@-Ht`@Zt2KCyVqFVh7wZVw<1_6VTAAf$ z3sRQ#qmr}*WhLn5A`exRV`r%>iuH9>PPK~1;q9gdqR|-P@N8c>vrw@@BLQa~*L|Gu z_)n*yPmT*<8#I85tL!XC`H-Kyx)$_DM~bwz!3d|qv#5y~PR+0iL6+3K;-T7JcOMgT zN;#+1rli_tpr{(J6^Sp~4>{IcZC{VI`hZtUg#}v$pPTenp%Bht%i~wAmC0IMu&qS4 zoiwxMAq1402%~vtFYp~`JMXRT)H!`oJ&n5_=^yNg31gYDYWL?uAK9)beMM%6Mwjt@ zIhU2vOVZsXw5{n1%jK)6Son+C}&gs^oNWzuU_+Q^F`>!ADl3oFaaah z1gpGIqgbnAgKET%1xNb`6&1i_0v&dG}BNZvr^HLmci|8I2uzlS_$Nwei$xT1-CWx#)QvacYqAA&dY;ctF?fa!h?P9}&sH)>N~LhMG3 z}pMmnnw1S?ouCbhw$EXD35cMhtA?A zuSS`s=-IAMh;StY3;|P(m>3wDh~g`lb6-$e>q=p6%Yo2XS`cY&t%ax@G~7k((A|Ev z?oLN^3^zy9=5@`yVv$oax{>KADrIaOji4P&XjN1$eKv;MT~t5jEq^pIuaqrLc>65Q z4BTe@Q>3c5)WY+Ry}-rk5PH4fAiLsA@)=VbM<+R%?|rA)pEQaODAYBvoo3SibfR4h zvJ0GT`nWL1UV-*gyu8+9a%HVx%$kOFZxBU(o;}xPGB*1PE{bKGAP^r@Vasty<@_^y z#>F`l_wb9vekX*Dj+iMJ4hMvVqGxE6_fwvP5qmUu1-jX^n3=f}=owdAZV$E|#oJCP zwWr@ssqkGrdWrQo?LK+5!tyK>@}!WCwzL>}cDa5Nd0>oRwP1QPJ_eVblXF`rb=#C4 zwIJ{a(r`MT`)vG2 zZsPmfS%7=V($+sT!8`0(azfOXw*@?(Y(&NUlGP;Oys*YeaZ>vsEtB$FqTBR57nAb;6j6;td z?wN7lEze~S%~Bg{Bh1gVTR67x6jk0;Mc1F-=$ysZ$6Ci5i%6oGHzaA|Z~%|zB5K3> zl%C^S{YT}j>I`Kn&1b`8nOJ(b#YfA89X+ zIb8{KwW#9aYB@QCJ|rMZ=Yswz0EYq53A zzTQW=9&42lu@Qrf{O&4cs-4=RHH3^pK~XSFs%C~s<=cHPj7&3IzNoMb&S}YoRo%VV$;TBF)frdZ!=OrN z(_2cnfi#`wm$d7y*1bI0bgLs~{*XZV;?(gI2l2~XZr4A3|0U*lGr&IgV^Glt-9{n8&!s z#*du`g^%kFu2jWNeUDhzNam%K=0jn~2hP4`^grS=hZIu2UNaL_Gn*B&An;sazyd%9 ze@1_h^*2)Hf3MCL;RIs}c8vI}tEn37k6%>HGfgIQKCk++Ue#%NS{mhR8dS zChR*Vx3fg<@<$hyX&NZd=PvH9clI@IijK6?d&LU70U=po^3I{m=6zx%4P7!G3`wPg z1?@jNrV)x`r7qpuX~ra69Q$H%U9Yr$Bof*`VU4dRnH1~xCo8mMk7}?(6tIIK$?pdG zEv|gxk(%1t_ase4#h*Q;T00SlQk3nj5%xLo z__x2r6}u5qf{YQlR5XAsYO-JI7%Tm|u4;-2&DXA~(qE4FtFB45lO@fnwN-CT4+$EZ z%NbPFWsaYGFSlzGNPhTIIva|d-?JYUeoJz{M1GXU8OM`}B*2J3(lOc=a|iy`^F5H`~iI+x6JI z7EyaVGJj!dCv~o$N=q_q;i1tckjv=};;E493~#FAMg{z=3*2_vxa^t*fwHz+!Y6sJ zgmW*QKRH&5Yg{J9ZzVbuoIN$7&-6j|3j6^0sX)MXOE7Gp>XAmMI?lEmxqFD-_1|Z|xliJ--Z(ngc}#So0ZP%_4xyTTqi>kIC#e z*bXA?4bNDk5{HHB_f!9cFrZT=M+OSi7B+y2i&MrYvO=WQZiPUwEyzm~6=9)LEE+Zc zS1?mwOrF^XEFcwzfgztS$VMd^DK~}Mo<9bVXQTA<_f*lrypT(<#zbFZWp1)EJ{nqE zD-I9mQc^NvVxl`a(WRm8($M^sw_0+bkD*d{hx&Wu_XR$UYktc@R{^fP` za}i8-iLrf;JqpdKJ8_tNJ!>uavXYUmPWiPgM=19(O;rkfR=<8Ci z{W~{oyYE+F03Z>2ek_TCoW71|DsBAmkdSaREc}|3U>~2v zB`_)~F>A{M3W`=z60NMPt-M^PAb&r<*v0u=`+ej5oMjtY7p$oht!K^^CBHF3jF$IL zgjB7TO25?oeKaLtDB@wJ3gS)$XAh`kPSzjE@LILTzfOKpN$T_1D$JrNLP2>iY>}!wD|5p6!5>FHy$tqCa z2SpPHj+*7?=EV-8UCJuwFyurkYNSCEk}S#7HpfLj6D9&*%&I^+9I>$za}TdGUi9b7c;k=1=xG z=2P|@=2ynJ=3DI0%)T8!<^%R@<_AZVb45%Zy`-PudrZSgaCzl}zY8JRov8Db>Uv3{!1Z=2BN`65VQ{E=j6{wYPT6)BAT zlcWj$DP*n6RB8FiNPYpTGBKdlIXBQvr1PbklZ4e$yDHUY^=x(8SY)DstTIXdtclC0 zv{qJzX3f!Z8@vvvO+*~NyvAkvE5cl@I%aS;+dGyfu{>AZYEMde17|4yFWo|N9B9?Kn6sK7dk=9(7Zh4~|za=i+2~^h$dA`-L%HtoF z0j@Fc!&=8+^7`N^UIaWANTfHAQz~Z_N-m>WE@hR<;zWb}(O|ZyC=iiig@-4%*~ppC z2bM^!f$*HCgT(t`h~u2Gn}%?qOywnP0dN6C;z9yInEDcSQEAM??91j8wTQ zNvLK{TDJ2)42s?hJ~)^Rx4f3f2iU8~C)qoSkR7CGoRQkD$o^JUL(2kKCC9<6;n=+q zPduq9Ma_PFO4xU_`RkP(hPl^)u-yNw8=c?tVd(;#-?6BW^~*;mkKK=7{C|bNr*zuuTTcB8&Al7 zQ2n-ad4m{077??DVE0NY7USIR$Zi0#K4cImW!0#I)_Kax|$n4#SjZ7SRI4P4&TZcSYXZ z=R{cQf2!K+=aDlw>W%gSx?A)lh_KujS&#~@tKEHYOtOJ3)y$V-(MlKVi`qr#3FvMj z@;g}>^;6ZeD_E^zbs6BY0@?Vpe#g=6;B#r&I8G|jt+5ojN26fp-zusHw1din?e291 zbr)0N77A^;-MUB%?Abb&yT_y875FOZ3y!9mOW$S3C>u|heBG+2jdv%51zRKJFmDi= zeMuy83CN3it@lr=nLap5h9Jvs(3~h6aie5-hVbV6^s>h^kK{kAdV|Ny_I}m%$omXB zPZmfgiU&s<^Y4aBE!zyZLuY-# z04cCmwFUGGk~)whZ>3R^<5GJY3gWBBiL)X{phTOdBnga79E^{r6T#gVKW_R3?6A^9 zoW~l39JXNx(zlV!e+rB(hs4N}wkuZosQGt3I)bXo83*_U*SU_tIH`7A)}dQb|P^Z}$Z zAl>jOz4A%)O;RhSF{Mrg{&P)H3v5)ZsqxR$nb6@0$*8<;FVMsC35ei1>@Fp1w0~W4^nnbG zm*(LMBfP|-a=Hwo7z#*^#x0aqnQgBYgS-yvVUjR< z5XdX99*V7vykyt#@ZH-~@rBn||4G4Hu_veW+q0C;%b;YbK(cV_pGLQ2A1T zLHG-)jP!*UhVjlWZ(}T<*FpH8$b(h2T<1NaJB<(-1blBVG^j-r|7qott8cSG%zKT! z&J|e1pDm!9S3^F@zl{*c&ts>$_!)cK;*|%05%w#C1=hOXSmh}!ERi=au81!nES*;` zp3HxUkRCuvI17>y)d!kUF$7C9`|!AFci(+rbE@7Pv1--B%eK;5-DvHpwHCn7wXYiB zT4)U%-gDO6ildC<2e>wLp-{glg3TmBtO*S-Br(E-C%#=Y`U7ly5Q;lS2tM{uCTUPW zvp3hK8dl{fm)@!>8a3powO2 z9<2p_7P}2c|Ms$X+MZ6FftLpKli)Su7M@}l6G$UJgow4oKEU8?oLTa{$L=R@;+5to z{@Kf}IGM|?P>UpSdjPXZYkw_Sxow{MNl|l2?0FR6d#ASXejriXRZwyulk2_Xb^ZXl zTZ(>Q_hW#}C(C5(H^M%sVao2t#Ye-qH_%k&-&bVQKKAv!0Np=o(n__c4yZN@Hp-$c zR))362y83+0lt;d0N3`tHirX^WaaxlNAQ-&RmXh=N^cANBk`1 z49}cuDaX@%mTqRA<8@Ptrd#%~AO)@KLDH#L$;}6mqyHBI;W?PFv6q5Fy9<)8G=zyvh3c4;#v&cf9Lt zjMj99Ju2!n6aonnkR*{4usEENNdlTY7avSHi$x2bK=8v#5}iNhHANCkdOxoGi}??U z8iO_GM2+bXjIwf~s&X27XA0=Dj4;@e95q-S=^zj$X&T_wlB9+3gbZ^92OtHu`+@J~ z)IHo>amt#uMX{C*k^xOvFSZ6Uy`lhmlxzef#L`Pz#d7~!(MT}l zlf(Tqo380J)cLKTETGfA9nc9;F8CL@AJ-d)$2_!Ku1f*h=VQtZ34v_iL#~_4FX{nU zRqzI|s!*4IbJ#54qg-Hh?i+#xNe4Fgh=D`i{0$~#RcOk zH`YhgLOR9?8fhc$eOPPGnlBF<{`e2x@9xJ}YnnbOwd@)!YAZV@>a6xRyvnOPcBAT_ ze+{l(mY+Ozjs`XUjM7U;LKKD!H3$`o6^Avd$=NJ6R6`shO)%JH$!DQaKEHiSh_ z$T`}BkddjAl4KPX7!;JadYEOWYFfc8X4}rroC`}&P4(w=@&$24B4FgJ(DQ`D10<7y zk|~(P+a2SeP{1mcAytbfAeJk5lnX=Tt2JYn%83$)*fM*sU1u)qzCC5h(BO+e1+)#) zSOe{a6gbgCq7J1Y1=%GS3&|0fr?U*?)mLa^22VXgK?C@a2}r_~Q~pv!D5{7oFq?G5 zSfd-4P;50U<#mvYt0V&e00$!?AV$;^3(6-+n!;3DG`Q$A8I0{~M_Eju2v(UmY__nE zDi9Vsuc};lu&ST~#0BD`1{%{x3Bhwj9577DV$UGPwnp;T5h7lb#G@NG_#i_iN;c<; z7A~B_(xX$8E()MVPMdN~?ccR&i@9_2=H6!U=OIJsAcbckN9v@CXC+8($Bk!+y4G0p z))+2)B;PnHQ>v`$dIgCVmM&kok{Npc1w~p~ZReC*8r2Vk)dJ`v=F8yLm7zC*9xc+R z1(!lVT_OAn6;7pSTyHq+Z*QN{H<&2QU#A?7s3@7NSt5-Ac|1X*hthH@DBJ`DIgZQN z5H6Ygq98AwU%<&P#8jpz5*%~$R^e)?hw!B()SpfdPwbDsPfraeP)AOQH;C?#6^Abz zM~ooCFy90e(qCUC7^5`#NDCRrso?BEGK(OOkx?5ahZ;H7+(D?{n2*!he&xzOmo4k1 zO{=iQhp*q3mj@~+C<+0sMNTM4PH7pRh92M6HjIck1mI7?j}Hl9Oo1*96`&6GH=$qO zwtwH12;P<`{v}WTCU5>lQnG`J#3Z+gxiBi~yP+ZD=;*1@`J*3>^y^Ga$M*p#I``Xp zi_Z6cq1M-B+s^lK;?~z~5bvk%OwKRkPVI-!2Hpl5e?elihFYExOI@+N1mA^OIWK&L zuxWl>L+2?aKeh_(2)+0jDZ!wbc79Bn{8}xUKt0QYH72jv=-Z?)W*$Cumbo*XMqAl?SrKD6Cx%ONK6x+MO{&L}at~M4^MJ{l66^7yz4m^qE1`xbnL_P@%%JRlToEs8Mr~ zIt`awQ+&)I*Lrs^pr!rxjLy;_lbfDfE; zum>qf?to_}^DTSzen+8rPo-LDP3X`7fa{@a2LLy|I$Vu?b?D2qNF89Yxc6YSp=-d0 z%w^orH7uffc(I`y0DQy?ku!3QKRrF6uZ|59*Yr5uGYZ{f0N^W2XKBD!&3b69O_pu8 z)o0sm_t6eJJY{b?PhCU1>|t)NeRepo4xGOnbkMgxRKFlt3t8H@(6$79G4gwbYvc2p)zP})?~bTFEK1+2HjXJ6>3 zqi}5}>|!vwL{}AzXQICwjAx_jf-$iAi(|ZC!%0a|tyYYTG`n_Hd-h~wV`=T%_x`X@ z7e$_`$^}3wgpv`Gg|SRRBv2}yG1;0XQP;T*LlWoGOjC*wax6=@ZM*I`%B3{XbxrU* z9oP>5`asY&2$BfHh7p7@ikib>mOr-O&idcx9b=t!Zdh-<(>B=Prj0hbVv|j7*=(B& zjydkOv(9<#f(u^h>Whlc7(*}3<)!QEMm*x?c9NIZIevcE02_Gn*)TX}lLapgh9-lT z0mE1?w;3)jbMpi{4u*9uZtEDQuP*hJeUco85Zf;$JoT=2PDB1ZA>Q^Z}oqE)DXSz-yo z3M-KI+Pj7S6?cb;Q*XVw%rp~hx#cL|Z@-`X5uFnPI}krA-ti%RJUQcuC$4(xsZ*YL z=Dg>gZ`c2o^I($FO?N;K5PaU2;_KkPM)6%RpP+mb0tZm_32r$K=Z3%uj=&JOz_BSI za03W04`l=vLov26ib9J{wUII-6jg>{C^)W$Ak>qjCQ2h*-Cn*7gTHCIY+0^)=%wo{ zp}X$F^~kWQL8i*L*D}jhSYf4iR$1eVwbp4}>urhHU;|$pZPL|dTMV+*Uj7O_GSOp? z?PB%^!K2Lg$8V?fC&mBc`|~_wZ1cqz3MEQx_tjTB*EhQ#;k)k~e)u89Pd~Z*@=Kah zrLQIao99dhLUJ)o9zHk#3|(oT??WqC*A57UNYvf8|3Xb{a5IW-O`l<;VzF2v@#j*h zv$Bz*+@Wc;3`2osiE*4nsqLq*mGL;tkQYTtl4Smu-DgZu)T^rT?!J{7+fB$#2N^TYnJW ze-!mPeD|lwckq3p4u|g>3!RcHKlU42!vJD0uoB|G~U zwV|(XCI1AjWkZyH6t9+GgF?QaVvxWFP`qX@4J{h=fCs*%6O+?!cUZvu{a* z#1!?4(IN+j6Wn~?>T`mfN*yPBq$$O^7)3H6w))e?IZX?s`+RYFq`yTP1>Oh_EPBxda*|XXu$Y zmrAkIpBb5-%2O;cu{7%?W6m7?0+$n;r~2Q}g=yY)A*&QT&dD?Bsj&q6(hL{}x9@8o3T;)yVC^J z%u}H)#aPhb(k83u{rfvwQ5@pf5Sp^FNB|DQrMMI#m%I>JfbRu1+GwXoop*d(v!-K@ znm?<*$G=zp;>FmZ$chP&MA3C;|K3;AeS5i9Y@9$6#n%#_f->`+2LM47-r6O*e7Ib$ z+i$zyVp^-UUC`)IY`TEMj!$WdCnLz?z!Z1L6@g( zH1KBq$r`O=H_$n}R5dR3&ts)THokAmaEhTCXQ_#nYm`-t$OZ2H$-b}h;6+=+OynvO zdn+L&0g5Br^IE$!rqqqwi`t4?c_*CG{&rkCdM*fG`)qP9jVpXK^lSmzZiLWGlswTb z^r=0S7W~uu{y8u}x-yC2{5DI@*TryEnN1M$&1%8OqgN1o#W#f+${yGCUmf9O0HT`- z90&-s%>Mvt3X!Hr0D?A3AOJELSv)mT8OI(XhG;p(xGKS0Mjri9(4p{wJ^R{ZW>t_X z&;PJnfmHC=(U@fp7GKH;;wEhtsX)AWJvdh;r8u113Qd9-1okgkvQ2`s2bxuGhynnk z$+-gX!XMa(O|T>ZJ~mRk`VeNh&Vb>M@lUlY72$jUShWf@4LOp}v34xt$Pm@c8L?4X zVWUx#FwlU64FDF@jhMuMJ>cZtUBcR$IJA7~lt@T6P5nt0OJH-YXsB5txgW&ri z=o})RCWRJK2TOy$FV$1W$<@przBH+NZw?879BwikRL~KjI8uLYb*-c-lD8rlfEKP& z5Y;f5gv}Zfj3U*x%Te-or3LGIKi9e(PO1e_h|YUAA7Qp{GDYl8dvnjyU9**6H~E^6 ze)Zsd;GXJ}ajzzItkU*V*jrOmF5FlV8^Ih>*F;r3Zc)r1C8MSmVRyQw$R|xMb*eag z2wH1P@`FH^K6U#`>FTraA1#Z_LUEWQ+PAa+u(80ZilJo0^{~g#y#MPlTm1_I91Abw zVLwO`uRkUSyMg%b5oP`kVyxav%f!+0Z-2UE@*2&GiUlN}5&779gjP7p^b*EV!=)=w zeAT`toMLTYGCzHqqiV?vWMQR{8z)OkY>LtpEz=DNjXrn}dEJZ)YM!iEf4w6Xfz1KJE-kZaPq11G(Z+3B z+FUcbm5a11K-;#DYVJ*4-SGK%X&akjNxn8l&3#$ZjIox;v>Pjq*R~>5{?a3jCepdq zH=tSiXsb46+m!a_1D-zHTIIU$rb7j-H3O-) zt!f{hkP?h!#}CKCVLxI^(M~8puWLyN*<;n`Lbh|)_6473OY%5K(VIV0#vW*EAVnj>_QuCcTa~O2juCxC(^%~)UmS%b8k3)tzi#U= z+W?$PF}B$r2<&&qrBQ}u#9D}!V7Ga44~fXy^m*KWNncZOYA&~YLziiINsp{)0Uy7r?i#yRtlXT>`CBa(kr z53g%^A^DJNnUpi~7g?q{8b+ zc~~|^KH(g@-K2=*F}0aYb&=`$aDiSH4$ZGO6A^OPg|!)trgF^Nf#!qBNXA>n{P$9^ zvGQ6i8B|dair^iPLJirvrYI=1X6-X90s{|v$!w%+82Q^-r7b*u5ESnGl2Q3-Lslpk z5S}^j$b=OXh&v&9F6-rKhwz}QIt(YlPff~Hq8R%%R|a$wk~fmF696)}hL5R`+?Vvc zZa9RjtJM}6wBibHcqaqGOqlH`1!4PcOS{DJJM<>35Kx}5A0t{E`Ra!hy<2B}oP6ip zfm}ZMJ)n<6ica;XI5UH!Hj`$+HKXjHK+^|#F_JP!zzEZ+ZW~E?F>$G-^)r71-UcIa zQtD(y<}f)RV<{Szi;$4s1poU0LE%||=G97jJam$Tb0a*E3?K~9=K--;4PZ2h?#BHH8@{L&Hul9Dm;WmR3kP8%@y)`5uMyOvE;`d00z zC2;3CMz)0Xx^jW31~!mM^xTB(^BZl_tN=wXJx?&c5$2&c!I1WOa)wmlAc@`Do|U4ih#Q6!8_hVJ=$;}CY^C)o<|tTz)XI@nbXXO&NlES86SUQvo{g5yhe>VH*44> zqvvaRviKm{jZ=M5raG7=TD?7eFTG6Qc?77yXVPQ!)j+8F*W%$0co~G-C?xBZR&R8N z`>Y=GovE!y^o;k^f;O(`mql4I_x$!?5$W9XPXOaMKgUaaAadTmD)I2%rU|d&CS;DriNy0um>zsQY$SFdrh59Q_LmjJ zRU3e@R?1N?4ePJ(lIO*Bu*fs zQVwD|1*HwG;5n`SDiUyL9$}dHy^p0*QfLyV4A8^BWZ(JlME;xtng7NL?zda3YXf=r zf=70NCzOp?wQP{K{s)N0a3h+Eygn>8O9lB#Q1yj&is(q4g z#UWuNwO&Or+UIPAW1Psfc|`d8Tr%lRDMMFrdx;Sj(OZ}~Ka88`(ld<=#i6wpd(Fz# z)?QR$`M3gll4HgNSA0Yldh>Awct|G-sUyGS#Fz!a3<(7`kCN-fTo~%kqW8fo9`xU> zDrKAW;9J=%q7l(U|CZ>Ql}tj#O7I|EaH9d0t^8Wf3Q6J?CVjgJ<}xx%l#2F>rz%x& zCx724zSVG3k!0Q$LKianC+~$A&{q<&1z4r+`OD3&=N?P6*nMDpQKn zgIdB5z}E}!%Xh2Gr1}UM$JkQ)j^7~MONVdG$WX>353Vg00osk56!E387j#!lgt`$q zO4yqstOcqdXZQGFGf5(Vyr9tWN)1cTyR7YLRW#A{AGLQ|3siGLHZm4HVT8=2A>=i# zuF?}i9>|jgJ=>%c1?nSmwW3AdV0$;i5n)UC4Qo)N3D{4JnF?blG-$|~22eL-sj(o( zIfBpRNFqLxoSd2C6McHD&rWycRGBBLsBywvKWPWG90fX6X!VbmtuDoMri4wtc9D>~ ziDsfQMDQ+qPv^dw=4%B|^R-%XlaPlxh?i0A>s_uw6vFc21~SMrANn^T-?*7)>Bw7Z z^Ou2epVG&4*YB3Gko zQo2*rnNY?|S64JPdlB8R5W~(h=K4-g>X#v{{wd(F0b|wJ0dQf+*TW#afOAo8B{QJN zn-c@;sfpYfP&(UEUPmqWM3hS8wAgE|}D0)TX1!oizO#rhxfayh}B5XM38tE4}XRV*(@>sOx4EI0g5aPjb%(%2}QGd9JZ z2f>8UFNpsF9q6zS!fMhkaaOd2~uMBp{65#EL+)cj?m20eJ&LSv1vz|fayt*IyM z$^Z&isHp)Qv-CpzCX^M!Xx31`G}hF%QK$IL`sh2I7ZRNYl%*rgjr8y~R$lT-?n8~$ z*pE<92}~HR*J9y!Mk_%+g667&P@Yjc?;I!!h!%onObG;BYJv*`YgRi>b1t)?eJ=a$ zsN&#{$sh4X(tdID1&$`5cw~6hS~9Yr`Q|>a%=u|(-VVP}2->;k(Jl?0fZh*mI+wKr zYnF^myDcfC@AF9NU`#ziieQ34j=9(~)E`LRJAb>)MGh7RH-9-uomd3qq z%VaC$=DkSL#gz%%y;<_7GM^Wp82#ZLn$m~kd4)J`s7C)U2^xF!BqPf@ ziumn*B#w*C@3RBK25i3`u+I(5_5{LzX3c=(-YT687C zvk%}#SR*~Lz%>r=hy>IfCy6BN);}}H>EQQQ<0lehFDGO0 zx$#p*Yg$EvT!(fcVm&$rLG0Tg*$W8!G?EB9)$8TUr34a9MTMpn?CYC7>k(RLgx1kz z6_^&vO_wzKXQxIA(5JW`)==cb3VI29JUf=oB#apO(^?JdA_cVI$53KL-$cX-481uW zd}n;Z0ALB|I#^oOGR%3U=k?;W-U@jniL4%5H5@mO_Y#``}LupjcL z&>hd720xHqH&{Di9tvV#RKYNk_R}>|3kJskBNYHm3dv@uv2O$gjR**G)c3PGsTErS zeXP%@|0z{yrG} zK1H5JgFoOpnIZk+aG{Kvn|96QP;A8$V?g^>(M?Qp|sx;>)PGdVRsbQy5! zYtP0T5Zo9Yr5dT!QE!ii06iPsdF&Y$YM;7&f{ivWxi_d2r@*GbTAA!Uw{sSxOhiEh;kLuhw9+J(Kc(YXpTna&Oglbar z>a<0*HmP2T`L;}B@jQI+=VsN|mQnfPM3n&)*RC$htR;0LKv4y54vuW9fOqqj?A8qu zRU*X}35pz~i9#kJFFz~>j96(oOvdb*PXRiM0JBQ5vdY_96ZF1sb=Ls6%{>EKRzL1C zBiDi!1Vc@AanGk#@VYFT53sAlQI+bmb2hPCFuP6DJ0>|nn3qN_VlBOU#j_)}WV#$C z_LC3Jotv5v-bxB7T5|;^7)u13P~Mvo3O+G&xx=SGSJ9S$L-V7cGovIQ37_QEPGr>v zMcRV(Vo7qv`Kd0F>iYa~{@4T>4cGW%<@AUL^OfK{X%RTSop-o}8UkE@uf6*i-F`~$ zKX?1HPcxjEiAp#~G^fgz)m;^=twiahL6b1Ngb;RfConwASA z{wgP$AjO>stGl@YN=6O~Wi;P^hilr?Qb)F#r;zwTL(Xhq~OBqHqHg zfcB#p3kT13W}0_OxzM7Bdz1~D0OtNukF~rF5}^+?l_p=h0al%CQSt)#ca=_0uPa%L z>{f>Wc>@OHv^CTgX7u-ty_G4=okPGQ}9c4TsdYvcb3GX-@D_dSo5x8)JMkQlhQ8!~!X5;p?M4lE7yPzvw`G z)(FMM5QxUFN(8Tty)(cFHmq&ZyHyE56PR2e6i4RY3-y&m1vfm-BCkI$f)ZlN>5l_)OS=>{LwgtH}X$`!?Nos9hGky$0Hi+ z($vQNV;&{>Oo)Kr7C$lxrfL@A?JIe#~h@8fTLHb@IWsH?CkLeW8__#bfT;P7Oi|$js9NWvdhz#Jl$8 zfC>W7(1qH5!)n8B)!J`ZsbkBR(J7>jtp4$ctOje5F9ZW5Wi_0rK%izfrBQ~-{7Pho z<9Y<3*f*pd5Tx~o4jC#6cz3LJzn>}%2ooS*E*5F19$G^FmsGBYsMw4^N(zDwKCB7P z4g+y1FreX8%P)Iu=W~-YKA}QqNj>C2&DDU0mCLxGp5&o42f|F+2=QpsdW72C0bPlV zliYZdZ-hkH?-K}hp80YjLQ|WU=mm`w;E{WN20teZbg=#Z{2cM>b8dr8$=aK=f-ahgtEMi z^b@AsGB-GLE`=SGrttz@v;VE#vCxRsk{aTGDauSOH7mYe@|icoajEQzX~=2J{c+G8 z7f{YDrf|(O$*>U2(Qt5RCpT?w1S#}fZ5yi3PLJtk-WmqHi^YRa`-C*$3-~H{x(+q) z9`ro1Y43m`7ZX7iZWPxhq{Vh{7(_^VF%G!7{&<0x5zSnP-xjXqwWYzN&;_87B89xm zsNg4X<^P|1GcEWedkx5)g>J=FVt9+-RZrw|xdX>@o_@ZUBUi!7w{Fgp6PjhpJ;jl< zAC}ksttT!gA5qVxO&GfN&-rc-3cByX$Q5tSbmy_`J(ZWTm&Dab{s3f=E!BJzHRwbB zuf4bmKE>gjb&Y+}6fZ1UPM&Y(vxx-&swBQlT{~UOb2}@i4h`#DO~Af8vS2hE#)@sl zvA#R&HnM5AZUOUgM=NU3$QCO(!VD%e@I2R$Bg@}H&gHTvws&slhq>u+u7{PLR-$L( z&QAC3h{AM|uDO&ThKBEwz|WtXCg__w#x}+W*rTNH0<#=-O-d#V9_o~-TBK{FGUG)S z$v03&`sH;SxLtvb@w60kc{Ya9-bTt`bHPg9%+ZqAr;a_FKh(8JrFE_ zXT(D2LfMkM5P1hf+DzSAbU`x7{m<{^m1?PiMH0mNYqhpyy^C|Nafy2h=JB?;yu7cm zS?v-OZ_&WAvrc__WiegKszX!X6BQ3fqTU;%TNJzOik@@G$P3qfmINb)W%kmz9sFxV z&;huHs^}2J?!vjc=*k_}9&30F+{`oS3o_Q}AG5P@Y|?xCUVdx({P-3|(|7wB|G9aH z2GAgbG7Ve%B!p%egtuex_3XCVBvU`Zsw>4OFAgcDB(Y(2wFy$}Hvv2V!d+>*k%_V- ztM6+Z8bBa-+*Lr}VWrkgW|zP^(Hk=ZJiwY*p(QSNGoeEYt24p+618fS8hkhAXcw3I zhdNw<_b;i@wD|9X7-9e3V*)Pe33@rO%3q3xx0CgB*}?Zr!PeqyxU=OsR_LP!Ua5uCw(%6qQPu~+t!$ICui>y~wB#jc zvjC}>j+edcc-R|V7ix^uyJ>omYIOJ5?>;2xYRZ`fYO;MPyrag4b3`_5)~m7X6%zf1 z1(?X%iVW?)%1ha0$8O1jKlbV>0pS`x&Z5B5-?1(Ov+R-BI~IcqZ+w9u*BTKN%r5D{ z1CnJr^8VtZD3QZN^+`onS7_|#8a#KQbFV(pr`p%z%v|4##rWpT99uo}v*4PC=`Jg- z&4gg;gI+6s_rI6z9~t1B29i_}r2$8F_$ z==I_MO-XMkr}Vw<dnchMu+B37{U{ByUvuyP{YnqNKCk#Jm9QTR=OQNw!e;8&BVPwJ z(vYaYHR7FP>nn2XYxG1C$L+sFsLf=?lk0OmZjZ}>yeIOz$3Nn*=abhk{{nfO#~=C( zrk-M64v1#*Q+O!L9~OMHEFM7%vR7oIX>y}ryqcGQnJv!r&gqo_)ZA`&Yv4_vV1-P1 zhVp1uN`;kNfqTigi8>#+s0gjjgIV%GGmbRMIEJ(td!tBb#ghCJ9!g*sCe`ick{ex$9Vbq5x@Nox|5 zbMthUuMX$+6nU{yulUp53FSZhiHd9rt>LfA@ySd+A&nfR(ZMSu5CVlh_!4g;+h9;YC9QihbMmo0gns><^#v% z``fSv6((;*e#l)pq1+2-$sD_a?lbme2aIi4tNx33v08Bdu(Bx;M&7=FhTCI)%6}U? z@+ojbG+ACJlfEylcs9l4IWKvC_koDt%wynXXLM`O0q8Mw@a^LzkxCr)&dp@h4>C#O zPa<6n&!%HTmA<%=8I4VHQ&=9*P;pO`2Ne19*-ae1k`-ax(L54l8G90Y9<*Vyh%X9} z}yL#U+u!Pnr2>5I=LLHWb>KL zj+&Gp?77_zN|%DfnGPMO?0$ES7EY+D=q#Y)>f6>wDM1fnmAvju17Qo9@;7RM$$lwH z4xj*NH8)T0`}8|o|CO5kqs@U#9Ml*U@fQ1#!if@1c2^6f50Bw>)C=T{SpZ^BD!EH^YGK4?pqpz;_b_WkEt5==}+u>uKq~c^7k01Tx z1R0h=`MW<}H3S*`rgqt!lU55A&8H7iD}61XK@0dv)099KzmngCnG>OJy5QoL+_I{| z6l7AZ@BjWPnZV-5hH+g}6hx7#QnD&!mm>E76^&T{j#okgNKAP{Ko6p{M}?Py?2B?D zOj)fyXS7W}8#M~RdLO?0JwR`CFJvgV|82ly(|4>^Vow=(+B;iano{)1z4IlN zm@35Gn%4;IUAa75i!?oGNKzCb)?m(s!y#8g&k`(F403*)u8Kz1Nfw^2HVNWZEy&b@ z_RO}uhV$lOI^kA~wD$4n4P9#qpNg-14ncFj@(#c!WuwO?Q7w);IpslK)_g25Yp-0- z^j7#LNQ6N{7WSYjZPmLl751l;w!fHShri4wk{}Xf9PM?<*Aw-iPm;iaYPt(~{h67% zNsK3^#=cz&ePJRgp=arroUm$Y3IxV}k*wD$Y}K&d^3DH&S2R~Xc86aMa*g-K2hoF<| z91u1$O=E~x-kbiV3~*g^wdPWH&8Ip(u5^c$UDPh6Y2<_l+4vV>R=zUd|RuzOE}8&~!d3 zT-;1*tgI5keZzheA1=Bo#)N%{tM{Va2JwK<%qOnvUav(`|~1Rx)4Vs3+F)P)@7*>f1ZJbxCNFd$*XRI?r%tsr0$;7L*pdbwtgmLI}aTID(1W<35;JW+kpbjV2t+h znuUXf4{kYEa&CztZ^w6e6N{m%ln&&!)E>c498Vk}oQ%Vk<&bS3$mVsy?6h%^ zfL2}vVdC!w@5Qc2?fVDHuXR54ETov@EW}fq&3WPi6H*YX^VG}Tk{!>Aa?iudTf9}~ z+0$uBlF6FxY+QQXDFM0JJc^3SSTsMX z1!re&)}-0-=%Xp!`|qP&-TjzuKk1>V(^OPy;kBNJrWc97>^ypq$(`_XIi`QJ%W5U`t#$d6+F zMw*}%NEI30VS4^&YhBI9bjpLDuA%^VYe$h$JrqbyvO$<=>Dk`0ffUHfpjN`VS)oMas2e*u7#n4hh7X$wu8}16^yOH&0<9Se* z>3oOA^9K%xcmVbgfAOHH`G+g_Bg==Z?5yO0EAS|9hUGMKOCJPTE|;ai#3Jf}*J`E= zXuHN%{n*q#uIxVjfcxUQp6my)c%T1yBpg1lHFVMTv%GGr{`De%pZK55O_x7*Smq9s z(oEdU!T zYYtJ|YRd!p#uQb3FFJZPTQ^)$Q~yZ*qQV#tjXof(n(y6Zyg}%4vgo}A5b}NPV6dLE z70)DOR7~vO&X3fLx)@SfL*c`wYf_jdByZ$N{vlEh&_C}5`7z;by(ysGncKPY0y^`2 z>F1o?O@vbg`SpJ2?VdzR_dR!AFG;3Z%8VS`3H3mm)AO1v+_wyC1g_neW_qpP!p>(! znHGG_#D{xLU`kaIuEp><^>Q|KfhebzjT-xs@9!BTH0pH_{IcZ9l!h5l*KvmZ>$ z%pnCM+Vd%5N5MJWE}jG=<8%PqAjxRigH!)>vwx260(uRgg=Q@AT!Hp&@OA(+eEKjR zF;O#9O3`6hC5x0P1`M?hMM(?yuVv4;FzsMX(u-+KVDd=f(F2R?7_h16nV>+`3jYaRg{LG`5vn*Zm3(tn|f|vHRmni57Dlu%lVcZ&1(Ga z5ZzmZ$5z|%^6BT3pip4(77azg`U=~s*uOnI`01Zbc|^k^t7wl0Kg@xo_c)B3(aCKL z!r6OqA>9e-u2X++0o%Nt^V?iRv>ZPAgFoP^w5Pg2k*pOaOH`RcK3zAUw|a(GqPz<@ zRHbaKe%4auN4C|Kf6pr+fU)Da_~Pv+b^HX~$EzDqwCkPoDZ3Nf{3S~Qu0^#@I?8&k zyX99Cd4cxsi9t$AdOzOcEy+3m&xPU-8~6`~HWVjN@1=ZlnZHx~IoeG5m;BS0$V!z16@dsd6wn{6IE8(T-?Rro?f zQxY-4^2WqB`5qP&ePBdClrVW`ZSw`ze^UFumzCh>Lm&?ojv2 zn>vt~)Ixn|4$#9FugbI@+B!hHZtv3AGT~_GxIA0~%qrmsxaotNuTJd1kZru~2khHu zz}a->sYnG{e!x%-0G0tJAi&!45}y@C3=j_mY#-Vch2CrK;PIKXt=@S1;rA_9F9e7{>@{8VO4^^s zx(U`WBinezl!6t;t1;F-FxQ5JlUR}@B@~l#&o%@mlK{_@%W&g4F6>k?!B|KMX`e6M zw+-`2>MB%^Dn!~T+J1Xk`C<58jW=k(cRG59qPU&+xFv%qVJ(ykF%aT?vh4T9f1r#s@LsV6*T*;T!65To;X%!*sEHn0|*M5#AM`_homH@Rw8-y5;g_MWAd27WD(3R@UfwP@cY6% zgwrDQ5rx%$xG;Z;VW~41h=Yzj*}+9D@>TS8)}aFPgd8zeT#YMND0pOo6K9gE&`Cf9 zaB2iCTz?0bcr_{Lv?m4@2Soyz|pYp8KgD0zCX;chDtm0tDBq9AsG?*|Snjexz`u^Rv!8oOdV;dS` z7q1(WzvqbOp+j+pUv2AL_)Yf`(*=^JF?%_rXs?>U5dC3nc@F_^(+=G9&Y3aVtdycN z2O^zAwFn2Pil|37tmdi2*dGNx!~SWfUJSSlfI&!xYATrKPA<&Falq&bSatN-?N`=I44^~l!&cMKmc7bv35l?{)-24-~|^)SxM z$S?@kouwg!l$2=8gAax$DqcvHtj!M+i44L?z0eS5x5;wGfBI?2=Om@*xQNp^Gf^9u z$rJ&Yl}L$TC(TXR%dbcgXSUP+HbuFpj=a*;9uVQOlTLf@*nR&CNrQu0@lC1WDW%O` zntR9g$~iip;=f*}LPK&S%TC@1AW&pjzdX&^WB-oZ{&(jjIWcoECW_M+k_+gU1j)^< zFYLrx0D4?O=@+)ViBg?ZCSV= zw*wNh2P6~$8cq(@`e#a)>A&ZNM%QtOWMI^&^&pUOrT~d8f|W{D6Q{JkC7hU-)8cT; zIVqk3C`(%H!QfeuV*gD4!`lwqp4Rg+GH1_k8-3I)Q(GdZHH=5(kpEvs$IdKcn%8Cq ziNvK>MgL3j1Lz-&wmbz&Dw*>iY5dwpX-VdI9&asOJe<_Uk=W=d=5MtRpHw{Vwu~o^ z*_WaRUNgmJN6wi4ye?&B!qJSF^1HG~3)HN=iG+Aibip}gn>${UqPly#US zDj*iTdMqLq0maFEjs_&1FRTa{no1ZHF^D|e$}kawQQm1g@O6TY6voBk8Mi())S>~R z1JazS3N|gsv&TDJIv#BBa~VV++VgMu&z_C)=VL|OOufCqP0&C9X!P_S1*%ya&MSj_ zMF-&_;h-yrza{|62U@6uo~^AcT{8dXyW3w~#0^1da33g-zk7>1>QU&KllpAXjod8jz(; zDNvfyT?p(b05j(Dw-SUQ>)FMe+&&e>fT0Ka?K5aNM(6_?7C>r%)#rd9U|47_Ky>I*~=6wv&{rKaCG&D_&B5Hh^HzePRQkz2b6Bku)R|FGG&_t3@Cp-Xhv|FM=&D zG?&M4*$SU$zB*(zm*KEj?z?P_&Zc$Azi5yWTZWUru^HoYt?8w}s{#(xP} zc{#skkAGE+WnUff(hNT1u~)p};s|orE)UFiY!IVH4!gV%bRJg+F{ns5ddKjDxoc7w z>MGTf?0w7l=b#pU=fai}=kSP!R7K7(C-)WkbscwvR=fliQE>WqU~Ms%Xo8T>o@Jei@`NWm z(oua?CJuA%YXg2T*b`%SYCq;b^{8OE`$D2x#DwgncZ0HM-chJ_pWFQtdmsMK!vs?a zO^OKzx%F6cU$-_DP68pVIeMgg24Y_+~C_qxl z&O4C+AnC&@$%P=&|8l(iLPHc@uCHU6ucsb@+^4bm&ZHnsR{E2Zu^05(IKf$d6S4B2 zbOh@wG3zUV)*M%Qdt^+cdJV6Zd1C+l1Hj7oqUmVAOYqpYZw$hY9?A1Xsx+;w1!5o9 znuZjYgk`C5qo14k0P^Q}i)8oU1D-+}s*48JtX!cB{QlVH!i83jxTsrV8R)`Z9K=k) zy+C+#2&`_pl@3#LO2+|<_3V$(40ud}Vne_ffhO;XNzkz&f-ze)l^|juLC2N|U=2_n z;G3uQ;y{QuAu?S>-<@lu{`7r4UAOtf4WiwY^X6iLrMDKEBC-K?Nyd?xVJ&l@AFVYZ ztPo~#FKwS#4gLT*K*qmUO_7U^7pt)#(~wKJieQN8C`Ii-Pj9VR8>>c&{wGIG391c!J&TK6Lnx*iy0R4tn-VI zCwCz-JLXDY^s|IW^`*fTXjhFFl%=agr2Y+|4h(RT_t?rUl6iP=N># z2$!)9ehFtz7eCQ^T+90YsXJ)P4OUS#GzgmTLW#B5XcI-ZsPQtiYWVD=TF;-_4PHJV zMJDr!odq-~yadNWJ8c4BJW|fU`~>|RygS*5&Zfr9S@HgU1Kex^-)g8n;r+)Z_KrKe zYAt^4E9HFQrjV{`>hS6=9ocX8quG;r@I;|`S(q%9k&Cx>dYWSB*yM9zx(XTNjp-Pt=QxI zVj*E*VdU=agHm+v+=wD6?O-g>^~ki{z<}bhUB?mOigu>!n6P!dy^a4WFq#Q5NUVK5 zP}}j}v+fhU1$t*5vrAg6?C@9`R~fE*w_BefC*!dcnjaGDvHUyK5CjLn+>uVgEQ2IR zk9K$RK4L?!CCVGaMH20Yl0_TIkAgMRA3{%VAO8Q@)m&1WM?j6gtSy*jloGW5c^prni3sA3LZdWh>Ju2c3I3qD<7 z84%vu_cz4}g-uC2?(hb-Pn8nQwKOWE4qkmD@xpx_m)4ofk3Cd}Kkf%o-CG=Gg3gXl zA68}Hc=?!_rMv9JLKj^RtT-|Kr^a;k4)M$BEgh~l_!lne%a(U{NTj&2iFTIk2UTZu z--BsP^yATevSz>@=$_MstxvroD5<7>4nrHJ&7;rcWCGm{SYw#>1|3OwuGLG9NM*)U zfO4_Ic60%M{r`vT6iS?G6MBQ2N?K>w?HoIr_UlymDfgW2Z|y8=>@EMeLI2`z-PT68 z#aFe_dgE1oO%=C13sR$jwl$+{If5k*{P0$c%nazvva?BiIhppA&J*$k zec{gAX09!#%T?cyd>h9zDmWMhCFWJHaxZ=&)Vji{GfKZ?pN(U6vNvzt+2gr0a}AU- zfrO@A$NZNw^jUqAfy=;c-%S&#%uY)j7infoB{blJ6o^6k*T8Q!!`GMN{9b7`eRN6H zgg&d)`|W=ZQuu}sCAk5eMkDk87mPsuWu$V=iT{4THARfV0}FG04y$k9WnZuzST(VW z2rE|4nM~3V>Y!tgX*VUS+RLcR2jCs}Tuis!a?}{SZ!S&SWass7N=K8g3K$6Jg+^#YMwTpE1sokm#Dn1%%;Z=yQu*?bXSD>$`!t$v1BAU z3W=aouyy+R^=eOrZ`e7ev`)M>RSr;{Hc!VB{nF#cymGLN&=B|VJ-{SS*&?JnM+UE} z$cv;U*g>U3CBZw z&lkq~yt}i7z3P1BuE^9Jt^+#F*7T=-Dshgw^hGNJ*^^B9e~~nH$S(U%Yn`A~B5)0< zL*4NrklJFf13R_u=LbKH^mrW5J^r`3$DslRIrsH(tqHkwiLQ-HQeGHby*9xLKd1v| z6^6xOPp=kLR4~YQ3Ouy~6}9vQe_1y&m;-+IWRXi97mt#TczX>0eZL}gVvBkIb6~ZW?yDX zM78}nDIa7;h*~kq;I^cY_y7M1p)aZIcipqP^IqoqxqdHMz#KZ|J2DH(fOrJl= zFjzmj?*i_G3Bp?D_Qq(kAp8BBt2wa6$B%YAZpr%iUuDLQsX-B%{4~gTQCYq-c%Abq znQY*wesPyN0}``{kbCc4xzmg8A6P(u@uBOTX7I2|RWCjmpbNaNfbKY7pg1zurN--m zOIaO2f3z}!xix$1oH}IVuJo&n>hG4~3cQuuCmupc&4Zd;h)NIS3vp^gs$A92->ywyW%Dq1Qpi&@m71ljJl2TE87 zY5nY`nDZZ8hiur3R(rmh)!tCBI^Vjj+1zmMe^^;kJN4g%jwS6uP)3S+cSnuoizCK^#X+)HU#V|Wv{ zbNv)=l+q7$YE8{nYX}7;Z4(d2w&$USt6|l0-FsW0?LU?ECtQYB+BWm+XQhY+*4qPF zy9*Pjtjprc=Gux~pkSAOeK9ok6%)6zH-SxX9lq)&^6d5C9@K=`3?d?HZ8$B9WQk&CVUZl8Ej$7!veaomu@IG;%29Z7~H z5h&8qfsVvwWZClz6$ay}dX24CPBsT{T()AuK?qTpo!@qxSuma&TqM!Qrj*o+k)lf= z9%AO^@BH$!Vw|{wYQ@UWUJ$&mp|HbNu%Z}!zszFIf9OU%e`e)&3tkqA#hSvy0s|}1 zQ=1=wm|3z~fpnoARvZxC{ZouuqghyiC|GNFLCW+b4W{wFXriGaTUe+>d+r;V|X>97rT@xvJU zAJiPYc+{SgkH|K+HkG*jV;W=}GqML0jWfisS6ykt$vBW^?rqBQ2fQqTvDL(THhh~z zpPgivZO^wXgLpgIHu3A!7`ZD3J5Xm#_9EPX;-uVtyo~#&q@obHyDhRaK4O<0gVT1f z*Q&>rF}8iqkfr`z!0ECm{oi+F_Us1)C6 zT!=C*gOs6-=}?w2WGf$a=A@q({$fmCI8jDuD#g zJg8?Ls>wAgY1Vi&37`&b3$_&$RICG31!rGnVIlVy%Gy7vGhnkE*651o`zu;Dc2qM+ z6`w1{*H&5-kKa5zbLP#>iChrHfCg!XYzqN^ZMXX#_YO4HntrdLw=}HKd%lLL0qO4$ z0noTlSs`nP3tFr(K>&|{&LK@8QT?MImc6{}4Zxf}8>T;DHckd$`HlBiGyExW#8=qQ zK;hpdf*!qado%UiJ@DGBgu<%A{}N{({_Fnc?a0xPYXWhF&ouFGskxsjR!lejMs?RV z!~c;StN!WpwoPyjfe7`yJILwEh|&+yUk{X=9(KEaK#5Sz>-vst0?AK`K>Q?clgtJY z+(4S3Pbt6DTk6cSO8!Gj8vf3+bhPK{Z&IL52p^Yb_2&Im6zgR}sx|FaBBxlMLF0c8G+!yU^H_tO&R8jm5M-)IxNF-|mj>(#5~ zlPhkDrhzxZ_cdD$+6-DHCLKvJbyHY2UsN+QTsW>jdley_$JC7ZE_w9GJx!HZL$`lChBtl=7;f~XL zh0c9K4muZ9I6Xd!CM6;q5iLjUzrgu>ZaR9mV8%0H(-v_yi3QS}kRufO*n`!+ArU}% zd6;CqThwdtB|x#NiOx0Bb>JJM>*KZ9xi-0?TzzecT%19=k*>tJ(F;z8D6qEi0~VRg z@6zs7nZ)0B+n)aA)SUV~@qwnHU7UMd-SVvW)VXfg=xS8LqR4&!yRPisBgMw+zpghk zm&!~qk2U^7v+IY@2TH&v=;~Ayfk<5j+X4&mCYeu^!ZrIrM*wVNb^;lrA<`4r^riH- z^-B>NIZ&)kYOcC(7S;NaVwF22Ci|y0|HimmDHPDau{H;~evPHz}#KS3!2Gy`(->MAdn%021UC zwPBd`g{mrpG(%ugW-Ti|rFiPDr7wbjaCE5bE zKD;LsM*@tI-bt1o)epp@ufpRt-_lEzwnz4;DcIrnG>Mx2eRPH<*A3@E5M3lQK$y{X z2Tg1pN?Zs6ie7r*ymZqG5rQlV0F8pE^)1h)0{}FIPU1Rcd_&(a$Fm^pS24|RG2gcb z4S_~d29d}5e;cQCYuGWeLUqP~^(WRIaekz8rcUU!b3nQxJe@po2h+{IC$BBMnmO$- z&85tae*K71Ys@2Tzr3BX^{H_Th*w`SHp4`>bJgBIS`BZm z4clu z?OmJUy-<`i!bF4q?VKR~LTB)1fV=mm`+pxk9A0QYYfPPu(#Lq1a#rSZwa_h6+VLmS%HM3-7bHEn&U>yLP6ug*n3 zqH)#|F-b`8kah`%A#GY+C*RlFhS^pAqQg14?;A||EFJxr_P7!=OYq#CvL${?PY5_7 zKs_zhi-Qm!ko03Cwk>Xy!&@xKE@-XEkuSW?@jsIYtIw-L1QM5yfQLlIW%l;}!Qw>u z{>CHEUl>2EIr#E*4SvI=#;9hu7``dYFs2TFJv;EOL!o;1-3(7x>%@8=lM7dl<4B!q zg9$gDX0qn4m7G{(<6Cb$z8UkwnRVhzUmeJMw-L}4H-(%e?dyB!I-CC?2uuS)pO`uK zcH)Qmy0|U3`yQ@-bmvgQ37GV#u7KlB$FoQ8H=Ut-1RXogDSXWDF6lWReEwVz?Hr9vo&>2r09CyJ*IxiM z3j&gm1W@|&-nN%N!yC2zv{yRsS)GY3q6K(lruPy}IM^br*^7!m{cF5&!#?W%7x=0x z>xSC%HbW?8#gC=fSMcRW-#3+KW!%j^@;=*)9PqrkJz7QHbnWOz*u@jbUDXeZ&xb!q zJ43&pyjdc`EgTbH--e5*8oY`$%}R~FvO7Z~C&IR5&xGR_DQWaaJWqs6>`5-Kc$gkW z>bg|l1%K3NEAS#U1SLgZVEi!+VdgVwz4L;7s_PbXzm|;fn!?_vj@0iDnUFYF(kse( zlW~cn!E?lqQqq_&6MGC&qa!jb@-$1LP33l1s|Hmf+ShxEtMWygCHIr*EhA~%^H++i zyTDw=hx=bh3Su^RiL}{}Wg8Vn#lz{PUq0xHsS5VZ*Uxa<7lWIDueRRVUif?aPR5b9 zkveW|+Vw}aMqe!TcUCF;HYx;Ns?6MytUGkH2c?X$z{r}avE#4G5~Gg=s}EZ>m_Me) zkjnUE|EhQ!v_r9pZp0y`sZe{udP;%Wcv5KquI!B;45=uWecWsWDcbpK7H0QQt$OM; zc*~~Yifu)?#|=P?RDnEZ@@j7)qBNs&3y3UhAd~cc(xzu2if9H#ppzjrPR)3(F?=iU@8G!-UzHJ7&dt+Kbgj1# z6`%qRKW;o$kkOp&F`H$^@Wc&PXXiH89R3AzV1}_;wmaleeT?4x2|&{jrLvKM6Ij2wPV`7=%)ILZRJ_XHxC- z2S-N@2P?vr{~}boFP$v3Tw|eFItf|s@0%0{CKr|!+$kVvhPNr!X){4*A3nrxlxQZx z`%)_(zNM`o?SfkbM!h%Vnyb6G|8|;eomhsc-eGCu3!?EPm+zCzGj1Q$YMc3$-tyDZ zo(P_*y^YbvgP#ghUVd&aX^zQhj|nS)>U0!@NzQd#P+4EwTwL92@w_AY?cgoO@%NiH z7)bYSTx`7{+9%Nv1`}m+bF?1pQ0;9OH#!Wrk`R6?!QuYY2Bih1Z_eQb1;|HQNe;79 z8w}@HvPw3*uFn49x*jFEQ)hy@kX5pgG})pz^CP8<^Dn^M;T*l+G8KwI@>hf)`Ah9; zbM2|i7Rip2*PR-T?uf9j;!*bB?J`;9c2(e=EeV7(SjDwtdOjeN0?SY0%F z^zRpCi9h1+Edd{-AnK2ii(QJ^(v(e}vQ+`0Jy-6n`|ab>tL3o{*>0o&_Dc!gGZsI%3E=ub5oNdikxonL^)Jl>c*w0p(Mnf(S7qU> z3tBG?x48c-5VY2kOI-5%Ki?@37KqmJhk;9DCgkwag|S7#B7tln#CWUHnx?RvYtN$6 zF4g7cq36+g8Ofx?nuLtZ_E?m^2-%(gXeGR=`U^Rg6__AkoFUbhMj4FKRB&am0r1N*gHK3ywghNcot$M&1v^G%GTW!?jw!4G9z&g= z$V?Izye`P*s00XzX^evvUZ!JNsO9|U2l>)E+k#0BdM9OaxcnQ$909w3Rni{ zwuk@`9d?ETi@e-QqZT6^=y%GRht(L?pTcCWqCqS+wuUVZTI+V3JTUJVPPii;BOXJ# z+at_1bdnBJUc?2+DD61A-@QsXwA7q@Lcb=`14KdqNsiAIF4AJ9M8!+Nf^f()3%2p1 z?u59bxbvINOYTzLbXmoF6Lr<++SQKX^kJt?Eb`Hb!?nw<(6}$SqJoxeMw(x!NT{rp zS=^AFyXz(>cUM(scuuW@xc`$xv-DAMmGU=(l~lI52Yg~a|ml)~r8D2B(^R83p%&#_}yn;YH3SLSoxQ{c&D@e4lOpYa4d+b6u` z(!91C(edZVd0=c{R*Rc)D&6cK1?;R~P?XH8U zm8!rH6abZuf5Cy6(K5@bGzFjjHq51IPPFVOb`7Iy6JSDlZ;S z3&#`DQy>1k)G=)j)rop(^}HcT=x=)Tc=SW2w*bz786@$Ie!!L!K7-utuNpGmle@3z zK5MK-_K`C%6LI98D0xn0;qF#S_&-LijHYww{$hDne|5^nGt9CR@<-2Pnvs+7!4WS~ zN189bK5-)RZq-PB@<(ulfJC{xM$*_W9A-(gi$XF2D3{8=T3mWv%y{6womOoR^zSr& z9J6X`bCBhKllUlgZ4a>So5@t7^sukdU%Sd_={65KZwHwWFn6?HrH*MIGbvJ=WUNB> z6in$Vd2NS&0=d`cXe!0O+%_&SS*2XncZH<8>p#%mG4+iL?tDaDUsOCWPHR=1a@(+2 zWiG1HHE{Ka{1l66^s&EWh06XfqeiWihJDgeawe*{&J~u0-P`5H^25gYg=G2B``d)H zUtcL}gIXd~@hdJ#SYJX`yq$$VFI0P|Dm$(8p=KhsR_m$p+$Xjh0@PjEbw{M{10a; zo9+1c3-fmJXML)x4)`$7`dk<*QczCM{)hgA3M8EUJOn#M9v26a#{Bg1sNn(Wu!A*r zj(h|psu7hgeFG2g%)v(3Jar7U`hrdaLk6VVY|*4fhQ6Z9;QypzBWaQCbSZb>r(L<^ zv5Q-eh(L`1@1x-C*pIXNk$&15jffCgF8VBYRH9^O5tl5y$JK}Fyv|l5Vi~drlbrVY@yc1Y>HNIc*k_QdBzTh`A-@bA7$J@ zHvv|gIs(Aqb4PK{b32p}LMcc(klczu+@>QWF$zKgfWS816iojB1R`@=4cyeIi_pbo z$kul_ELn}P&FY73?iu*{`bF@>7konSA`X1is?n@ekS++B9Z#-KW_sBA;?f$(Dry>2 zL-aQ~9QiVx+kmzo(P-adj|&-g(@sh(PfCwZW-|ODf{h>9)tl9S$xaJIU52t+vfa6$ zAmqi`s4{?fn2!7_jZ@$J0$H_FTaBW+W<{h`&xZ4UFQG~1Aa75jjMITm&+E)8vl}`F zRb9F5$5uwC;Vo39B0(TDA-_zNJR_q^4?z8th-Zt~dW!I7Q*%$EbCxIQaCFgpbe1qf zBJSk?GsndE1ov_x5Hn|qk4Vdv&egU~*$bVxFHZIx!d>D>ihvm)q2n&0yicO6fJDj; z61>SnDo_%mdmI(9PKt$hV1I{&U;s|oFdH;!bwQ;@P26LS`C795HS;lAL-Jv*yhT1k zVZYwua@zUQ8k?iXJCB8S$F9?mVuIA){bDYOuM_iAY|&T-_>YU6QX>Z!z!Hs|!~R-d zIknT;s3+P-kwI3k^AaQ?& zz}6hWcW#JwMCwgJyvH9t$_x4WL8NW@KV{I-qxd(pO1#sR8 z^K8Z4Eh8G*4`A2*Ytu}aDGK@CALjdDM*cnR*QJfAGSB)=&Hm+_M}Jjb7`X!zA1sdg z@j>Y$&Y^9uk@!_vXE#b52Inl0yPY52C2n3X!VveDYU8i6WM%KTU&w82=lS&DRZ=y^ zEMdPyLR8e0KFBhtXI{G+(~i@bTKJ#jhG=8vE^obPwO<;B#cUrohoMIzZS1z}*nIV; z&+b&5c^!&w8Ry7egM+nWsHY$u7LTR=*iVS@uBIztTN=w7+^wB^qm&#xPPx_vu? zfJZEh)@&0Syh&gFgn)n-br9i_++N_`n1;LsmI28+dx_Y z{Ftb{e}Cs25ZsCT{L`btCIu_41^K_2Z{I>E`30g@*ws4u`ysHC`*?5_T9{{czPp@q zi*=yUzgqCHw{2v+b%oijxT~a{xuN8?SnCD%Cj(Ngy+fZcT}Z3c!}2vXTx-VyBan1( z2#zMCX^0rRbPEhv%J@OmoQ5Uo%td*dfO$NrKbm|$tt@JE=t?S_1UGm6Kd&auUewok zJJSuOANrgf(`}<$4)(XWY-e!Ju#__Pf5a02_kW?Y3h;?ye|(2uCtfzQ$aD4Smy9;FtM=lbK5iteWHM%aj-+i-`{nkRUFhp%2|Y27pZJ;V@va2xCG^uKX8@IHkG`p zA8;C~TmI&6k&941TNH{w3e+;hJ#TO)dEWC`=wXat) zbXr=>271-jW)FtnCUFv?9#X_)UVmIt;Y^BPEG{U-hufIz4I~LiiuIFkr z5<2@bL~7^$O;mh!b71gpmWcgu7{I~aM}kjXGb9Ce-w%#kTpwgq7I@qJT37ffEi~;&_)YN#ay&ndm#5P!2Ohf4d0TH1^2rUoZO=SnJ_>bIr@%N~={KHi(%D0y1)w~k!XtITZdm%3w$#}wxMus(9+ z@htMmB3jew-4XN)cJJ0=O1|#uTl+P3_-{X3v4{zSn(a1Lo&OD(3pC|x@XuO4|N1f7 z&b(N4*>f_A;vl$H4S5X7d1&KiSe9&09xdYjb-;&4P$C-1NC8RF!#nqJQHgXhS)g?WemUl}smQ&WGh zBlH9$=*A??;7o-Mqpd<)u9-$tI9;XP#;DR!Xn|dfWDr=yX9BbRB2wfxp zjM9bBz?iwGnCKt~MFZaaoA(CL;TOX$;tZUDhV8l7D^r&*PhE-2y(Nk(`L`}B;;!UQ z*^3rj8Hl)5cAj5!E8=|fnlA$vrvecmFda#G*9R=*1wGGgCaRt$)yu1&;5@e3Y-BT?@i>7+7!rZ#M#S%eiGGQ~j8DVI1QaD6j`X_`*#(Bgwz7qt?)5C z9KdOH4p1h)K4Ro8Q+Uf(*S9Fp>n&5R@i@F;DSncNX_=m*Z7b$S0 zAh?P@zR=VVLtH4^(+@ib<{(!`NATqZPV)r=~F;`=8%IPc2EvkLp0c=khZx?~BEnu6unkL5}8S;BFIMC)H?a(GuY~yj}#FdlGA2 zPX@IKS~YkLmMk%U*FJfAI@u63Kx6XO-DHq_x6uG(GZelN=&8WpOdC>E$E<0U@|)Ud z*A}nb9#u;JuFSrl8Wq%e>QrY?5QF?KCMdf-6?^7;FKOZE`zzOI@@|G zgYGjTAcs{p77O%KrB=DM^uD<|eV3Se)5@QbRMS?&s zy_23v$?T-3n^&SXO0h^bwI=73ZIy$=_bT{|V@@q2XgsJM+Z;$?! zYAD!ym7;XHBo*|9*yOqR__^d{2Faaljx%X0yrd*t+Ao0F6~o*3nvkPe-RDkKHvQJ~ zy8<)VPD}9f{a}>6d|_hf#nmf=zMJ##Uo`8B6#@<&A!zr^boK=sZc@3A!Pd85{jW6f zE&HJ$EvE3*o-5?H3vx2sg3P)hR%#+cf|Kwo$cu z9yK!vv5e@9=c*=dx6IEoxB?-IB^CoU=vl4VL_ObM*RtpG2voXX{X8B(0K8u@65V>s z1YKZs`N-v;lY5?nP-?bRTym;XCQ{&ORaF7DlDCJlcUWDhaTay}gv_Ocs)v+4(q!tfvk6j?p>5zM$y%E0aWWLin|($JCQZf6KZX*KX9V zl{VLY6Db?J|IQ#0T)q9%+Y$b*B*I^19nIegmEX!5m21ChQ#!1u5!KZZRCaHqk58C? z^v^wL(hSC@E0RsEj)vFX7}OYsD9@juW;5eNArRAFS5@R zgxwRsm}JBN7Y1oMp{B_nP14eNaH->*6{V;$nFY@DP9v za2QZA(*S~j0Syjrl|0kDA2}LqZ2ZWNxnb*#CD7Ad{IG_YpE9(!xSNxtWBnWkK?35h z%)LGIolZ$$Zi5F?PXiwuIGmq<_DF~Z;3#xlF?+V45!YS$uYUsR&6}{qw@aQ0vFpG! z=#1O7@C+ZP63XVhhn&8Q%j0WFEh23~a)SCmm>5uUv{F4Pa3OadD)0O*kCP0;Y*qs7v` z6{FRScdGXa>x$vQkTHq>+q_AEPs7KTfj~A1ETffaDXrgC{NEp6Ju05d&VSQ|nXjxrQ%n;O{U(eE`L9*i z6Ac8_Exe4nc3|y;E?(3^RCQN1v;JIDu}9>V9Q)35)28XtDB!qa_*IoTXTma8h-2~; zJi)xd=HRAO!I|Ix{rT;8r3B2}U~(MuQ2WLUyI9$IRZRS9l3fJbXj0NV&>_!hqqQTB z$7k-ywd>~7wNml!Pk?!NkGWNZ$YI`9HL6rO^p^nL>ResvxRW!+OGT##kc{?68zUL` zQ83z${^36rl@JHE?Ifc}Rub3qOcMl7s$nH3*CrcB8kk3RB=f5KE_M&jD_Dt1WM*O> zO*&Iei%+Fc(giG0Qt87Etxm#)p#SkgBlJz<`3a8WPq7y3xX-VvvEY;^D>DN(YS`lBtB|Wa!r20;#j4tP?1J`}Q9xI^pth1Apq}b}_43?86Bg2D2LU?K zDqD;rUNOGjU7E(tsjuMjj>|JEL+E!corPe~)t&|6DZI&oYYDvbx%q-CPdH$owkrLF zU#at?KgQvgQ#}*Ejw{?4-|Q}=G3uNC7)2XJj52xIm*cr-(uZ|cM(TNum27t75nfJ9 zB_u;9vg!!X*M= ztSQMDlD|cLmK!H&`8l$(C8sr;LTMG`ti>NeZjU?uKvy+7`5km%pPRt?{W&|DK*Me!Du_A63>pcF8Uh~p;+xy-A+SkXz;qjO z^{F;}2Dq--2a|Q#v-9^AuTfamR);Wg);?lmv7y^Zd49R2AXnAqO>84+@mE1A5e@{}eS|s&1T|?w6=vL_hza4Jw)84zwEb}HN^+&K(N!?#wf_+BxFipHN*2CHGpuD;7<(17xc>2VY z5TaD__%Z|@Jjh_T%}o}zeVS)ivZMkEMV8HE9T7rEkjVTDpdw6ELzrrW8a~kotTWPK zBEKSn+1!-91;T;xkCKHSyUu1`#&e6q$o!)m7$hH7*Tjh6SKK2OE7_%qSgbse#ZtuM zv1N%#pD2P@Uta-(Ld#+J`sT!f-2ypTUqcsX;{$5*ndh&t3_it3e%+2w5Bl1elIUb9 zpT!l+AOTpRdC(gIX1O0Qo(nce-`S(BW_F+4?W|^OkqwiOIbE5T22BwC2$Qi_kVv!p zZTf+JDX#xZ)1STu0XCN5hEu~bj?IubFMj+?dP-c`j1s1XgI%!+b0wnzMiu0y3=d@` z#zO9ua|P+;O$Q z$kMRoBn9V$vGK&Dlv-ZYT+3xSA;l$gO>ZHki9sY@zMNjbX(2iKkI{~kIGp2TCx2LY zPQm3g6`>*F^2lXG8`(*wBGYpUWLpAXky@L=iGTg1T24xGZB}N^!XYR|qSf(k+rT|S z2i*Vn^ZzTgbTG{=x0XO8-JS+EB-n)gCDz1+oKZR=j( zn8K{ErIXWU-6n@epluB7k@``B>yHa97j=gtcbML6^o&P_^_p646bEsUDM+kW2o-tW zP}MSA>=(Ju&pCLXmluu-U}Q$Wf@2t%rcVP`1~k=+_gD{K-K*AwMC2qV({jKzsh_Bl zO=P)YeTk7FAu#q%ArdgUkc5Bm8fIA=gWdB0Q>!|Q&2^8|v=k# z8+3r}<`Wv-oXriK-M1ZY@IWZNh6PRo*gYTD*f@21(yu=(5Bq$Grux;rhvSRchtXv0 zNJMBWX2;?K7He`OL=Yo$*<4Cq2yo~R3X=;VIuZMwJPMp?dJV(#`2uz^BUm3;!!Zv& z^!3F2(7XWS#Rrf8Ik51N6ZFw@Er~vHJ};G^tKY~uSiktJV3l|9DM;i%x6UbfbzK}y z_pAF4#}~&dBYkp{X?egc^(*GeIzUMSb@B5u^MlRI*2R zduN6fSP5@AnOvVqwq*I0nD|82W3c|k+y4hw{X=|YFgmkNC>LZY1;*zYxiGuV6FrkO z1E@J@bwqD{Q+>G$R5jyspozEIpjIPX6g zNhR+XDt_RAL<5MXW8as=+)I|!3SSInoZ;zL<}(w!&;l1L!Ag)x3H-+VfY(l4Q+}R! zLBMg~A?R}Xc`Z$zmTXfcO?i2z=M89I09-)k;sZl{1wi6wkhoU?5|3!pmg$>N+L$L` zRfBxS&%K?W&!3u#$!BZW!}jOS*$)q&bFe=@oH;6QBRHsSz36cMoI_;F-r?NEyq;Hn znm;v?dwW{2*16iiB6yj65I9quQ|}smL7aPTSuf7PpMVjsDrqs)BVtf3Eg{+(xV9n% z<85Q?_(-5mLpuNh5`)5k+^S9ia!G9g^!^7Yubg6;)mQ9+zgAFVY|C6lB3}as=XtFB zbTZKWFTk=$bTUpWI)ZBoHTE``{*_U4s9(0!n?NT29^!I?jT=!-|D>tSp92tp28#;1 z7o8VnO}rQYT`cIpp6TpV0Ua?sNCm)VXzr7!?kJ6yZgayNbB*z0&?uAZF_ShA7fs4H z8I86nJJnd#^;?onxbQl#F&&T!DDqbegt;J8UG5J-09gkW5U|4D!b;MpkOkBf4jGv_ z)ZXbuZW~ZvjDT0Id{LnR8%ym0$i8v=OuZ41!;2;Bm@!SWi>3G-+5`%aP-nY#H5x>7 z2+_T~ynCX8ycto53TE;Y1){ur;}lILDV0ga>&#AM$_56ELF)#G04*5W<9Z7(u^f%? zg;+7indC{uI2njyU<~9ND}lXX^d)cN4?lgP0l19O&d(?K5qt@(Gh8YA)%f>P|K;7>h!0K)A* za>v1SN>vyZc6`w?_mg?z9#je&-_fVlry~l$Ux@ArgEioHgkc*RT+wbF$Z#!9V8YpY zO6R)XSHlKC1BX7U2e)wZ337WILQ$oXL+JSuJgb~)##2KjD-CStlvTml`rGIu%~b$2 z1zwE>OoTRQ0J#AD_+qQcj@Hci`P-R0b`bY?9>aDZG<8DDmm2Mao?aGdG~eH4@mjt0 z30i{IN;r_Q#9}EcS5}skfEm0+qa(w~>>)?iuU>Ln;aRR99><>s9M-(RfF}SGWb8J> zZGpC({OUQfqrotLU%(|4n8)jdTAGg{>+7`=-t4U1gN#@BYla0o8cf<4d(SAl@IyEm znGRfdoy6(>>&mD7qvE=#%RA370=K zc`t?)J{Fnxak$>rp;Eeq)U$k${BkrAE`LnrAQj6`kZFp}K(`6b5_JABTX1J#2ibdY zQ_ct`9AyEYE3s2%s}`!j>0*nE64Bmv08c=$ztfvzATXIJRF3y|Zuz(2?|c*}VA*63 zR`NYqJLz`zj|C*s>&NzXNCW{7x_fqR^qzUu-;H%UcGNZe#_eDb@ci!vRjSdjy{d`F zM$qN$>8-7Fkj*BA9|G9C^$`{x+k@q8Esz^%H)>PFo`y6P`f2pH=DR6rlRqYdTVGp4r0p%k zowN>WMV2EcQ{39OoXP+B%sOo4LwZbK00M7JUmve@+M=>Wn{%&x)8E>b!j;SAW9V!+ z#fb>!RToemUE}-cOv8S`ll#_owJ%1M(hAJ zH~9H&2nvhOhv%rgEOB`?@df3HiFsP87+4tSkT-gazvawiD?5l}}#OZGn99$LB5kx{ODf%IB1;HT{Fb zGL8jEG%duwt*TTPi zAt0b)-Y&eAgPQ>}b9^DX?9nsKv$7k}1)U8oL_DUYqaiQ0{7L9T`PJBkCEEkm7#mxQ zrCZ-FIA@Lf{-4aPs@1F;*ij7c25dEZ|KlppF59XPN7|1ZMiT7tCS#`5mi${s3bq&9 zHE;ju6^WlV3pAH56{XZ5;BEvu8P@)MG}0y}RAFBH zI)B0t71fReQFCtjcor)2Ku@CxU02z+bC(D@btksP)SV`=x*rBd>shd(&qVqnY2L{I zR(em^Se~+F`jg8)$YJ)uImg)Q*u^O~ENtQZp6R>I>tJRVMkD)nreY*EI!)Le-OssZ zf0WE<)@)=;IGBOm7w})syyBGYZ92vRotZ?5O~m31fdzWlXQ%7_+bX4>r*Q)Z5yS{!t{I&E&nwj_{%#B0sHonVP8a@|(X zmgfvtc3a)4Pq;Pn7`74UV`u;Z#5lcABF|Pf{>A>AeOqTh(#C&#A^sivF3FTdg>$xM zVl{kU1=G&oqSMp2Z-%xWx(TOqi$;%~YK{{C`V~TM!trGHeGmUtec)(vGZaIUGE5j9 z8NH=`GBlk4+sZuZa@n$l4twSc=8q0~0;=$}F6hXe1rUL|2%Qm_a z80?O$R40}eKZWgNnXo=_R(GT=0sqKtPqAw3aB<^m*r#}t_??^&0D^W~ef@z|Vc>mQ zO`67lCvR2Dngr~J1|xf^SLiwMG@qy7;vFpJx3VPdncm7-jz7!z{Bo4=5Z2Csq-!yC zJba5&RB?iNhJWHiUhT;Gkt|;$Ba9sPx~oiH)Kcb@)a;bhDixIXwBhuCw@CPWvX4&h z>|GYW>+Gh`d;3-?%Wa($dS~}X@oG&koqnS8H`BCvhPuCrS3chZFwAEFa~u2mFodgx zg63!M!Y*@1U;R=h7%L1Q@fUq$7;^ui=m7pD=1C6SCLnqYJx!~;aq8@uo2M#iepAt- z`~0|t)OKG%w331GbqYluIbu(7KI*)u#lxdzkHdZmSU=&ZNf`$k@HPwvm8w)b?t7B> z-WbyF?}83D|AyH3CG0kt-y@<%o|;PUq0XD8x>^suCnbC@;JjcDGPuKKvwhk#+#c=O zXI&3B1trn>D~g*;i!zE<8or)V#1nr; zFXDyK&H06-Cnv64ekNEz9*bhLd0z~rjcE;>UQac*w#(a1)6cqnC!7)@!r&ml7Be-@ zGdzdjt}ch*H#}zzp0jgQl=b>mVutA`s93AXR<;@V$eR2YT)lZs%8Q=yE3bNrHOS-4 z}k0~P50vc zJ~SCkLf}aRY{maZ3?&2lk`I#Aa?V%-XZ2HBB?!om-<}HgZlE9d==!B0#-mgK4ul8~ zVFkKS2$1Id)ZKA0R!jozyXe+tMt6M);do*Q6}iotkOVXJ7AhBF0{Ch=A8Pagafsf~ zfKx5#0Euj-hUyjK0!dx;P%|)WAnIAg70C~YiquJYLt-i)d$v6G{;Q%`pR>_?pyfZ- zz|nL({Ou#EEdI}lvsT85z?T@fLPsd%eE74EGh-SCoQaK)vu3y}yDJiMhWpebB%M(B zey0>`qMn2~oX4i65ik&7=^J#qt?BmxBa#3qF+2;Rq>PCnItDm;*aaf3IHts+a;7JF zf7pIE?amt*N_o=rj%J|X8&GfJXS+a#BIXZSiCuO=OXA@;%$xuKh}^YVw?LZiXGa|% z=Z_d9qk5x{TxbzGk}Rt!UBILz*%%%83q}i?VaNgcyv;I$^|lZ0!^WGgKctfV{Dh{7 zSU(?%^EQI~ypJ%@O7BV^0nSCK^hPTrTU#fE_VdP^iY04qRoHabt(q|F`)}HGtBbx! zW}qMx#?|`flPdITVVBrv^<*>Xe6`~F@Y%Z2{yz>z#59QjK#F1-ab+{i>MP1}wrpRW zxE6t1BU;Pagqan2WL-NoAEKvGRFb$?HM5#?D3Dc%5-h5K94rw>oemW z$?=Ktn`K6h;YFdBTw4YpSk;~zC;b)8NKZVkEPC?~#XyB$QqgTD9*!EaTj@(?wA$^k zkqP5{gNFPx@aA-e4u)*jO8C}aRW9d?m9THEW*rTm0}lW1QZQUb(Et~}z455LnOW^^ zutY}?M^p`q1(D2Bw*g2?J6A^p*sD9RzvDxQ#5b8C2;|_<5Q^j=ifCkbf+{zY)%^U_ z{1`991PH-W2=y*P5~HF_)TNwAX-2^_(Yu991kWqLi?I*4S`Q3WKX?r`qge()B~TIZ3uG8@-{ZTpM{CVikoxF5f1DYM+AJs5 zpy!+?w2jCb))P5WU$?A1Z@2xHQ|yDhGuC8pINOG>J2%lc$AN4@?cz<#`l2A#ZC1wk z3$)bRcd>EE8nbDK{+`(1Jq0I&+%6iR+qc~t{iRJg^uX|6EErtAPU({lCtOSw@ zDbSr?S_k-O=)G}T5wSx~+2sz1oF^5JZtJ{$j}URO{@mqXW-8CVx!Rq?vIf$ZrN0EQ z`XkWhTXQ~$U@VD(Kn4+zWLCH@*l;Viq~PJBgc9+*sPJJ4&|S%6q|vtO_$|CRsc$tg z{^KL)_|k3TOCA*#%s=v?2)I11fJdR_@wmJ^E?6a`NRA4uusYqcPd$vOzioh}TxnTF zjw_ks3y$|jJBS2V9uu@QxtJv#moBLO*{mM@*4t)dGh+s}U%%D;FkV&pyJco$9k0ry zO^W73^jpWX!Bz~0nAQ!@fh`-GivBD;8P%dLm$h}vnN&m0$>#rqTUX^BZ*D(Je-U;% z`%&<&5F#&Qa4Ml>e0uFHhU@mXssaAcVsSN>PxSRoruF_5ojZU6EE(vZ?EAwsdH9}p z`8nu7U(Y79jsZQWWy8>zCJFlgSx(oLcR7hyc~`Zs_nrGzW7q-)WzbJIe>sj9+$)jF zdjC4xZF$o+u^1P7JWU>c+$kwnClM-AyoO%81+n>y!`!(5wZ6DdOlO3YL^iE9ZJJew z%%XxROTA|MpA-JtaPE<*Z&%bq|DQAG#V|^9du3BeX$Ykz>a^u1&mFVF((2pV7tS0n zAP#1pTmcXu1YNg^^sSk{SUW3K*&xh;!{-EJf;qV3u<(an7-zmFnBA^Kxqvr2lcRXFNO9qWKZo2 z;TEDT+vDS-PP095P)q63z&YcPaYCHjMb=3nKo=EZ@dge%RqSTnh^ww*NH-#{*#6&@pOGqaC0IoX}((D+}G;2DiRfRTV?L9RKt``yDxmjTqR8iMuA zn>O8}MPDSdP>?jn=qc?O@==7!I`H~vYcX{63z#ydnPXrDk=k+P=BwTxxz(&JGM0fm zuJ>cHI_!M02g{JY{HD~@j%9}c;P;EWa)g>p|@at-=3vsJm zDmmE0Amne~%Q&Q?9yP2apsNd2_cpN`FYq&Er}JEPhi@poKEE-37&F~?{6!q^{7Kxz z?_wE@kHfzpZl21^{w(g9rtDFE$}LR$<_Y!spsjp@)GkDs?A}J%;j7s1r1xU(!R|2r zp4eGLalE0^?wq2)VQR_py3=)c_sXYt%;|V-u#nX-Y{P-}M5zY;&pByT6tUs3 z)>HoA_K&v4n|A^`Vmi$^L1GOcr~LUZcx4)B_+4Y@yNf`ml!D<;7Mbc^X*~J<=j3{p`sur8ws-iH_pbGc6_igNrEh-B|L zC%F}Hk;4jL4}#06w=)1~G=0|YK-Zl%y_hIcU*F5Ke%y(*uiPQg412Gq27NW5wF0N7 z>C*u+dq*>pquM55`8qoMwbI134Qw+}bLu(1i4QS6BqW%ML=wpO5F%OPiwL2I1{03R z(~(San`ZR2k;istp$EI&s3Ia#WhBhr(2%Zu;>O;N*AS%N0Gz+$YYN~FtnL;5RyA1n zoG;k+5$LpIfz(dJ4QBhIdWU)}N?kmG)Q)jS1P$hHxz2X)Dh0X*7@z`_?i~l}gLvh! zR|0_6lE#xjqjnhpre$r6_-;pNr0rg~mP#nzGGVBe4)7ED-u{r7hGYl;f`S5BQy*7A zi21_rSg?Gd47=s|x`t)_;7!H?DHy-GV(U#5G8*3e<2-w}Z+%aj@48y+Z+%Koi^8CJ z%HP(`d2|WA{)v1rm)wZUKxd$F4G)SGytt2DNyu!LIOXOS80(WIR>OSvrJ`f$nSJ-a zp_H}1-MycgUUbZTi9cLo<#`f3ogxU~g`Em!&N+p0@e-ASms|~N2JPcXw`06xd}1EQ zNFVQ91sucz&efm zq&#`1?yRzhnbWFJqF^Xxvm%Gt&~vu#Ov6c%1TlhYUnZU-5~}hPZcS&7MpQW;lP|Gq z{6wI+u?K~s*R^G%#yXU>y(+)e!XPtDK2VXKL!*#!RpTG?H+RxJ+zEf!R-l!4jX(4;w7jltl!K zKYJ*?QvuAd!GVDe5Q8{eNgBO__ew3xT(M<)?_gI{(R2;d|DKmY;|05U0n zB*w2ZkPzg+7BiiR#x^u`t1_+?pB~3S?>q46xvJ7cc6@;S)uP z{1}Ou5KNf2p1(FVW-2*r8@(CM6o^9l1_yFth#`bbgnan&9TcZJqbA!+1l>!eH=)9S zH$EvPkQGUIT=MxFn4AJ=q2e`ngjj1nWo_~ecbzQ1=2@St8fT-kHyS@DP~vv>R88Lv z-iMFMHEj;r&G%m@bmV@F2$>20rioIJL66ZWBxjYtcPQ zfv`uFBSwUV`+}H+0P;;yf>+qn&~3m16=k4J zwF>Wz%Q6kz1SBUephAVF9?t#mN6@%+xowyzDtK2ofK2gMGKa_gKajIGXyHHa%KUz^ zJNUb|)*jBaLpKf`eP417(c$dJ%E24EUHRWNo6^o$`PWnD&{O?BljEQBFn^l(Sn3WZ zH~_>195-T&ZP;l0r6$65s7C{RQW)}(ifA9TDZ6vJS#~+yC!)8=Ik3KTf#m#YHq#~= zb)lXw?tW+@3+{<2Jfb2f#AN3ahwAqF#YTko2L2rv|iIZAgPSb~H8Q%{SOjSsfDVD!guEzLWw&Oo`B zFF)?CKYi==>t_Um`<>pmOlI}|@W%h3SCyA;KwGr63WLNk;VG%*W}{Qa5Lce#VnT#5 zWW;Wa!B)*e@K$W){X3tdN&YiE`@%RQv)OFhZQZE9fxkdC{Z#dVHNeteJ6FxMD?Y>w zC_fl|t$5Eme>Q#ZTRE`xIGTxlz!7)O)lDsw@m&Nih)q8rs2Es+Kxrt(f?a%!jf->* zbw%tyjQwLa5zaK{wrJK4pHufcB7>=+!NhQhPqT2}qr49m#A?`3b#J)PkG3zsIb@%g zhwTz^UazV7Mq&8PzV15*pads~7(x&AK!H09EFMx?ZX%^Ahv>N_EVF96qjq$&d{!gD zIHJK3c4YbVnTAx;GFy>tn5mdm6$-Ycp>zFnFMMM!$2-*%t5`jcirbp*ZJq0%1Kt$c zwSV_6E5``OI1fe(TiUhzr`>yOskZC`F~@jdt7ov%^u=YhZnfgGTc9_O1$iw4J?VPJynd;yyS}Gb+T7WcBZ&YoAB94VfB7l?8P#dWE*g`=F*eWNr#q6bsqKjy z)@?_aQS{*dA9pU*!E&lkwN%I};u0Hat(InoH{W60IXtD4m3#e8fX+aVU{V|$DDvPV zrvKUL+@84VpYm2z$Wyu1H{n2Nk=e_D-hJJ)80Z_b|57C&-w2hkjm{-zG;of@bV_iz zu_KDeA`U6p>aYn{+x1oT4aU&K5*@DO8-B9+)u%Qj@qjCWzN?9;3Y?;3bFj5UHu0*UyIG^csX))Geq0SKIo$U4{JHA2 z<+5WsGZdGyj(SB&rO%20vs`pcEui}SXcHz*s zUIoGZ@EbE>RkXo)&zC~=G1xJs`b&?&cz(19tl-N6zjoJ@7j*EQnG;Svo$34vwG#g= zW&EO9Gya=eS;6m2ccM)=lREeX<=r)bUx9y!;MDeh@>BG0(a@&$*-cfe`d>ZQN&<%P z^kGR%2us@#iBO%a^?6q~BSODBS=U@YH~^`V)2S@|Ap>h$vcHf&NX@ilIKO+`vZo53 z4h*#VH#@ojve{>T`?Be4%RyL(xJ`Vm`9#TlOO0x}55&n}&u1lj*d?AnVZoY7763W2 zMnju+pN+x+9jkg49VPfNe<=WstS)Rnv3*c&oMt?~`C!55wmxY+xC!N@jEo&8c0}v! zOxsy&@5#Mu7)&zm8u`qTU(c9gbOrNohz5QxVadP~+(hIA7!@{o^(AR#q zWg&!efx<4j&;Sr6?cUrm&+CXT#Rz!s)vHun$fTw+b*FL*3b^N2d-MgPdX4RE=*?*8 z`3BJPRkgql3Ie7vg%ALV8@sZY%~W!Hva*or#f8EoR}98=KMpWgc0bGoc!P)ShN|Y_ zLVx-`|D(q^ki&YamTSkCAb@U}5zK0wN(QE}gC}|13JbdIhs}_w_3$Q`FdI^tTZ5xTz= zkdQ)Tp1+wzt30*|4$&P>(pzKg@g>z8k8ml0C7B#HYC3!QK)RLspq8y$~D-=aVH@ z2H|yyWbDS(s{pLIJRWT7>%fPT=TAMg)6RMts`oWk@B7$6%d8j3oQaqK$!yUS2rFg_ z&#DXk1)jw<`JMsAXHN0+&UO_BWT$UnAtY{papt%`e9|q&Bra!zMJ!R zl#GZXE|eD`W-ubeJj2w8BCzlNIe3IesG#Cl|Ba!^K`GBB!hC2g3pin>NR@)?k2h=T ze=}U)*`<@#?|==%Qm8Vf8H*~VAn}J4{W=LFO~4H@D^ES|hW7O?RF~qgM}|u%i5JrLY;NUWcQ zq2%13zC1EUI~eYlyN`*nt5YTk+ji7U2YW28+Vs0>lw~3q5@l_t{}=0qwgSOBv+LyC zbd+IySak{3E;F($CtF@89~l_|j)}bD?X==bmEqU^!ngIn&Egh)kbKb0$9yVUsQ6Uz zY2j<~dp=+aqNOjTW#tePngtl#>a+Wa#xj6X z{<9^a#qEc}Pf7~~!8)^y9agZ;PtUaX@aH5=)3szhP(@hvgdpo1Z}fsxbmaz5>0REX zF_+E>n(E>M%G=@WGD9wJNZqa3jZO<4>&_|{F|n#Jw>&>&Fx!E8i3X6xq+QZRD$oVk zo@SHoEOTNw(5=A&6%h}34t&oq&qjJ6M(Ow!{~vj#7hYYp{$jKRSx0yN_wn+zPSa)c zr=4l<{k$0tg-&P#0ep?~gOUoK*fqVKWoqu-;BT}9%xLcrH!_MYU z6c^`DEWrVS62rk-%qYoMn_H|iYRaoY??*vOO+TRR05Q&3sEeDF2z5RvMeYbm0Y38N z`EpA?Mi{}>{!Fm(z-EL0J+^!{*838;`5y&Y5;Q``II#>evJbKEk3fU(it?)-&{YG% zTAK(01Q;~%)F+Y^cuh+s_yQFC$$EXYk#)>3D&pO z_^GW?mh9jmjC?x{9ap>+Kugb74X z4l6lnUz$ayHJR)&n~=>?6fqfjxomb?#?D}4j4rS=)#N5rY(+*gyR|QpeQIfu#VZFN zviTOSO45!22LD>WG`E65OXX6=M?xr;oC6F~5a$Wh2oe$@5RH_pOJ$1CAaqc5d3Q}= zKOz7#AFziqGuonTLoNK|(M+cOp)Q5X(?p=qDdp<6g*Md6hQT%@)5ax+o>WVFMprQK zS-7PipG0-dNaDSJ}J z?Dyj6_F8~=%E6|BZ}IekOuvJe9XHq&7tijZGh3M4*b^rrnZzJF2jO|;x^p2>a6BzM zk4C2P7-W_(H^At&vw{%LjXD+Uif^F?MMS?Vz5Ptu;uiKtGvz?Qkr32RTZW7AvwRsF zGKlmHpk#f|ws)QEKm~?^!_?#P}U6+@ZL36>5YB# zXTQQW|EZaU!x8j9hp@nN@X!!y2v~TKIvuy6cHrW9etoTR>smi6Ryw9H$F$G@#G6pQ z>ci_!|9t6_R##fUN8Co*cA5^kfeKPP&0)xmTisTinVW(7<{XH`>^8vuY|us2Wo*NE zq4s@Lj(GU^cz6UjJB)L1k zZX3qcke~6(?(^o{KyFIaA%aI6e1PQX#fYd97$iqz0xZo&4V4E5mR0vYJ_GIUeO_II zi_rI-C?b<^+e8wR1+KE!yQcxy!D87+g&@Q)^$cxStUR**%83s5lpSLShURlQm7PeP z3A@L!KlzOGvsh#-RgO^A9HwFY5Ih_QxI*SQ6lwc0QX-2m^dZUpC?kh^p4FARcN85E z5PU!sSpoK@#YBFDD_=r{k)4odZtHe8tWa7qH1<8@ivczk6L0KGW+2zE4_d!o{rE1t z5t7LCUB5nLNUg1{UTumu)aH0!ZS5eHN-!XZiNHV_>SC;<6@(b$ecLEWCq(Y~KfDJ$ zbMrwp?rXQ6ql6J5;*De(lshDVlO+(E^TX_BZZou1BrZR3B-3O=_enmpq&?_YaY)pL zP9YUHh9-%g(fDM$P^*!(ER#sbRQC{j&vpP%o}yw=En94BOI#d!^fk9)6wcnoUKoWR z8cg1zw~B&5&)MyFbq%z$^TW>l@V0h&POb{bM{uFr81`r038)Q9BfBH6PI-2AIc?2L z18mDu-QH`P_0kD%Hql=$cXo*?b#=koxC)P2-Hm9JZ5z^Mk1Ru*`lH$2yRIbrC#u~G3wZGg`18S94*b8gTqfg=cz zF)P8f@s-zyYM_D@0qQO!I10>w#gn${X7cSW?(=4Nc7M(~{&Vow@}PwP@vv9ug5Ea! zw_zBwOOZq8QvOg2qxwc>$Ek^rPZm|3u!Ewuo~JQWHl_Ynt<;MB-R>{I9vy2Dk43m| zf9;t42cxOvQ9;3@5^=%&qofjS;XafNX3RupMG^40JV82zmY2@s=J9|n1~7hY!;x)W zIJdnr;BtC#^sIQkppY}DaDF~X93N?II=O(+V-6i;3S7_**8?k(In6oP#_aO7a5}dm z(N&nqgq@Gi^31Yi71TjyYgp8BrMo(#%y@X9C5L@OB8efvk-msvO3%=P5<&r%-&<}c zvJ}At{6$QAv3<@d4g0N_*-Tv(L%jm>S`y2n<|v26_mSLmhT^35sFiH=p-@MxzzZl@ zv@5J()JnCD%lZnO1IH+sbMdlJt`JS~4n0fV$~$h~P^u~SKZLFyqun0_ z*zF0bSy>}d8jw^4^Xqqs?9-Pc;`H_FMRk;%$7hY<6XAqiRE_?#w8)|X!!!_njx8cG5UpoYhdp8qRT{nuz z_j1#4>s$Rrf1d*0_c$(+D>WA<7{z9ooeRP6qg!3^gfPDlbA?F`!zqS4?;VAoU2J#L zHVae7{9;pw}geX8V$=_uKaC_utvIc5iEjtEOJeK6^AIW9Ccd8M3{o zh=Y6I58nTuIbe9a>LQ993aMdT3Nfw@8jcvpRKtZ~R1s>dOZ2E|hU&DyBz;FX8zI1R9!wHzjhW-up2YYd)sn-St(_Vg~ z=RchvoeDJri%w2{^m?wT7Hu@ye-~S&MMy><13Sq=`!z^!_rU|3C46uUPfK4D9rz;m{>sIjrV=-{lNFJWs0E2SwaOn*8nek;>omy8n6 zv??e9cmjlMJ3x;0YzdDy6>45}q>PByFYl)er@VaC$@xMb-YrFi9(*cdA*4tob1ab; zdayzdhk89Z*YTDjOiyB&1Y||{6FI^gt{%St%?8YRjlXJo4s!RsR97u+ERw03eM#TP zJ@{(0`B#{p36R}vyb+aY>6m>IcdDE1VNO(f5>kmV0R>o~0@I4B_b(YvTqn)B=H=Z_ zmpF967~!{(2Yu@>a@XkE1cD&qJ4U!K!~NJ?O6i#(EO}2GDhc0ohe{Yjnchp=-rG zZ4h*2t8zV5t#O}5-MnPB)&~M6*2SnYD1{DY@{Gg5ta+bhc7e!^2Ot64Zh* z(Q^AYYF|y)LWlWLLj!Pt5&&qu=A~CYDK~JOyT9^%uXf)lftG4RFNfy^LmVA}BL8~* zfj&MTKnOucJjopjQoqHUECm;DX#J-rU7emB=+B13)o>GHw3|>LTsW4Pe)y1+bAQIQ zw*ZyqIvjy1uJs(nRUV*cM6^?hE(jHDV4Yli>-jdheo?#NTuX7?jdPnDGdzdZz}lR5 z%hYrVV01wb!e^Pg~9?}&jRBq4(UJYarqnFlW3 ziis%O;`)z+IS@C!7G>=m#d9=SOKEmN;C=p`QCxrf6V5+@fz=B}+tMJXrI6jTbdJ*6 zwqW=5r6c_tB6YwrFJ#LzBR`!Z=p~txZBMAJN_$)J-iu2f4Z5A^^GnoCrxbyeJzjN& z7*z;Y9E@>q4^X;S1zB!OjYu2A_h{hWP+x>^kb7}Jx%+@H5joS^V-mmc1Q*oW<1>>e zJTMSYexNwW7lWWd;hNr2d_>x|RLdaussN>Xd(1(&BC2qJ2o^uF7|=N=V;qFDLCc%3 zaw`7_%eaUpIc!4sGuW9hCV3_`Db#!Xy?!J8s_uxxv){ zxkg0>9>4mJ-)Bo)e~W%(uUL8OSjBzP)*slNd=EY|%kDRN$1g47UfZq#lb>%d${(bI zKl}&lFa5#4djD&(y+@{f9{+0U$IEZV_dAmIs(2v&1LM|h_4-=d3^yZ$0Y#yLFi&qu zgRYzqhLIv&4!aKRt|hOMDQ0j=(41zkqBh%ZUw3f>((TonxSiSZnEXKK?lNjLV6PRG z#anwU)@tQGzk@_h%iADHe#5qQrlqQ^Djv>=kJ zdCk&ZxSWrC>*nYBk^S|5-BAHvJf$L@R^=7^dWO#tw!~n&2HbQ1u!MP=2clKteUyKl z#->g{fS>?@qhAQl#|onJSWnjRV3m|0;bK_add4QA1H$(xU@rkvlAG{$AdAux!REJ{ z8TvP0n)W03O98&R`Ib2 z$$&D7WW?L5b%qNvm+fjA>=ACl+X^!~$aiE0uuPJ2gh#M?iD2c-V9^oml%Zf1%HgUC zarnben^1qHKP(|sUiycA8dj2Xd^h9{(N?#3X*!d0eO@E&O8aJ)l)2pJ44>p-fW6!D z`=o>2N@_KDjcpfae~DRR?@SOULW?fYC+QMW&QO~L~Z1>qKmoN6cu z!LV~Fe=zi%>n$VbN*lWL*qeCB_C`iC3~@v5)}Tu&lD9BgIGecDI0{97=sGJd!y&8N zAtbW05*Ar`92!}15gu7RZB`*$n1`#8(c676fv8t7}j~pl@m4J zAnSDA@3TzbbW;Y-!P$D{=FsIa@g2o^Y}_jMWj^kKs)XK8^M2gD z3!l=u03BK5hvMxe?hz~Vgh#^6ONLY>T`fiTDHwQ>x_6ote-V;G{c13Ecr(#%BWLB1l zC#kv8-1a!qE*4hFx}kC~7icKdU8Qd)nT1nwDAKuFr%HRa=ElAona$od>C2W=bU)i+ zrWdlRlD){o-`6X*A-vLQ_9inM$UTO>Dd6%9&gZQl!tBxS*Dg@zy*&U`&Tvwo6rluY zv;G=4fPb-~1Z@wFe8yF_Q%SczZzw`7X$SD>ofWUs6{*u35{r^_`sozxN@2|0rEo{c zyFa#HDRIIHu`^Nv*=jmFx(1o~T}n0-=}EZGG1G(uM{ZIFV$Sxm6N6?s;ZpJ7+!tHq zd2!cjub{Kg&tCv}d``UTy0T?bTNWL>(%`)vd2GHYm1g)fxg|~`BHyg7h!s*r@6dTIZpFs z!(89!rJ-sO6QNDZrqt#(Lr0m8gk0HECOL_ET_QLuXO!hEO_98Sw~*VRyq=*@AVvG~ z?wfmrYhg6;1-{R|!8grABOgC7&#fsthH6fUux;mTkqx|5Gks47M2){km+lAuXgmE# z==FQ{r`=!r4Kt_sGxTV<*E(jTTHX3JdN&oXS(<wq5_Usr?gWf`LvP*`F%wPNZ8K$OeN#@i1sR@eKS8opUbW8Gm+w^oTVuPwzbkO%Hi<5UZZ1%iX zIj^LsR~uD5oj;T+;yvGSjcVh1|M9BOv~h-$95_W1)Asd!xJlAB+hAl)c5l$1J6MFo zpJAuzFxuUo5Zq?!b1qv`!ye%>-fY>SWVqE24Odo2j6g7lsdu$jsa>R^y=^x$BDC*m zd9Z&aAu+UQ@3~|e>@ylKwN~BXZTse_t9JyG0gP!X99q=mtxAGPF^jndJVlfAbnIVS zgig)$Rb)8>On6&j9=wQlOzfs(_A@QFg}f&&_<#?pMTC0qW1ZBK&wtKrq9Q2#6NY}w z6;jQ-b2=vK-mc>NaH{5-re9}X6WlgiF)|1HnAv}W@zX9?cNjT8@Lw>#JZ^f+H%(Qi z*)RsmPbDn0)koSz-Ka|$BciM$JQ-r8(qH_P`r=LX-_x9|72618OhA-W%Lt{v8T?=! zi1nK%zUay)rp3lfH$(1kHlwIAuUXtHC0B8a*nklW0z}^4#zn98s!Dr{mG&ZUprd{AP5iD)=*Vy;*qeMIcfU@cXN2N!n8Z-d z$zjBT2_p;UuqfscIDirpv=-*EuV*HKJ!8Pbw5~r|Y#`b>Pm$cl8X79HBNH8<9K zWKQ;cpw|uNdO})f-n(cP1IZX^MM6$^MIvX_0%&KTz!UD4rZx>W(C$q!3L)Q=|)yUA?) zu2Up-!^316k{uCvI{6uk&0BL8>1pMU7dp_ zLmUqB%Ifk&3+HZS$DEi(e<-10yb0HGwQ=;=`l6u-wWJ-u8~X-=xr$rl9dvmm#F4Rs zAzZ+xCAULamMzT>>#8lZcg?{^zqyU!(xK)bxRXOT$(~chMVg1nGFOWNotuIP*k#+{ zjtt3t#NQ$2UBn9LxEpTT2HcB59&aVUT^2B#&B|27>onLj7};L3DsT_~Q5+bM2u63- z10@)6`#`JanA~NFiqyg`_N)`#O%I3sfwFF zj!Av#VmDv;`j2q^${0z6P_4g>=AkK{Paex~6pH=`j`-7`(X9JOC|y$RsorQ&e6r6q zH()XyycDgwI*2PDGh{dm=0I>|3~&?jN*r$(;w;MZiO@*!e5OYeI%zCy)z(_WGr!US z1eO`;)+27$ZBhPf8?Frp)ar$BLbY~uiS@pTK1DE`bs1e$L%A{Znco9(AA&{z^oEik za!r|Md~sItV#$J46C2O)&bAEyQvvH ziMx6CE3V^x1mA6RD0t${N}6k>+xOTQ3h=BkPQOWnv-Raw?pK?fCcDBq!KUlsZI-T1 z*+>ttAgVK z3!^C%uU?(X9{C@-rNy0g9!|4z!`9`zqh{Y_V2Q+j<)CQgv>#6#c9T*4u9GWSDhCO! zh92K1ij43?8jY(&<0{d(T4`MI8dn#MD^=r4)HqEm*)C|W-XHG>0T5*w1OkY)48j3K zTn0hG%D6o*=Va4WqH#)=UwEg`Pe#TnLz{i(%F6C5x=H{tlD>B!KkO$E_2X+Cc9ZMc z?>b$Cr`EQc;Cf9r-4W9qR|({ygia1kRm!t!*5-YEs2#Vrig8Wc8JE^eeNwE?8CUPI zZ0df4*{g|E+Nw_4sy5oHHrlETZB>M}s#IH*sI7|DR^sjJTB6wiF=fV)fFtX&uMagj zt4YEn%2|XFoxO8(WX;z$9NV^S+xEn^ZQHhO+n(6T#5OukCKFFMZ|45tSOQAWSJken>$>*tv-YV9?{g0vmmN^oOJ0FaF`6Ifg*+)SNNkgwKf-*2e?A7h z&``Y6BELxfp*TeEmXI#a7O+mVskf`(c!6lSon*w7DYjR(V%Xc@^BL598O_hFiH`S( zL2Cva3Q9CX0X1KKezRBE_}ZakJn*!xchv=MwU-vsw{*s1VB=+{^YEK)mpfS!fIo~y zhBha@qV7EFuCFE$$}^c_p_(mBy<|l?jyt+NH5GWV3-w}f&=?Q~Ayvq>BtmP~YB4r) zCf`31DPhT~I*8>xZ^GG3+u1iJeWT4H@f&|Q4NQhui+>S8ymC5xlPsxflSv7c{anhM z)U1U5MPD|sg&rav880q=r+(ypp_tx50&a_y9j~vV^z&-MdYE8i&GuI+WxZy9IrLH* zAV5}-_SSSgEvo$GxxLzk3YbD6r z_et4;t-R&W8)`mdm_c_zE-c`|qs(=k(h{V7ia;s*<952;!x%4K(7PM`%V_ye8W6?p zqCjf7v-P#ocb2XN4g`0$y?DY*jN@OH`J<+zR~aOnFd%j3;}-`}wd1DG{F~=0^~f9? zNt4u+Q;cCtC(;?u-~BGCuLpW(7{k9M%V?V&s~u>tL#PqjvUjS-m=S*^K<4?UKZ}qg$fOvCOujWZNl5y5FV_)1{Iy9yToe4!ct%oEOaVU}qRFhnf z=9npV^w;4(=l_12;D<3}4z085_46exv?2($1Y2{|M3V*Go!M{O>875yhGA~XMo(+a zni7P4xL@$8fGe|Vj}7FCv&qT9k_wyS2vMq}q{I-edi3fGTOGJO!u&74&06rtLU zNskQ^R|_dVBZj@<< zkEMREcW%-OF+@uWnN5=hRAEOR@?6p6Sfwl zy(?SaQ`=RA;dIky%!M<@f{s4-C7Bu}Lta0T?1t`O82FLbHtAOkMblq^){RvQ#ocvy z$4&p91z(diHREJg;kMAx7B=>u3HIxIOI`CG8>yCK+#R>w%X#?vI{TQP@cVpE`jV;~ z36uGc1CM7Yn^R@<-a{uc)UnlmeNMS1@s_e}{ANGj*uJv}pH>lZ0+Wk|t-vBqFRwyy z8L{^cKG`LsMj&Ks5#X+7_}aiTmKG)0hTLpOMh{cM>}nA7bw@Zf;F6;f|6;wr*Qk3+ z3ZdJeB5)DcUvHkUO=S@d(o28VoX)_{*ZE=o$!1{J8c*g01~q1iIjx7=1jT6ob5gw| zE#2xgFIRuig2hjg+CVA43rAk~knGm46Z zE^0JtL_com6a_inETw_rR{-v9_pPeJc^(ocnAI_1clO!iiR~n?KA5P3p9iMiH`4@b z4W`8jcpI6gqkQwyE|JD&^j$NL3Y+-*wpkCEPE)N3+g*a#m#e<1;g6!4Y&c-7x0nFx zyzC){3@NrodmQtwsFRG}C+ez&^v)g&EtbyS>Gi8l*9qeM0zXIirLM1SoW8rbAly2R zcG_*X6i6;~=IRuu!J3FWkp?LmS50mZ_5^Cj#bu=|DJXpP;IOk zN%89ZS;`Ex5z0I|uFCC{wL8laXhDm@Ew=c%t;>~CN~GxGjAAIwRcEH;-ti5wbWO^X zOD5@fHA@mF2Pf6NAzNDkwc2WuWouHe`85Ji&-1O0{bh6U(EIyHgk&Wn)~%@Wb-*5F ze{)U!EaZ1c&MSNs`tP7@1!6bJ+LyNTJSG0M2@H}{&H;F~gtqw#cRfJF=%Wb)KLyp5 z(;if#suij%Z2|eAH8y33wsQ!D=xglYo8zCI>ZzZd#=?gg8S?Lt4u2lcC6|t{TfNy_ z2nG5)g)LyRVyAk|&I4S>`+yqmhATG&;jRU-E*L)@M+JAMWco1H?#~1p1km{E_+R!X z|7=y`=fBH*#Cc#gSnqklukybd{;&#YEO0Qlus@vK^BH#ySP1a{h#QDE7d-Ine)=u? z8>g4o6o?SxQM6|$Xn*R{8F8=R;3+V#o;kgf% zo`KQv!UChORo}CUo8ekdetmRw-J9 zX}u{cpdSxHXnObMSL?3Zl!&gmJ?z3SWZKKuMV--pha#}7!1GJ@6+Y<(xwkSo=?}0u z?223|wStZ9{{AK)s%u~L&|kl16=~FQp`VF^W>qqhA|_`?PTD2?G_^w<@e?tDZJZNW zlOjYZLbVZUxzLi|b2m(&m!Te9CNA07?syelr@dt8gv$>tiTv11kE9wL*#Ul_`bX&m z(-!EX0KvE=eIAvmkSB?I2S7el7!JCRmpA5u<^7o$sRL();AVW*9VPr`ikr zbf>n3l)z{9D(0e4*Pp}Rtp!+QaafG2C#B$>h&3C{SRRj1FtDXL4w)>ZUDbr%mDxC} zmq>c!SuoqzmoCM7>6PTW;mu! z#xbM;PTZ*Tnfl(?-vSNzMDz#LJBURG#$YfcE?Vrtm8Qa*_9KC~FPkfAfLs|xkFe!v zBkW2_Ww%KcL~4&2HpH~yleyHtTPux7o5%Vrq(zNSSaFn+qslpBxa5*%*ci9UPQ^7h zi(v;Hd0oOs@g7wfQypYJC8q(!#rxa$_9|2I)CA=+lSYtN7-!;)7K%4}Q!xlDUDJF+b(x8JQ^Y>e`4hmgJwO{x*!oofsHTyX5C^z`CjDa_QKO#^*O zo>}yqIYx$>^qH5pM|IeJBxN|5cQR0O{YBm zc7uVXv{n=wH5OtmZbWp@7FW!9gLcOCxM8-VhM4yK0s0jg%ujmhhkG+!Y1a}2X--w8 z9j~;|=~qqeR(}|rlpA{@8M9)cIzo9K{~F0NIwe>%Qs#cH<`oebkb#H6ms&^SM(Hjn zgj;yDS9NzbowJ7aG2P0d(%$2pMP*ABshd^1FWqMVA?vd5k%kprAPRvuf}XiO2e z$6&_f2+HCzgt`<-C=cMl-g076S+XIUV&WVcP@&1{Y!?y%6Lbz}>2nEHE(h;6i7-mb zFN0k)S=Fr2pGD(;^e(pD!xd&}qO(d@(nLeuPHK%o^Jep-CSXq$LI&gmEtt&LlRdI5 zXu&47l}YXVq>87iJdTB^M_4E`l@hI9qhVx@KuaNwoXqkX6T5+LXX(hbH?meNjYDCi zl;!8gfE;Z1RYMM+rwW^K@~DxZSa-Heq-V9e-6z4suto!oBiZTkg_EJuADlY&g;tNt zDibAYqiNKyk|sytCNO5*=+TjjNHmFC+lmok7FQ8QLShLAu$7@Ilq!u+YC%0G!-AvM znF~nX+V3Oc>krZe5sP+1`IXiaPxXN-2hBLC32pO&?AtVxn+u9Lkdu7^tpZzBd~Ge% zXfLE#`O@?F}x-@EJ9TB%I;}V zQ|Hl(&nR^y|G52D_}l&QVSUBhXzb~B_f^~CHFD@xKMpJ}mj2Taq8Z&wb48boOp=cX zG)K3=vV|ApW%$V%Nx?aW+ZGNiu5E}VEyd~i#>L+BMHRi zuV|CPFHR}2iv7SG+Mb4)+%8&1xMq`I_Gwa;BrMC`JHj=KK-y(;=h@5Bv$h(Y zHvZ}s$-G&e1*Ld?7OfDq-VUr}+P2MPAA8d}5|a#o$EM+W9gtXC1)0*?=uLpUf#fm< zCQn4JXB941IQ2(>Q^|z?$=Nn?JFu7iifg0BU6|W|G6_l)9)?1DR9o6EP_jxY)mUi3 zj&`C$q%p8~OLZNZ%uc9-NqodmR1-AzwpwJNxD{6uUva46bH4zF}IbsqKFTQWaW zS(!ssrw%>Y(V5)iCOO}dQXfB%C^Pvw1!em`%fmr>qAcEdVBSLvRwlAuz zgq7>Y&Yc^)fX$U&C-fbTRN-dbCJ7gm(OA{7kt9TShE4v&UwbNwwt#a5IweqBo?#X_BNFLpr+-O#a_{29dyR9;N#h$zyRU5htrYIW|2uquTF)s}3H zwSx_04=BvrIHJrrlu8Ev@SA;B7&U8_hr{Pe6_awMfDXC^d@c%9ld(tMsR6CD0o~kR zTtA$;q?qB_H?&ebUkUs^n7Y_4+H>fESNx4i=}-%>cBb_nM8^Tm}ZGah-Y{fuMNC&IZfR}~e) zANz^w^Nx*IPPr<6(i3MQ1a}WRrVQp2v8~TMieR5g1UyN+iE9S(M`t4wG3dt1qTdB{ zPfxl5!kB}0s|_C*)Yn%}2^i_@wPdjSa!B)QlkUT@)hl0}`_*FB$sAb}%RzWG>%hhR zp)qqmu^vvUr$2JQj?)mBbebW>Y z8MyoR!K3lF$4tY`C~*9B$3WS*9VH4DiSTH>u$jMBU#0(8c2BTpMe#{My5Q$_TP;v5 zTWH6L+n(;SnA@R$=8iyrD`Xk&Rcl3fA#)bzY}>BZl^@e+YmH)JK1ClsAh3H*nQW0* z-Y^SlTs6DyTFE0pr;Bi8V40H)7UMLNr(&aJ6Bk}8qYup^IiHmFkr*f&S<6Z{T2MQf zljb>qRyF5pSF;TCMd>Qe(Y9BshshR7ndQ6XcvBLF@xGJ`O6R_%Cx6t1AD=4Y8A#IK ztOe^L0tjMD^B)QAl6_Ej z9Jo$#bSODTCsC&HaR>#_9 zs^*i?on?@HL&H!S9+Q3jC6SSSfqr+kkDyH>ip&I*5{6DiQH*?Tdo<@otYjw5%y7=j zjt9e0Lt}r8PZGjiCeN*(6ik`zwH}q~9=7#%;uWln*HT^*5Zp3vD@l}PjHIBM@|&7> zaT@r=$cwGpRVE2;=zxX*;1dyox(dq8+~|W;R{)v41c1|&(T|*C%?}XueHMKTyN_8G zVBWZiZd32-+t_D=0Es0^9Bk1uc5tN;in5{XQ0h}%1yO!J?I?6%)07ySZYYjZN$6r__?@)Ksv~YuA3JzW;br+kS^Ox z^4P4k)wdE#g&%qf*%!rp4U3jt$5z5art}?(5lPTVvTlv{dC+a=6R&V~TG#rt&;FD1 zyw(lVm%gF93GRAM;bLMJazRD)qR^B}R`_|FLwF{2F*bA%2%t_X7zbIuA(x!0{G4w~ zm9!j&uG9{Mcxn|7dvXf6`u+P~16T=v{InPFO^W`Q8$)?=qTK8f^WI>$M3;ZZe%^>@ z7Tm)*^SdxrwuvGG(Z}L#V^GY)YjJ8uB7`Z-6JjfNd%}#B!Ip(_*@~%(d3YC&z$J`Z z{>B-O6CLXa{i26UB*=lZ0JD4uYHF0!o^qEs;1A2788zQ`fYq%5 zi`f?T+#zyg*Ml_V@00h-=JN0Tqq07OmWLX^cf?DGh1(is7U?7|na&*&a~R4^#&v#y z^xQhFKl#Vo7#b@nWLYD*NWgMac#5HNQ=$bf@a$Z|B3OtCd=fRN0pGg%$#%fW%n*(8 z;5`9`YVaD0IRO5)hrafOX{Lhh<;^_)5p#y`LkqIHs5)@0lnTD}XD-lv72L;1{OH|3 z$T+3_2w-iH0*O^<(??usf5@Rdru`{0vRLJ^E~YrrWIW9UER zX3ntoyJWMav_t=BWG{R#WxuOvw3~eQ+dgPDZSzHPZDkP-_pB;9ycnjG&V=do=%lkn z`6YV1-E(8bH=tFSGO@JlG5A26&f0rZOpy45cPmS2^&Um}LzViu*hD*>O;sx1B;viz zCTlhQJSlN{QD*~X=|`jI??STF1Yu-BX|jIh!0jb9>yZem*%g5Ig6Jk2B*)bxzc=^$ zzEJXX^RviYBVs~hZOh9jIoFSk=JD#Z%Rlk#ojJ{O3EH%ge9hOguv@XZsAL)DjFLP6 zJuL^O$r>}y6zAwX*=^m(D&%yZHY%?jBx9LFR&!UTg?z`j8Q}PIeOIO6qZDD12KZ1# zIPk+hhey%7n)E25%|vR5P%#2M)lyR44#|=6z@Odvtn3apqCasH@d;5{{HW!3^5rk& zL*N;~40j^h=RaSl4z1@8DXybhw|I^YK7;+cpOVph}mMWO?VFm!ghC4JbS+JS?=D5ogoK%LEyr*w6>Mx0Ys~PHue^6|?87*b|Hw4q4YQXn`ZZ7jowZ6W4-&Ed%%62# zeIt))KMLnu>uM1SF~{3|Vgps)fF@K`O+TB8^LORODM1!GL2JpYegPVtQjjdlF#*cv z{J|O#8NW`p0*5oQmm>}b!cms0B2De zDVK_vnV^2l^#%}+q!qx0i)}0>W}JNqM?QhnI!p`%ji2CZxAdU(x~@%We5ohkrfG9E ziExrc@&FO9KS;8=(N@peH5*GI&KCCBAIj!9%PI#IXxt9i!L78*%N_k0ew9_qJ0$Z? zHuielYq(Afcqg_PXUL{6wi#BNQ)-NejY#d+YE1PCS}>E=JBWL*OCfKwmb8pfwu4l3 zq*$Z-b0~ub%KH(>O-6_P1DjSZc8eR?kbq#xuv)D&R-2L(%U+>;$I_55T3x00z4$XG z41&19_8O$w4f|Rdz=F(H^~5b??gHybiYgP*`0LYAN=+d`rF*8i#tI}qxv?!fTV8J_ zcqY>FE32n=+gOvO+s-}NI9|Zq1s4ey`UoD&wtmlR%jbn55DvHO7Mh$UTt=wQf;{$S zZ|6my`^n1l^3*i(`qXRCBz*YfNL_iDG5gPm848J9FN`c-AR7V#;6okADVcZrfc&J#E|S zodmA_xST~nsS`!*ImP;>HD0POGX;4sVHYJY_ye-Mjo~pj%ny0#*4{q$niB4r-DiA= za>jQLoL)ucFc9vhPw>W~c#pRwbIp#aqhj7S_LwESX7`M5b)XAdbpH@`Qn;CWWXH-GaGT&P%UOKeA;P5e+`(@$X#R|Mbz?? z?ux<|wm|}a)4!JY80^`>2oJ%c4WvEGm~}MNoMolq_#U284c;#v$iO1ayk)M*-`tI! zx;7sqif=N!Yh{T^*%~s5YPB~U2uw^GG#s!~dVg0e6cx1#B3KOrGKLXE4vC?;&MaT; zobTpD#47|9@S#rE+NwJFsd?q%Do&A!m!b0QBU$W&%0pPFrInB&xYJMIL1pk%mL`Bi zhNiTyNRDOyEx@}iznl77dz{^pqiV3f=+RT+isgc52hHN9B?oZR>%+I-o~J1Fg7Fix z+~6h)4&*<7q%K#^Oy$_+iNt=^-jdGv=*;hWa4q{hqCGL8&m6i=&I--8<7Q+S!FCS_ zS#EstMD1ao15y`qr1y?rJ1I1@%JE6(hWPqgHy{4z5>%JWNL&SQtjpwS-+DUeJTFLyX`BLZJX&S~U(*A? zi1W^EZgJ_mBOqu_nmCItxV`|0(vcla(CP9;I)3-y#M%zbd^R5*$jo(?mo~_#wyN>~ zB(X5MG&!lR3ppbQQOtpeKd@mQoE*i%apRG~Wdas1wR#6d8y}iLAUYU7r&~s0Fz6g^ zL#oqi#RwjPcT_>XkoMeZHm;|A715I=HBkm#=+4JFy}<@=X++mZ18#7!B$Qww5YtvY zx%+BE()!6?$P6al6AEN!C{m68S%nvEER?^-B=%Aw#M@VFm4KV6RWC|%odmQOAJgz{ zZ7hge>%JUBltxiaB{}3hWsuRV2^QlMhPfDRLN8EofwUVfq#>U2Xl^7ieJERA<4h$V z&Iv=+Ym3pca}fm7>A}hw{kYYuv&UA|jX;j1(O(x?ml*PlT z*ab_6BY~G5thcY=?3%CW+~c62?A0<| z@-#?iC60V8o_GT*%VLYAyVoR~nc3$3FejOa1Ig@0>`dTh=5+`@kPg${_$H>hJs%R8 zb{J_ajs!DE7Y(KsvrR>jbZ8mD)k}!Zj2LLf_|bDLTH=u@bLks4QDl4J<0jX9(&ELU zr3Ryz>1ZK`?JF;ls>%SUY;GoM1kAUCSiJbLEPq*f=#GJKq9swV%Xu9ey>d6DmI_#I zVgtJ%H$0H-bQb0EMSH@?WQeq?c{jE*F%8j^M_kGFw4Ycu$`E-9HN6o@Fc+NG;LeEW zl=XNK^EtF80DU|uq9ru;5hUVm^D5aMW4de?H zLZZ+vX60WA*@+=U6lYP&LuH34I~qT_02Kzc;~T(FFV?$JEzMAPqc!KU_~{$E6G*RZ zmh8q}fn=*V>z>GbCFveqQ1v7a+9%+p+mv>+vG^GZhvuq}2$f1l0#>xLZmNxX6SPCS zW0F`;7F3gbNMijA^NcHaz{SKOms3oYz|XyoRHce#XEK?l&=?ThZh|joAu~~Ts9VBH zYchMNo}CiszyAL3mq!$mE-_^$*>N2{uz?`R#)VG7;NQ&>N(!5E9QDJn&szSPV~r42 z_`QOK8pXs^VyqKDV(9)HvCnz|C;Gn5f@hUt42CDlhEls^ZK^4;uLuZJLgs&y5dCHH zqgkdDs26(yuP(3KwOKs%F2u{4J0^W$Xo_^lF2!>{Ive<@euDvoQ;d<@T_(5mvfJ z+0>S+FL4pV=ziZOXLLoUZiz43)v(Sj$u!+kbe9_|x2yIp23PN{mnoM^MWxa|ppEy*O#uNnAP`!yOKD~GaSN4)jdo0?vMz`VO(A&96aj{Nse1MR+(XP^m7b2 zQMk9|XnPjnCD4=3o^nrkzW<(b8&>X?>lYW|Ey?O3f4ev@oYG47z2;u=;sb*#&iL3|kb#P+^K zn9x`p__0jG=)uEZU?fp;MT=)}6fr-5g`gx984?(gqDN4wQ@AvLPm_|92O zr;_O<83cm(UP8rS&}c|j=a&~(7gm-ynb=r3fPsV!q0k^CiIgniFd`_Cq)nr%vbw3apyAwu`?qxGhtelie(ac5V|Sg5A117a5K}-}gj942^(vu&dCJD^;vbdjH+0n5~W;lgG zw483k8E}X?k@8KdRH%r=xIp}cL_1c~iRh4ADwRwtT2;|tuv9vOSS8(-dmky$xdB08_z z^>U%+TR*UGNH`oWvy9vwey-Cjct+<8 zdcAYp<@SK%!|`C4j%`yKa;9B7tGRJRo?I4lM+|u9&QqhQS%Y8gMx)tye#nRa;Y1WG zX8m^Oy<;FHBczuo7l4T@)u^qI$@kAkBor+Yf_|bQu?R9!7%?&IbEG$W(}?UqI+b)Y z8lG;|;;+(a#d-xZ#txYGHU4h`#7Q7w(UE=_$1#@7#-l-zYl7Y$WU^n{Pn*g1FN8qi zfhaSi@>#wx!5E^`95#;8kuyqXIip8PP0%PQF4z_nz5dV&sZ!7Lrh{L{VYeC^99=3_ z%W=o&aXaVug@Lf+0JK*~JS-85QtPlCDy>T3-DvI$`lPi|oHfVYXH9{RvlgGR8*?Obr5WDWzD>t{Zx+6Uhb$nKi-@A+{lA3Jx-t8@)K8vlpjbDOk(S6I^%MKl`Sj z;CM2WhU-D;^{a_gg!QZz2=?bi2pBAKbRZR6^4Xh7Cls1$lI2-3li1b=o#TtJK{2HY zPQEKxVKrYKp{)oqGY4|@d#Xuql>R1IRPz6HywP9r0#dk!u8Z~r8MqFn;*%8~T8n(= z8~l%i%2CA-EkzHEqjz(9?Kb8hAJ{bqlhb{`;mN^qNXHnMAWM{VDe79_K&Ti36|%LC zN&0eqZ0+_%U1RZT?=`3GX0zQmLlXa6Il44N2~!rmdd|*)s}i&LmEH+SAV&S6HMQ!f zeXF~JB5IqWL)9}z(NAk6DaXbEs(Rgg%HOl3Nz|%1d4s0s9z~3bibT4+4dp7}Fcr8h z8-jmQkDcvBRb(?@gJ!adJbyq7CI1R$0)rVQ6Z5k%a_H=x-{FxR#3cb6D~fFCdU%3c zkt%g?QQtvKkxqiX-z)q+E*n`WeQyQWSZofHRrGu-_TJ2^{cJCxzxJ=`V)E&~$|5mF zVJKp~i#bx3)&}nZK@^!>TWH;F#G+Hn@oyFTkHtVDOfTuqKB@*p56mCiuw^oJ3m0Ue zyVqZ4>)iB0{{PhPpK@lhEqE~w5yfGZnvb8sPF2_zD z;ps~Hpn)P`tT9}9;)RNBYw52rIrD|clBmngPcYKeSO1y8CT?8<10u92a^)=DBGoEj zA*6K;YT*fULWqB9sNm9;!oQXOzbXoV*)EbOVTbFNS=03xmhaeZN67=^zY&oE=|^aE)IIsOX%H;pN7<{QzMnjoVu z=ZIdlP#K8DAk!j<_5O!cHC^50dS)=qWo^s|X>DOuf5qfQ+^21SA32puty~wJ1f^L9 zZJ9aTK+JUo%bIDWS|wq$lDbFy(ifE#mNw@sd$cPeCn6)kTSuJ=89nIG0@(e_KP{7otP_VNJE0iOeo1n31nBqng*vjXI^(8Oy34m zO-5Irhg)qR1WGMcU0iUc4dhf;xvR9fnu~a{)o7HA^`0ea-}LbS5rL6Xg`<**v(k;j z7L(Cdm*bY3@z$S08lh2IrDK|@aoVjRmY|>}H@8_)7j2Vl|*G-W1udolDf&Bb3} z)owpp!uTy8a|qDtqS>46w$kcP&R5#%$3m1mnsntbpwqbgVRSQS$o5w|@VRptIv_(v z51_?RvP8b7Uk)P&G!QAa@PA>8T|000pWi!tzbE)N*Mr20m^JbKLFNAqj{hz4B~O5> z!|I}{vbvI*3I{_=Q(F+A-~l8mxG!kWW6>deBTAk?Q(<+1m8G?z`G1NH05Jd1@2^JG zI{3f;p@BqF<# zR01L;|c;Ou?=5HfWI90L5|#aul0ii6S%0HLlJqQ{b)>A(2)@*yDY0* zR8E?hP60>vQudb}k~AcBimBJvmGM`$AosMA^Gv2e7dLPwDQ`q)1`5PgP&}#MnbLA| zP3&ECc9s)kB4KPvhBtRdr!>Qe-LF!SQd(X`B^p^U+>o*dx3DxK_d=_~#-FTo2m?l% zK~P`JvpgUEj7V%Dp7Z8PKKD5|)>3n=J)UZL-T{#dMMfKjPR>|N-&c^*NM#gm6DfmP zevt5pG5wS$(3^||Z@|%o7DfUSMq2);){u#Fg-GW6f|X18_gh;4oeeMk62C^d#MSw+ znmEEB<#R4^m_;wIwUUOn)GlI&$Ix_D;y=SN1~w^cX5elXW4`|8Nc0yUSPF@ME7~Cf zBE}MC&L#57&xoJZpEfS%gVwvGy{kcVCIR@fM$|=idzltlxWp0 zsM^7*&bdkq@2o$Y&$bj_3r9H$ANvhr1IIQV!;PXqe`D1!V^oW>Fn+0BCvh{tHnIF+ zE!Y{36mKaV@}$^!ybI|QAYWLg1|*EjUss{TizcGUpS@vD5{%5J?L((ane0JbA@SAg z#A|a2lC@~-eQ%GG#^N>)r5nb}B%GK|89}X}q1|#Yn@C!ab%K7<(64))p03wVV>fA%_ADEh11SwQESa z*IloY4+P@yRkh#bYF@^$a3{;^ch$WrB?wB|5LhyD{)&|n{SN}@)*-A_>mSND4{d_V zg*4r=&0N-Nt&aF1MyYuvDYQ%XQKGE1KLNSup@v|ij=}#-aX8Sw)I@97TihLJbGmU{ zf=!_+=>&r0qRm&BylP6dE!$!BgOqaP8yA{IEk-RDa8OIBCrXT!>;FC%5}TpYNW%Gc>1K=5wc`SS)Ntde9mXF=3bcfsjWKPYq`{F-T;q^ za%C3Owr~<2v9;{NCqB+R90&33Cu5p27ZH6{ND4HGBx#%|Hw0e8|R{qV}~QxSm%4BCT5bn`BWb$Lmy1nxb3m? zWpkrAv)Y5%Pb!&2`IGs@u0>{HKL8b=bDS9uN+~u8bkvb(IEd-%6`g`M9Ml-^&Gr>i zkfce5KkWgcA*T_Ke^;*|NQUdCR=%qN{rr9uw>uvl-wn}Ld%#dapo0cKNjJ4zVAk7qv>?Ji^Hv(MJ z>Fim=C2c15>>c^TB1U4=RzTEg6Q-b40y_L)y>vwkL^ZF~mSv5M07bdu;?QRHbg{$4 zNg97+Jo-?2J68009XBGM3ZY5pjEq6sMZd0@VidmnSd8F|E)CyniUyMe+DV@z>+a3B((M-Djn3wsMdXJ1uh7ll&^@ zS5RppQFmx9E!1i-ZKCs6;UUaJuZSF98ak`6Ax;B0q7fR)ntZ2iqKW{MzE>4!Z7x$1 zMg|a9z896cE(iAXW$Mf)pzXYj$uCF-d(Y!FNSX~rKG9Q$Z%V6FwhUnrV4bWb4IDiY%iKX)>;k4G9|wZEt$1^?r0Bp2XnWHskasV;5M z?-X?r4{Z5%I@PDC_cZuSoRHJ%(oo#8cFcdMusMJj0JseF-7YxqvaaznE%H4)Pd{V| zF=V&D>F(SeGfH@&*5B?-zz{Fy`1Y@~5$j?tzV)8_z_ZM8_r6_AhVo78a-F&#(EX+^ zr1?OYX^D=~P7ht}LTvz(S77AL1FqrBG@L9F&}{Og&HyaD^$}rQFZvtoYX`S!+}76^ z=FvfE4`2KBgB`i>aM|d%>9uvO;yzo zIK`V2>dZIs;G5O<;wnnKb4iju22iZD0lzoimZR6hjSi6--B+OAuui9#gR$B?psbr*~T}{kuOD7`dn?$uDzbt z1Yhn~fuj9Oo*C&jD zKn+US399xzvC!uyKOP6MQjPT}-Z%$s21*#?$SD`M)z2Do#J$~nl z{#t8^fq<_>8z2s~HG+X&V47872iN~FG1J5nEe)}X0B-FkggToC{*uUlEPZ;VFNQZf zE_^N$05R))KCB51cs+0L5*=U679=+hGDQ*_L!+FKs`ZV_fkfgEV!J(FA$Z{pg+8eG zRb+&oR-!cvaCn}T+*R`lt37u4b+Iu>0lUcoox>S1!@!Kr<;)xdoZ8~%cP8$u{rLo%$RBEc$2a-uFMhy zb+B1IHqbv2z%EZMk5DImwGckX0?Bt{mM<^89>^<_CB#nbZ10s^C zh)&?q8c6i`>$0Fr>fQ7&YAhJZ;wDd$tPB~8=A&{UCbW1lliLyNiIeugzh(bbr`mt( z>?`L7hm)ylL%o*aQw<$lqOP=WnkOG@dwwt*3QWH_suz<|PKq)|XIa*d)VZsL$ka4^ z6Y9g`x~yO*9g%FkljP9Y2M1T2hG5hTUh!9oGrcYRUI)Ta4PTBa?PQikbaMw7J@AxqU9_-F(X>@0L7StV#oQw%a*fvTd7vI=!)95nT) z_ALha*S^hSxmsFjr_Uq;!h2U+-A25G121~_+(X#Fk{PM1+)3aH64UE8)3vh-Iu+Sb zMcDckDbR;*cH!^fk8f*1*@FI`k868>o)64=%D&)*BVq$l(pgIx&Acze2>U`t>l2vx0z;28d)|At`8ZX{qjnhy-7P6WUG?m)p7gffBpFtgB5vlejA+ z^K-dP2nrds?l89R_KXZxi&chrrM4?c@_;eLbv$u|Wkz!%oYhGmqB1dj^6B<5ykHeU ztf9t?{yAN)x_?CUj3)Y=eF6&{MKI4Q)CW;UCx-i^C1q?Ff)W-yE=3*B?@Osg zj;RbTX?-@V`Rzexr~W={@aF^WnEgrA^2t;QGKM)6kf=05@figl=v@W*C~bAuR3SP5 z+y&F^$BBA9ag^Z`@rYQP(zqFund&algMQm-?vpW}WpPs^n|Jsd7@jRsF-IkQaWC;; zh%>OYiTR=o7;Ix&*oInPyhjjPyJ7DBCK^lzsg|(oB@N+jmeljg4s(s# zxAVD1NF*Z>Y|KTK&2=Zt80d3qJKOr`|I)(xzqob_gmNikZD}|n*-#k^V{zZ6=7Gm# zu{%|m>*W7ARK@W>48Z>{15UbukSS7~i22Lnemnw^$W?NIE{ zWD_Xi#h}x<&Z&z(HqDu{4&Q@hK)<|+mZH-kQhoO513A*P=5IBBO;d+Y%4&uk@SK`C z@4DsVQmWq_JHh#T@fO*j?>U#Z;P}CZ{Q52Zt1YS{5pS803U1KowbP&CyKXfyy&wcZ jMeH<<44ISwXEVW!;lqI+i!2%33?9C_u0Q$VfPnrFKF%6P diff --git a/src/sass/fonts/Inter-SemiBold.woff2 b/src/sass/fonts/Inter-SemiBold.woff2 deleted file mode 100644 index 611e90c958f1b784ada6be1c603b923d57ca88b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105804 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 `>0IwGJyHK~ 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 z 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ⅇ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 diff --git a/src/svg/checkmark-seal-svgrepo-com.svg b/src/svg/checkmark-seal-svgrepo-com.svg deleted file mode 100644 index 8a5b4a3..0000000 --- a/src/svg/checkmark-seal-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/svg/close-svgrepo-com.svg b/src/svg/close-svgrepo-com.svg deleted file mode 100644 index a4a1e54..0000000 --- a/src/svg/close-svgrepo-com.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - diff --git a/src/svg/download-svgrepo-com.svg b/src/svg/download-svgrepo-com.svg deleted file mode 100644 index 9b8cf09..0000000 --- a/src/svg/download-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/svg/expand-full-fullscreen-svgrepo-com.svg b/src/svg/expand-full-fullscreen-svgrepo-com.svg deleted file mode 100644 index 53218ff..0000000 --- a/src/svg/expand-full-fullscreen-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/svg/filter-svgrepo-com.svg b/src/svg/filter-svgrepo-com.svg deleted file mode 100644 index 6bedf72..0000000 --- a/src/svg/filter-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/svg/fork-svgrepo-com.svg b/src/svg/fork-svgrepo-com.svg deleted file mode 100644 index 8087aa8..0000000 --- a/src/svg/fork-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/svg/fullscreen-svgrepo-com.svg b/src/svg/fullscreen-svgrepo-com.svg deleted file mode 100644 index 15379af..0000000 --- a/src/svg/fullscreen-svgrepo-com.svg +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/svg/github-svgrepo-com.svg b/src/svg/github-svgrepo-com.svg deleted file mode 100644 index eaac757..0000000 --- a/src/svg/github-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/svg/minus-svgrepo-com.svg b/src/svg/minus-svgrepo-com.svg deleted file mode 100644 index 4f655c0..0000000 --- a/src/svg/minus-svgrepo-com.svg +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/src/svg/navigation-svgrepo-com.svg b/src/svg/navigation-svgrepo-com.svg deleted file mode 100644 index 92569ad..0000000 --- a/src/svg/navigation-svgrepo-com.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/svg/plus-svgrepo-com.svg b/src/svg/plus-svgrepo-com.svg deleted file mode 100644 index 8410ef7..0000000 --- a/src/svg/plus-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/svg/search-svgrepo-com.svg b/src/svg/search-svgrepo-com.svg deleted file mode 100644 index 8369115..0000000 --- a/src/svg/search-svgrepo-com.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/svg/settings-svgrepo-com.svg b/src/svg/settings-svgrepo-com.svg deleted file mode 100644 index eaeef67..0000000 --- a/src/svg/settings-svgrepo-com.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/webfonts/fa-brands-400.ttf b/src/webfonts/fa-brands-400.ttf new file mode 100644 index 0000000000000000000000000000000000000000..0f82a8360517d2c8b7d16e85434d40c6fb735954 GIT binary patch literal 210792 zcmd4437DKkwfJ52_P%#d?>$>j_ssN6W+s`Qt&@;t2#F*RAj-ZdK}3-?YLLhx!zSp} zOHdY3#Hh&iDk>r>D(YNCL`CI#@# z-rDQbsZ*y;oqD6RQYxq>luH$lJAT>FnLA!}sZzR!(5+`*c-FQrw;XjC3H(YW-~74@ z-tyYDH*9`hscyG&_NC4}=d9QCeY$WDY3~Kb&LzNog8NAP&j6k0UbuaS_XvN0@@`bh zKXJjuXP@PKwdFpgS|@nF?!vQnY;!ibUrs#btKvmxU3kuCKKJZZ%GI1x%H6u{;x}#o z$nVQrl&gKYQn{sywz_;C^@Gb!*>PrU)jkz+$fnevypyM;$D=0Toq0I5-#!Mi`;SQ zlyC#{bB=AtyeWTT{x8%Oc5Hsfzw!FJ)Z0wi zj;U+Xv_rzAY%k!Kbk5aEoB9bSZlSM@JSL6JBlr)>`%8h8Ys%h3yg)r2n3;AG=QioaP1ynBZ1}c%U8YW3hl!&e(l<5A zYoy1G>EG1bK)uxCC(N{W!5vpV^0h6h?_i @@Z|Lo2o%N8V+8O&i2d+$8BHR07ve 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 z

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