bumble-enhanced

show votes, show online status, and change location on bumble

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        bumble-enhanced
// @namespace   https://openuserjs.org/users/93Akkord
// @match       https://*.bumble.com/*
// @run-at      document-start
// @version     3.0.7
// @author      93Akkord
// @description show votes, show online status, and change location on bumble
// @grant       GM.getValue
// @grant       GM.setValue
// @grant       GM_addStyle
// @grant       GM_registerMenuCommand
// @grant       unsafeWindow
// @grant       GM_notification
// @require     https://code.jquery.com/jquery-3.2.1.min.js
// @require     https://openuserjs.org/src/libs/93Akkord/loglevel.js
// @require     https://cdn.jsdelivr.net/npm/[email protected]/moment.min.js
// @require     https://openuserjs.org/src/libs/93Akkord/akkd-common.js
// @require     https://greasyfork.org/scripts/446257-waitforkeyelements-utility-function/code/waitForKeyElements%20utility%20function.js?version=1059316
// @require     https://cdnjs.cloudflare.com/ajax/libs/arrive/2.4.1/arrive.min.js
// @require     https://openuserjs.org/src/libs/sizzle/GM_config.min.js
// require     https://unpkg.com/esserializer/dist/bundle.js
// @require     https://cdnjs.cloudflare.com/ajax/libs/luxon/3.2.1/luxon.min.js
// @copyright   2022+, Michael Barros (https://openuserjs.org/users/93Akkord)
// @license     CC-BY-NC-SA-4.0; https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode
// @license     GPL-3.0-or-later; https://www.gnu.org/licenses/gpl-3.0.txt
// @icon        data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADf0lEQVRYhb2XT2hcVRTGf+e+l8xklDakElJj/nRKM6Fd1oWKLlS02kU2VXBRFF20tEqKroI7odBuVATtpgqiLgTdaKlaVIwK1UW7EWlNmkZj2tgRMoQxncnMm3uPC+0kb+bNexNIeuAu3jnf+b5z/78rrDE9P9KPmqOI7AcGgR42xgrAHMoXqDslD04t3ArIqvjuF1T1HSC9QaKtrCxGj8r9v71fL+B/8fc2WThkIjwnD1z+QPSn0WFn5TKb3/OGCiibDi9nnMqx2y4OoHQ56475zrJPJBm/GSZO9/kiDLWFNmnkzt1gUvE4V0GXL4FbSaRUxw5fVTNtqOPtOY1s2dtWrVq8iP3lWcAlQe8w7RCavqfbFgeQLXsxfU+1hTWqENv8bszwy22L14mHX0H97nhuhcQR8AYOg791jUfRah5dmQ+3aj6c6G/Fu+dQYqF+XFAyWczdB0M++8ebuPnTkXgzeARvaHz1u/8g7sYnaPn3lhqxU2B2TIA01Fgrt8Rjyw096MBkJ2KnQCrfj2pkZdsext9zqjmgFq0sNPsBSfcTNau1X4/gCpOROX60eidedqLB6dDSLLhKJBGALhfBpJBMNlSIt3MCu3QeXLW5gCgir3cM6RoM92LqVWz+s5biofy+A/gjx+vf0jWE1zuGvfFpcwEaMQQa4VTniMJGmTobyRmVL+XJiDVgOkndeyY8ClpDK3+1VYCktocWr5bnqFwYi5yC6F1gqwQzJxtYfSQ9UG8oaFBEgyIg4VjDzglmTqK2GrkLWp4DdvE7bOFHvJ6HmmK1hY8Jpl8L+Tpzx/G2H2jmKfyAXZxsJYP5b26iW3DlBGitOUtpxkddPC4guHKiJb+qxp+ErjRL7dqH+APPh/x+/zN4dz2yuiVNCkn1NuUH1z/ClVqfggCy/G0udm2Ll6Hrvq8iBeJMK39T/vkJ1JZicYmXkdoS1atvrEscoHr19URxAKNAUgvyn2OXLrYtbpcuEOTPJPIqIP98k7uJkPxX5KUxmSxrnhItTHGlWbDJv2QCN32FeZRcIrq2gi1eSoStxxSZM6BnN5R1fSWclcLX2UGPjilu89tA0LJv2GV6Hpv9U4yMJ6dssBl5MfPo9PX6ilo6N3oIo2+hmzwShjJOx7sfn34XGpb04rmdA56YlxB5EmQEJeEV0qYJFdApVL+0NX172/6Za7dC/wImUfGIbr9yngAAAABJRU5ErkJggg==
// ==/UserScript==

// #region Workers

// prettier-ignore
{var W=Object.create;var y=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var L=Object.getPrototypeOf,C=Object.prototype.hasOwnProperty;var G=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var B=(e,t,s,u)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of F(t))!C.call(e,a)&&a!==s&&y(e,a,{get:()=>t[a],enumerable:!(u=k(t,a))||u.enumerable});return e};var j=(e,t,s)=>(s=e!=null?W(L(e)):{},B(t||!e||!e.__esModule?y(s,"default",{value:e,enumerable:!0}):s,e));var M=G((p,b)=>{(function(e,t){typeof p=="object"&&typeof b<"u"?t(p):typeof define=="function"&&define.amd?define(["exports"],t):(e=typeof globalThis<"u"?globalThis:e||self,t(e.fastUniqueNumbers={}))})(p,function(e){"use strict";var t=function(o){return function(d){var m=o(d);return d.add(m),m}},s=function(o){return function(d,m){return o.set(d,m),m}},u=Number.MAX_SAFE_INTEGER===void 0?9007199254740991:Number.MAX_SAFE_INTEGER,a=536870912,h=a*2,g=function(o,d){return function(m){var v=d.get(m),c=v===void 0?m.size:v<h?v+1:0;if(!m.has(c))return o(m,c);if(m.size<a){for(;m.has(c);)c=Math.floor(Math.random()*h);return o(m,c)}if(m.size>u)throw new Error("Congratulations, you created a collection of unique numbers which uses all available integers!");for(;m.has(c);)c=Math.floor(Math.random()*u);return o(m,c)}},w=new WeakMap,E=s(w),n=g(E,w),r=t(n);e.addUniqueNumber=r,e.generateUniqueNumber=n})});var I=e=>e.method!==void 0&&e.method==="call";var N=e=>e.error===null&&typeof e.id=="number";var l=j(M()),_=e=>{let t=new Map([[0,()=>{}]]),s=new Map([[0,()=>{}]]),u=new Map,a=new Worker(e);return a.addEventListener("message",({data:n})=>{if(I(n)){let{params:{timerId:r,timerType:i}}=n;if(i==="interval"){let o=t.get(r);if(typeof o=="number"){let d=u.get(o);if(d===void 0||d.timerId!==r||d.timerType!==i)throw new Error("The timer is in an undefined state.")}else if(typeof o<"u")o();else throw new Error("The timer is in an undefined state.")}else if(i==="timeout"){let o=s.get(r);if(typeof o=="number"){let d=u.get(o);if(d===void 0||d.timerId!==r||d.timerType!==i)throw new Error("The timer is in an undefined state.")}else if(typeof o<"u")o(),s.delete(r);else throw new Error("The timer is in an undefined state.")}}else if(N(n)){let{id:r}=n,i=u.get(r);if(i===void 0)throw new Error("The timer is in an undefined state.");let{timerId:o,timerType:d}=i;u.delete(r),d==="interval"?t.delete(o):s.delete(o)}else{let{error:{message:r}}=n;throw new Error(r)}}),{clearInterval:n=>{let r=(0,l.generateUniqueNumber)(u);u.set(r,{timerId:n,timerType:"interval"}),t.set(n,r),a.postMessage({id:r,method:"clear",params:{timerId:n,timerType:"interval"}})},clearTimeout:n=>{let r=(0,l.generateUniqueNumber)(u);u.set(r,{timerId:n,timerType:"timeout"}),s.set(n,r),a.postMessage({id:r,method:"clear",params:{timerId:n,timerType:"timeout"}})},setInterval:(n,r)=>{let i=(0,l.generateUniqueNumber)(t);return t.set(i,()=>{n(),typeof t.get(i)=="function"&&a.postMessage({id:null,method:"set",params:{delay:r,now:performance.now(),timerId:i,timerType:"interval"}})}),a.postMessage({id:null,method:"set",params:{delay:r,now:performance.now(),timerId:i,timerType:"interval"}}),i},setTimeout:(n,r)=>{let i=(0,l.generateUniqueNumber)(s);return s.set(i,n),a.postMessage({id:null,method:"set",params:{delay:r,now:performance.now(),timerId:i,timerType:"timeout"}}),i}}};var R=(e,t)=>{let s=null;return()=>{if(s!==null)return s;let u=new Blob([t],{type:"application/javascript; charset=utf-8"}),a=URL.createObjectURL(u);return s=e(a),setTimeout(()=>URL.revokeObjectURL(a)),s}};var x=`(()=>{"use strict";const e=new Map,t=new Map,r=(e,t)=>{let r,o;const i=performance.now();r=i,o=e-Math.max(0,i-t);return{expected:r+o,remainingDelay:o}},o=(e,t,r,i)=>{const s=performance.now();s>r?postMessage({id:null,method:"call",params:{timerId:t,timerType:i}}):e.set(t,setTimeout(o,r-s,e,t,r,i))};addEventListener("message",(i=>{let{data:s}=i;try{if("clear"===s.method){const{id:r,params:{timerId:o,timerType:i}}=s;if("interval"===i)(t=>{const r=e.get(t);if(void 0===r)throw new Error('There is no interval scheduled with the given id "'.concat(t,'".'));clearTimeout(r),e.delete(t)})(o),postMessage({error:null,id:r});else{if("timeout"!==i)throw new Error('The given type "'.concat(i,'" is not supported'));(e=>{const r=t.get(e);if(void 0===r)throw new Error('There is no timeout scheduled with the given id "'.concat(e,'".'));clearTimeout(r),t.delete(e)})(o),postMessage({error:null,id:r})}}else{if("set"!==s.method)throw new Error('The given method "'.concat(s.method,'" is not supported'));{const{params:{delay:i,now:n,timerId:a,timerType:d}}=s;if("interval"===d)((t,i,s)=>{const{expected:n,remainingDelay:a}=r(t,s);e.set(i,setTimeout(o,a,e,i,n,"interval"))})(i,a,n);else{if("timeout"!==d)throw new Error('The given type "'.concat(d,'" is not supported'));((e,i,s)=>{const{expected:n,remainingDelay:a}=r(e,s);t.set(i,setTimeout(o,a,t,i,n,"timeout"))})(i,a,n)}}}}catch(e){postMessage({error:{message:e.message},id:s.id,result:null})}}))})();`;var f=R(_,x),O=e=>f().clearInterval(e),U=e=>f().clearTimeout(e),A=(e,t)=>f().setInterval(e,t),q=(e,t)=>f().setTimeout(e,t);function T(){return globalThis.GM_info&&GM_info.script.grant.includes("unsafeWindow")?unsafeWindow:globalThis}T().clearIntervalEx=O,T().clearTimeoutEx=U,T().setIntervalEx=A,T().setTimeoutEx=q;}

setTimeoutEx = getWindow().setTimeoutEx;
clearTimeoutEx = getWindow().clearTimeoutEx;
setIntervalEx = getWindow().setIntervalEx;
clearIntervalEx = getWindow().clearIntervalEx;

window.setTimeoutEx = getWindow().setTimeoutEx;
window.clearTimeoutEx = getWindow().clearTimeoutEx;
window.setIntervalEx = getWindow().setIntervalEx;
window.clearIntervalEx = getWindow().clearIntervalEx;

// #endregion Workers

// #region luxon

luxon.Duration.prototype.__toHuman__ = luxon.Duration.prototype.toHuman;
luxon.Duration.prototype.toHuman = function (opts = { stripZeroUnits: 'all' }) {
    let duration = this.normalize();
    let durationUnits = [];
    let precision = typeof opts.precision == 'object' ? luxon.Duration.fromObject(opts.precision) : luxon.Duration.fromMillis(0);
    let remainingDuration = duration;
    //list of all available units
    const allUnits = ['years', 'months', 'days', 'hours', 'minutes', 'seconds', 'milliseconds'];
    let smallestUnitIndex;
    let biggestUnitIndex;
    // check if user has specified the smallest unit that should be displayed
    if (opts.smallestUnit) {
        smallestUnitIndex = allUnits.indexOf(opts.smallestUnit);
    }
    // check if user has specified a biggest unit
    if (opts.biggestUnit) {
        biggestUnitIndex = allUnits.indexOf(opts.biggestUnit);
    }
    // use seconds and years as default for smallest and biggest unit
    if (!smallestUnitIndex || !(smallestUnitIndex >= 0 && smallestUnitIndex < allUnits.length)) smallestUnitIndex = allUnits.indexOf('seconds');
    if (!biggestUnitIndex || !(biggestUnitIndex <= smallestUnitIndex && biggestUnitIndex < allUnits.length)) biggestUnitIndex = allUnits.indexOf('years');
    for (let unit of allUnits.slice(biggestUnitIndex, smallestUnitIndex + 1)) {
        const durationInUnit = remainingDuration.as(unit);
        if (durationInUnit >= 1) {
            durationUnits.push(unit);
            let tmp = {};
            tmp[unit] = Math.floor(remainingDuration.as(unit));
            remainingDuration = remainingDuration.minus(luxon.Duration.fromObject(tmp)).normalize();
            // check if remaining duration is smaller than precision
            if (remainingDuration < precision) {
                // ok, we're allowed to remove the remaining parts and to round the current unit
                break;
            }
        }
        // check if we have already the maximum count of units allowed
        if (opts.maxUnits && durationUnits.length >= opts.maxUnits) {
            break;
        }
    }
    // after gathering of units that shall be displayed has finished, remove the remaining duration to avoid non-integers
    duration = duration.minus(remainingDuration).normalize();
    duration = duration.shiftTo(...durationUnits);
    if (opts.stripZeroUnits == 'all') {
        durationUnits = durationUnits.filter((unit) => duration.values[unit] > 0);
    } else if (opts.stripZeroUnits == 'end') {
        let mayStrip = true;
        durationUnits = durationUnits.reverse().filter((unit /*, index*/) => {
            if (!mayStrip) return true;
            if (duration.values[unit] == 0) {
                return false;
            } else {
                mayStrip = false;
            }
            return true;
        });
    }
    // if `durationUnits` is empty (i.e. duration is zero), then just shift to the smallest unit
    if (!durationUnits.length) {
        durationUnits.push(allUnits[smallestUnitIndex]);
    }
    return duration.shiftTo(...durationUnits).__toHuman__(opts);
};

// #endregion luxon

// #region ESSerializer

// prettier-ignore
function initESSerializer(_window=window){!function(r,e){for(var _ in e)r[_]=e[_];e.__esModule&&Object.defineProperty(r,"__esModule",{value:!0})}(this,(()=>{"use strict";var __webpack_modules__={607:(module,exports,__webpack_require__)=>{Object.defineProperty(exports,"__esModule",{value:!0});var serializer_1=__webpack_require__(810),deserializer_1=__webpack_require__(496),Module;"undefined"!=typeof process&&process.release&&"node"===process.release.name&&(Module=eval("require")("module"));var _ESSerializer=function(){function r(){}return r.throwErrorIfInNonNodeEnvironment=function(){if(!Module)throw new Error("Cannot intercept require in non-Node environment.")},r.interceptRequire=function(){this.isRequireIntercepted||(this.isRequireIntercepted=!0,this.throwErrorIfInNonNodeEnvironment(),r.originRequire=Module.prototype.require,Module.prototype.require=function(){var e=r.originRequire.apply(this,arguments),_=e.name;return r.requiredClasses[_]||(r.requiredClasses[_]=e),e})},r.stopInterceptRequire=function(){this.throwErrorIfInNonNodeEnvironment(),Module.prototype.require=r.originRequire,this.isRequireIntercepted=!1},r.isInterceptingRequire=function(){return this.isRequireIntercepted},r.getRequiredClasses=function(){return this.requiredClasses},r.clearRequiredClasses=function(){this.requiredClasses={}},r.registerClass=function(r){this.registeredClasses.push(r)},r.registerClasses=function(r){this.registeredClasses=this.registeredClasses.concat(r)},r.clearRegisteredClasses=function(){this.registeredClasses=[]},r.serialize=function(r,e){return void 0===e&&(e={}),JSON.stringify(serializer_1.getSerializeValueWithClassName(r,e))},r.deserialize=function(r,e,_){return void 0===e&&(e=[]),void 0===_&&(_={}),deserializer_1.deserializeFromParsedObj(JSON.parse(r),Object.values(this.requiredClasses).concat(this.registeredClasses).concat(e),_)},r.originRequire=null,r.isRequireIntercepted=!1,r.requiredClasses={},r.registeredClasses=[],r}();_window.ESSerializer=_ESSerializer},917:function(r,e){var _=this&&this.__spreadArrays||function(){for(var r=0,e=0,_=arguments.length;e<_;e++)r+=arguments[e].length;var I=Array(r),t=0;for(e=0;e<_;e++)for(var n=arguments[e],L=0,A=n.length;L<A;L++,t++)I[t]=n[L];return I};Object.defineProperty(e,"__esModule",{value:!0}),e.TO_STRING_FIELD=e.TIMESTAMP_FIELD=e.OPTIONS_FIELD=e.CLASS_NAME_FIELD=e.BOOLEAN_FIELD=e.ARRAY_FIELD=e.BUILTIN_TYPE_UNDEFINED=e.BUILTIN_TYPE_NOT_FINITE=e.BUILTIN_TYPE_BIG_INT=e.BUILTIN_CLASS_AGGREGATE_ERROR=e.BUILTIN_CLASS_URI_ERROR=e.BUILTIN_CLASS_TYPE_ERROR=e.BUILTIN_CLASS_SYNTAX_ERROR=e.BUILTIN_CLASS_REFERENCE_ERROR=e.BUILTIN_CLASS_RANGE_ERROR=e.BUILTIN_CLASS_EVAL_ERROR=e.BUILTIN_CLASS_ERROR=e.BUILTIN_CLASS_STRING=e.BUILTIN_CLASS_SET=e.BUILTIN_CLASS_REGEXP=e.BUILTIN_CLASS_INTL_RELATIVETIMEFORMAT=e.BUILTIN_CLASS_INTL_PLURALRULES=e.BUILTIN_CLASS_INTL_NUMBERFORMAT=e.BUILTIN_CLASS_INTL_LOCALE=e.BUILTIN_CLASS_INTL_LISTFORMAT=e.BUILTIN_CLASS_INTL_DATETIMEFORMAT=e.BUILTIN_CLASS_INTL_COLLATOR=e.BUILTIN_CLASS_DATE=e.BUILTIN_CLASS_DATAVIEW=e.BUILTIN_CLASS_BOOLEAN=e.BUILTIN_CLASS_SHAREDARRAYBUFFER=e.BUILTIN_CLASS_ARRAYBUFFER=e.BUILTIN_CLASS_BIGUINT64ARRAY=e.BUILTIN_CLASS_BIGINT64ARRAY=e.BUILTIN_CLASS_FLOAT64ARRAY=e.BUILTIN_CLASS_FLOAT32ARRAY=e.BUILTIN_CLASS_UINT32ARRAY=e.BUILTIN_CLASS_INT32ARRAY=e.BUILTIN_CLASS_UINT16ARRAY=e.BUILTIN_CLASS_INT16ARRAY=e.BUILTIN_CLASS_UINT8CLAMPEDARRAY=e.BUILTIN_CLASS_UINT8ARRAY=e.BUILTIN_CLASS_INT8ARRAY=e.CLASSNAMES_WHOSE_ENUMERABLE_PROPERTIES_SHOULD_BE_IGNORED=e.ALL_BUILTIN_INTLS=e.ALL_BUILTIN_ERRORS=e.ALL_BUILTIN_ARRAYS=e.ESSERIALIZER_NULL=void 0,e.ESSERIALIZER_NULL="__ESSERIALIZER_NULL__",e.ARRAY_FIELD="ess_arr",e.BOOLEAN_FIELD="ess_bool",e.CLASS_NAME_FIELD="ess_cn",e.OPTIONS_FIELD="ess_opt",e.TIMESTAMP_FIELD="ess_ts",e.TO_STRING_FIELD="ess_str";var I="Int8Array";e.BUILTIN_CLASS_INT8ARRAY=I;var t="Uint8Array";e.BUILTIN_CLASS_UINT8ARRAY=t;var n="Uint8ClampedArray";e.BUILTIN_CLASS_UINT8CLAMPEDARRAY=n;var L="Int16Array";e.BUILTIN_CLASS_INT16ARRAY=L;var A="Uint16Array";e.BUILTIN_CLASS_UINT16ARRAY=A;var a="Int32Array";e.BUILTIN_CLASS_INT32ARRAY=a;var S="Uint32Array";e.BUILTIN_CLASS_UINT32ARRAY=S;var R="Float32Array";e.BUILTIN_CLASS_FLOAT32ARRAY=R;var i="Float64Array";e.BUILTIN_CLASS_FLOAT64ARRAY=i;var o="BigInt64Array";e.BUILTIN_CLASS_BIGINT64ARRAY=o;var T="BigUint64Array";e.BUILTIN_CLASS_BIGUINT64ARRAY=T,e.BUILTIN_CLASS_ARRAYBUFFER="ArrayBuffer",e.BUILTIN_CLASS_SHAREDARRAYBUFFER="SharedArrayBuffer",e.BUILTIN_CLASS_BOOLEAN="Boolean",e.BUILTIN_CLASS_DATAVIEW="DataView",e.BUILTIN_CLASS_DATE="Date";var s="Collator";e.BUILTIN_CLASS_INTL_COLLATOR=s;var E="DateTimeFormat";e.BUILTIN_CLASS_INTL_DATETIMEFORMAT=E;var N="ListFormat";e.BUILTIN_CLASS_INTL_LISTFORMAT=N,e.BUILTIN_CLASS_INTL_LOCALE="Locale";var u="NumberFormat";e.BUILTIN_CLASS_INTL_NUMBERFORMAT=u;var c="PluralRules";e.BUILTIN_CLASS_INTL_PLURALRULES=c;var U="RelativeTimeFormat";e.BUILTIN_CLASS_INTL_RELATIVETIMEFORMAT=U,e.BUILTIN_CLASS_REGEXP="RegExp",e.BUILTIN_CLASS_SET="Set";var l="String";e.BUILTIN_CLASS_STRING=l;var B="Error";e.BUILTIN_CLASS_ERROR=B;var C="EvalError";e.BUILTIN_CLASS_EVAL_ERROR=C;var f="RangeError";e.BUILTIN_CLASS_RANGE_ERROR=f;var O="ReferenceError";e.BUILTIN_CLASS_REFERENCE_ERROR=O;var F="SyntaxError";e.BUILTIN_CLASS_SYNTAX_ERROR=F;var p="TypeError";e.BUILTIN_CLASS_TYPE_ERROR=p;var d="URIError";e.BUILTIN_CLASS_URI_ERROR=d;var v="AggregateError";e.BUILTIN_CLASS_AGGREGATE_ERROR=v,e.BUILTIN_TYPE_BIG_INT="BI",e.BUILTIN_TYPE_NOT_FINITE="NF",e.BUILTIN_TYPE_UNDEFINED="UD";var D=[I,t,n,L,A,a,S,R,i,o,T];e.ALL_BUILTIN_ARRAYS=D;var y=[B,C,f,O,F,p,d,v];e.ALL_BUILTIN_ERRORS=y;var g=[s,E,N,u,c,U];e.ALL_BUILTIN_INTLS=g;var Y=_([l],D);e.CLASSNAMES_WHOSE_ENUMERABLE_PROPERTIES_SHOULD_BE_IGNORED=Y},496:function(r,e,_){var I=this&&this.__spreadArrays||function(){for(var r=0,e=0,_=arguments.length;e<_;e++)r+=arguments[e].length;var I=Array(r),t=0;for(e=0;e<_;e++)for(var n=arguments[e],L=0,A=n.length;L<A;L++,t++)I[t]=n[L];return I};Object.defineProperty(e,"__esModule",{value:!0}),e.getParentClassName=e.getClassMappingFromClassArray=e.deserializeFromParsedObjWithClassMapping=e.deserializeFromParsedObj=void 0;var t=_(821),n=_(917),L=/^\s*class\s+/;function A(r,e,_){if(void 0===_&&(_={}),t.notObject(r))return r;if(Array.isArray(r))return a(r,e);var N=r[n.CLASS_NAME_FIELD],u=function(r,e,_){switch(N){case n.BUILTIN_CLASS_INT8ARRAY:return S(e[n.ARRAY_FIELD],Int8Array);case n.BUILTIN_CLASS_UINT8ARRAY:return S(e[n.ARRAY_FIELD],Uint8Array);case n.BUILTIN_CLASS_UINT8CLAMPEDARRAY:return S(e[n.ARRAY_FIELD],Uint8ClampedArray);case n.BUILTIN_CLASS_INT16ARRAY:return S(e[n.ARRAY_FIELD],Int16Array);case n.BUILTIN_CLASS_UINT16ARRAY:return S(e[n.ARRAY_FIELD],Uint16Array);case n.BUILTIN_CLASS_INT32ARRAY:return S(e[n.ARRAY_FIELD],Int32Array);case n.BUILTIN_CLASS_UINT32ARRAY:return S(e[n.ARRAY_FIELD],Uint32Array);case n.BUILTIN_CLASS_FLOAT32ARRAY:return S(e[n.ARRAY_FIELD],Float32Array);case n.BUILTIN_CLASS_FLOAT64ARRAY:return S(e[n.ARRAY_FIELD],Float64Array);case n.BUILTIN_CLASS_BIGINT64ARRAY:return R(e[n.ARRAY_FIELD],BigInt64Array);case n.BUILTIN_CLASS_BIGUINT64ARRAY:return R(e[n.ARRAY_FIELD],BigUint64Array);case n.BUILTIN_TYPE_BIG_INT:return i(e[n.TO_STRING_FIELD]);case n.BUILTIN_TYPE_UNDEFINED:return;case n.BUILTIN_TYPE_NOT_FINITE:return t.getValueFromToStringResult(e[n.TO_STRING_FIELD]);case n.BUILTIN_CLASS_ARRAYBUFFER:return I=e[n.ARRAY_FIELD],new Uint8Array(I).buffer;case n.BUILTIN_CLASS_SHAREDARRAYBUFFER:return function(r){var e=new SharedArrayBuffer(r.length),_=new Uint8Array(e);return r.forEach(function(r,e){_[e]=r}),e}(e[n.ARRAY_FIELD]);case n.BUILTIN_CLASS_BOOLEAN:return new Boolean(e[n.BOOLEAN_FIELD]);case n.BUILTIN_CLASS_DATAVIEW:return function(r){return new DataView(new Uint8Array(r).buffer)}(e[n.ARRAY_FIELD]);case n.BUILTIN_CLASS_DATE:return function(r){return"number"==typeof r[n.TIMESTAMP_FIELD]?new Date(r[n.TIMESTAMP_FIELD]):null}(e);case n.BUILTIN_CLASS_INTL_COLLATOR:return o(e,Intl.Collator);case n.BUILTIN_CLASS_INTL_DATETIMEFORMAT:return o(e,Intl.DateTimeFormat);case n.BUILTIN_CLASS_INTL_LISTFORMAT:return o(e,Intl.ListFormat);case n.BUILTIN_CLASS_INTL_LOCALE:return new Intl.Locale(e[n.TO_STRING_FIELD]);case n.BUILTIN_CLASS_INTL_NUMBERFORMAT:return o(e,Intl.NumberFormat);case n.BUILTIN_CLASS_INTL_PLURALRULES:return o(e,Intl.PluralRules);case n.BUILTIN_CLASS_INTL_RELATIVETIMEFORMAT:return o(e,Intl.RelativeTimeFormat);case n.BUILTIN_CLASS_REGEXP:return function(r){var e=r[n.TO_STRING_FIELD],_=e.lastIndexOf("/");return new RegExp(e.substring(1,_),e.substring(_+1))}(e);case n.BUILTIN_CLASS_SET:return function(r,e){return new Set(a(r[n.ARRAY_FIELD],e))}(e,_);case n.BUILTIN_CLASS_STRING:return new String(e[n.TO_STRING_FIELD]);case n.BUILTIN_CLASS_ERROR:return T(e,Error);case n.BUILTIN_CLASS_EVAL_ERROR:return T(e,EvalError);case n.BUILTIN_CLASS_RANGE_ERROR:return T(e,RangeError);case n.BUILTIN_CLASS_REFERENCE_ERROR:return T(e,ReferenceError);case n.BUILTIN_CLASS_SYNTAX_ERROR:return T(e,SyntaxError);case n.BUILTIN_CLASS_TYPE_ERROR:return T(e,TypeError);case n.BUILTIN_CLASS_URI_ERROR:return T(e,URIError);case n.BUILTIN_CLASS_AGGREGATE_ERROR:return T(e,AggregateError);default:return n.ESSERIALIZER_NULL}var I}(0,r,e);if(u!==n.ESSERIALIZER_NULL)return u;if(N&&!e[N])throw new Error("Class "+N+" not found");var c=[];return _.fieldsForConstructorParameters&&(c=_.fieldsForConstructorParameters.map(function(e){return e in r?r[e]:{}})),function(r,e,_,I){for(var t in e){var L=e[t];if(!I.ignoreProperties||!I.ignoreProperties.includes(t))if(I.rawProperties&&I.rawProperties.includes(t))r[t]=JSON.stringify(L);else{var a=Object.getOwnPropertyDescriptor(r,t);S=L,R=a,t===n.CLASS_NAME_FIELD||R&&("function"==typeof R.set||!1===R.writable&&"object"!=typeof S)||(a&&!1===a.writable&&"object"==typeof L?E(r[t],L,_):r[t]=A(L,_))}}var S,R;return r}(function(r,e){var _={};if(!r)return _;var t=r.length-e.length;if(t>0&&(e=e.concat(Array.from(Array(t),function(){return{}}))),L.test(r.toString()))try{_=new(r.bind.apply(r,I([void 0],e)))}catch(e){s(r.name),_={},Object.setPrototypeOf(_,r?r.prototype:Object.prototype)}else{_=Object.create(r.prototype.constructor.prototype);try{r.prototype.constructor.call(_,e)}catch(e){s(r.name)}}return _}(e[N],c),r,e,_)}function a(r,e){return r.map(function(r){return A(r,e)})}function S(r,e){return new e(r)}function R(r,e){return new e(r.map(function(r){return i(r[n.TO_STRING_FIELD])}))}function i(r){return BigInt(r)}function o(r,e){var _=r[n.OPTIONS_FIELD],I=_.locale;return delete _.locale,new e(I,_)}function T(r,e){var _;return delete(_=r.message?new e(r.message):new e).stack,r.name&&(_.name=r.name),r.stack&&(_.stack=r.stack),e===AggregateError&&(_.errors=A(r.errors,{})),_}function s(r){console.warn("Incorrect parameter type passed to constructor: "+r)}function E(r,e,_){for(var I in e){var t=Object.getOwnPropertyDescriptor(r,I);t&&!0!==t.writable&&"function"!=typeof t.set||(r[I]=A(e[I],_))}}function N(r){void 0===r&&(r=[]);var e={};return r.forEach(function(r){if(t.isClass(r)){var _=r.name,I=e[_];I&&I!==r&&console.warn("WARNING: Found class definition with the same name: "+_),e[_]=r}}),e}e.deserializeFromParsedObj=function(r,e,_){return A(r,N(e),_)},e.deserializeFromParsedObjWithClassMapping=A,e.getClassMappingFromClassArray=N,e.getParentClassName=function(r){return r.prototype.__proto__.constructor.name}},821:(r,e)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.isClass=e.notObject=e.getValueFromToStringResult=void 0,e.notObject=function(r){return null===r||"object"!=typeof r},e.getValueFromToStringResult=function(r){switch(r){case"Infinity":return 1/0;case"-Infinity":return-1/0;case"NaN":return NaN;default:return null}},e.isClass=function(r){if(function(r){return[Date].indexOf(r)>=0}(r))return!0;try{Reflect.construct(String,[],r)}catch(r){return!1}return!0}},810:(r,e,_)=>{Object.defineProperty(e,"__esModule",{value:!0}),e.getSerializeValueWithClassName=void 0;var I=_(917),t=_(821);function n(r,e){void 0===e&&(e={});var _=function(r){var e,_,n;return void 0===r?((e={})[I.CLASS_NAME_FIELD]=I.BUILTIN_TYPE_UNDEFINED,e):"number"!=typeof r||isFinite(r)?"bigint"==typeof r?((n={})[I.CLASS_NAME_FIELD]=I.BUILTIN_TYPE_BIG_INT,n[I.TO_STRING_FIELD]=r.toString(),n):t.notObject(r)?r:I.ESSERIALIZER_NULL:((_={})[I.CLASS_NAME_FIELD]=I.BUILTIN_TYPE_NOT_FINITE,_[I.TO_STRING_FIELD]=r.toString(),_)}(r);if(_!==I.ESSERIALIZER_NULL)return _;if(Array.isArray(r))return L(r);var A={};if(!function(r){var e=r.__proto__.constructor.name;return I.CLASSNAMES_WHOSE_ENUMERABLE_PROPERTIES_SHOULD_BE_IGNORED.includes(e)}(r)){if(e.ignoreProperties&&e.ignoreProperties.forEach(function(e){delete r[e]}),e.interceptProperties)for(var a in e.interceptProperties)r[a]=e.interceptProperties[a].call(r,r[a]);for(var S in r)A[S]=n(r[S])}return function(r,e){var _=r.__proto__.constructor.name;return"Object"!==_&&(e[I.CLASS_NAME_FIELD]=_,_===I.BUILTIN_CLASS_ARRAYBUFFER||_===I.BUILTIN_CLASS_SHAREDARRAYBUFFER?e[I.ARRAY_FIELD]=L(Array.from(new Uint8Array(r))):_===I.BUILTIN_CLASS_BOOLEAN?e[I.BOOLEAN_FIELD]=r.valueOf():_===I.BUILTIN_CLASS_DATAVIEW?e[I.ARRAY_FIELD]=L(Array.from(new Uint8Array(r.buffer))):_===I.BUILTIN_CLASS_DATE?e[I.TIMESTAMP_FIELD]=r.getTime():_===I.BUILTIN_CLASS_INTL_LOCALE||_===I.BUILTIN_CLASS_REGEXP?e[I.TO_STRING_FIELD]=r.toString():_===I.BUILTIN_CLASS_SET?e[I.ARRAY_FIELD]=L(Array.from(r)):_===I.BUILTIN_CLASS_STRING?e[I.TO_STRING_FIELD]=r.toString():I.ALL_BUILTIN_ARRAYS.includes(_)?e[I.ARRAY_FIELD]=L(Array.from(r)):I.ALL_BUILTIN_ERRORS.includes(_)?function(r,e,_){"Error"!==r.name&&(e.name=r.name),r.message&&(e.message=r.message),r.stack&&(e.stack=r.stack),_===I.BUILTIN_CLASS_AGGREGATE_ERROR&&(e.errors=n(r.errors))}(r,e,_):I.ALL_BUILTIN_INTLS.includes(_)&&(e[I.OPTIONS_FIELD]=r.resolvedOptions())),e}(r,A)}function L(r){return r.map(function(r){return n(r)})}e.getSerializeValueWithClassName=n}},__webpack_module_cache__={};function __webpack_require__(r){if(__webpack_module_cache__[r])return __webpack_module_cache__[r].exports;var e=__webpack_module_cache__[r]={exports:{}};return __webpack_modules__[r].call(e.exports,e,e.exports,__webpack_require__),e.exports}return __webpack_require__(607)})())}

// #endregion ESSerializer

// #region Bumble Classes

class BumbleUser {
    constructor(userProps) {
        this.updateProps(userProps);
    }

    updateProps(userProps) {
        this.user_id = userProps.user_id;
        this.access_level = userProps.access_level;
        this.name = userProps.name;
        this.age = userProps.age;
        this.gender = userProps.gender;
        this.is_deleted = userProps.is_deleted;
        this.is_extended_match = userProps.is_extended_match;
        this.online_status = userProps.online_status;
        this.is_match = userProps.is_match;
        this.match_mode = userProps.match_mode;
        this.is_crush = userProps.is_crush;
        this.their_vote_mode = userProps.their_vote_mode;
        this.unread_messages_count = userProps.unread_messages_count;
        this.is_inapp_promo_partner = userProps.is_inapp_promo_partner;
        this.is_locked = userProps.is_locked;
        this.type = userProps.type;
        this.connection_status_indicator = userProps.connection_status_indicator;
        this.profile_photo_preview_url = this.profile_photo_preview_url || userProps?.profile_photo?.preview_url || userProps.profile_photo_preview_url;
        this.profile_photo_large_url = this.profile_photo_large_url || userProps?.profile_photo?.large_url || userProps.profile_photo_large_url;
        this.last_seen = this.online_status == 1 ? new Date().getTime() : this.last_seen || userProps.last_seen;
        this.last_seen_dt = this.last_seen != null && this.last_seen != undefined ? luxon.DateTime.fromMillis(this.last_seen).toFormat('yyyy-MM-dd hh:mm:ss a') : null;
        this.time_since_last_seen = this.last_seen != null && this.last_seen != undefined ? new Date().getTime() - this.last_seen : null;
        this.time_since_last_seen_h = this.time_since_last_seen != null && this.time_since_last_seen != undefined ? luxon.Duration.fromMillis(this.time_since_last_seen).toHuman({ unitDisplay: 'short' }) : null;
        this.played_track_user_online = firstBumbleCreations ? false : userProps.played_track_user_online != null && userProps.played_track_user_online != undefined ? userProps.played_track_user_online : false;

        return this;
    }

    updateLastSeen() {
        this.last_seen_dt = this.last_seen != null && this.last_seen != undefined ? luxon.DateTime.fromMillis(this.last_seen).toFormat('yyyy-MM-dd hh:mm:ss a') : null;
        this.time_since_last_seen = this.last_seen != null && this.last_seen != undefined ? new Date().getTime() - this.last_seen : null;
        this.time_since_last_seen_h = this.time_since_last_seen != null && this.time_since_last_seen != undefined ? luxon.Duration.fromMillis(this.time_since_last_seen).toHuman({ unitDisplay: 'short' }) : null;

        return this;
    }
}

// #endregion Bumble Classes

initESSerializer(getWindow());

const DEBUG_MESSAGES = false;

let encs = [];
let user;
let numEncountersCalls = 0;
let queue = [];
let convos = [];
let quota = 0;
let lastestMessageId;

const userIds = [];

let trackUserOnline = false;
let firstBumbleCreations = true;
let updateing = false;
let updateingEncounters = false;

/** @type {BumbleUser[]} */
let bumbleUsersCurrent = [];

/** @type {BumbleUser[]} */
let bumbleUsersNew = [];

/** @type {(userId: string) => void} */
let openChat;

let debugObj = {
    projection: [],
};

const logger = getLogger('bumble-enhanced', { logLevel: log.levels.DEBUG });

logger.info(`Loading ${GM_info.script.name}...`);

/* jshint esversion: 8 */
(async function () {
    setupConfig();

    deserializeUsers();

    exposeGlobalVariables([
        // libs
        { name: 'jQuery', value: jQuery },
        { name: '$', value: $ },

        // functions/variables
        { name: 'pp', value: pp },
        { name: 'pformat', value: pformat },
        { name: 'getObjProps', value: getObjProps },
        { name: 'getUserDefinedGlobalProps', value: getUserDefinedGlobalProps },
        { name: 'getLocalStorageSize', value: getLocalStorageSize },
        { name: 'unsafeWindow', value: unsafeWindow },
        { name: 'getWindow', value: getWindow },
        { name: 'getTopWindow', value: getTopWindow },
        { name: 'getStyle', value: getStyle },
        { name: 'BumbleUser', value: BumbleUser },
        { name: 'deserializeUsers', value: deserializeUsers },
        { name: 'findKeyPathsFuzzy', value: findKeyPathsFuzzy },
        { name: 'luxon', value: luxon },
        { name: 'openChat', value: openChat },
        { name: 'debugObj', value: debugObj },
        { name: 'serverGetUser', value: serverGetUser },

        { name: '_showAllContactsScroll', value: _showAllContactsScroll },
        { name: 'wait', value: wait },
    ]);

    $(document).arrive('.contact', function () {
        if (openChat == null || openChat == undefined) {
            openChat = findKeyPathsFuzzy(document.querySelectorAll('.contact')[0], 'openChat')[0].value;

            exposeGlobalVariables([
                // functions/variables
                { name: 'openChat', value: openChat },
            ]);
        }
    });

    function setupPageContentArriveHandler() {
        $(document).unbindArrive('.page__content', setupPageContentArriveHandler);

        setupUserMonitorDropdown();

        $(document).arrive('.page__content', setupPageContentArriveHandler);
    }

    $(document).arrive('.page__content', setupPageContentArriveHandler);

    if (!unsafeWindow.XMLHttpRequest.prototype.getResponseText) {
        unsafeWindow.XMLHttpRequest.prototype.getResponseText = Object.getOwnPropertyDescriptor(unsafeWindow.XMLHttpRequest.prototype, 'responseText').get;
    }

    if (!unsafeWindow.XMLHttpRequest.prototype.sendEx) {
        unsafeWindow.XMLHttpRequest.prototype.sendEx = Object.getOwnPropertyDescriptor(unsafeWindow.XMLHttpRequest.prototype, 'send').value;
    }

    Object.defineProperty(unsafeWindow.XMLHttpRequest.prototype, 'send', {
        /* eslint-disable-next-line no-undef */
        value: exportFunction(function () {
            let args = Array.from(arguments);
            let body = args[0];

            // try {
            //     body = JSON.parse(body);

            //     debugObj.projection = Array.from(new Set([...debugObj.projection, ...findKeyPathsFuzzy(body, 'projection')[0].value])).sort((a, b) => a - b);
            // } catch (error) {}

            // debugger;

            unsafeWindow.XMLHttpRequest.prototype.sendEx.call(this, ...args);
        }, unsafeWindow),
        enumerable: true,
        configurable: true,
        writable: true,
    });

    Object.defineProperty(unsafeWindow.XMLHttpRequest.prototype, 'responseText', {
        /* eslint-disable-next-line no-undef */
        get: exportFunction(function () {
            let responseText = unsafeWindow.XMLHttpRequest.prototype.getResponseText.call(this);

            try {
                let body = JSON.parse(responseText);

                debugObj.projection = Array.from(new Set([...debugObj.projection, ...findKeyPathsFuzzy(body, 'projection')[0].value])).sort((a, b) => a - b);
            } catch (error) {}

            // debugger;

            if (this.responseURL.includes('bumble.com/mwebapi.phtml?')) {
                const resp = JSON.parse(responseText);

                lastestMessageId = resp.message_id;
            }

            try {
                if (this.responseURL.endsWith('bumble.com/mwebapi.phtml?SERVER_APP_STARTUP')) {
                    const resp = JSON.parse(responseText);

                    user = (resp.body.find((o) => o.user) || {}).user;
                }

                if (this.responseURL.endsWith('bumble.com/mwebapi.phtml?SERVER_ENCOUNTERS_VOTE')) {
                    const body = JSON.stringify({
                        $gpb: 'badoo.bma.BadooMessage',
                        body: [
                            {
                                message_type: 81,
                                server_get_encounters: {
                                    number: 0,
                                    context: 1,
                                    user_field_filter: {
                                        projection: [200],
                                        request_albums: [],
                                        game_mode: 0,
                                        request_music_services: {},
                                    },
                                },
                            },
                        ],
                        message_id: 1,
                        message_type: 81,
                        version: 1,
                        is_background: false,
                    });

                    try {
                        window
                            .fetch('/mwebapi.phtml?SERVER_GET_ENCOUNTERS', {
                                method: 'POST',
                                headers: {
                                    'Content-Type': 'application/json',
                                    'X-Message-type': '81',
                                    'x-use-session-cookie': '1',
                                    'X-Pingback': calculateBumbleChecksum(body),
                                },
                                body,
                            })
                            .then((resp) =>
                                resp.json().then((data) => {
                                    quota = (data.body[0].client_encounters.quota || {}).yes_votes_quota || 0;
                                    (document.querySelector('#voteQuota') || {}).innerHTML = quota;
                                })
                            );
                    } catch (err) {
                        logger.error(err);
                    }
                }
                if (this.responseURL.endsWith('bumble.com/mwebapi.phtml?SERVER_GET_ENCOUNTERS')) {
                    numEncountersCalls++;

                    const resp = JSON.parse(responseText);

                    // encs.push(...resp.body[0].client_encounters.results);

                    quota = (resp.body[0].client_encounters.quota || {}).yes_votes_quota || 0;

                    responseText = JSON.stringify(resp);

                    updateEncountersLists();
                }

                if (this.responseURL.endsWith('bumble.com/mwebapi.phtml?SERVER_GET_USER_LIST')) {
                }

                if (this.responseURL.endsWith('bumble.com/mwebapi.phtml?SERVER_OPEN_CHAT')) {
                    const resp = JSON.parse(responseText);

                    updateMessagesWithDatetime(resp, user);
                }
            } catch (err) {
                logger.error(err);
            }

            return responseText;
        }, unsafeWindow),
        enumerable: true,
        configurable: true,
    });

    window.setIntervalEx(() => {
        const hdr = document.querySelector('.encounters-story-profile__header');

        if (!hdr) {
            return;
        }

        if (hdr.parentElement.querySelector('.showBumbleVotes')) {
            return;
        }

        let name = (document.querySelector('.encounters-story-profile__name') || {}).innerText;
        let age = +(document.querySelector('.encounters-story-profile__age') || { innerText: '' }).innerText.replace(',', '').trim();
        let enc = encs.find((enc) => enc.user.name === name && enc.user.age === age);

        if (!enc) {
            return;
        }

        userIds.push({ name, id: enc.user.user_id });

        const div = document.createElement('div');

        div.classList.add('showBumbleVotes');

        let vote = enc.user.their_vote;
        let voteText = vote === 1 ? 'Not voted!' : vote === 2 ? 'Swiped right!' : vote === 3 ? 'Swiped left!' : 'Unknown!';

        div.innerHTML = `${voteText}<br />
  (<span id="voteQuota">${quota}</span> yes votes remaining)`;

        hdr.after(div);

        let color;

        switch (enc.user.online_status) {
            case 1:
                // online
                color = 'green';

                break;

            case 2:
                // ??
                color = 'yellow';

                break;

            case 3:
                // offline
                color = 'grey';

                break;

            default:
                // offline
                color = 'grey';

                break;
        }

        document.querySelectorAll('span[data-qa-icon-name=profile-badge-about], span[data-qa-icon-name=profile-badge-location]').forEach((iconElem) => {
            iconElem.firstChild.setAttribute('color', color);
        });
    }, 1000);

    setupUserMsgCarouselArrive();
    setupSidebarArrive();

    setIntervalEx(async () => {
        await updateOnlineStatuses();
    }, 5000);

    setIntervalEx(() => {
        const filters = document.querySelector('.encounters-filter__content');
        if (!filters) return;
        if (filters.querySelector('.locationSpoofer')) return;
        const div = document.createElement('div');
        div.classList.add('encounters-filter__entry');
        div.classList.add('locationSpoofer');
        div.innerHTML = `
    <div class="encounters-filter__content">
      <section class="settings-fieldset">
        <header class="settings-fieldset__header">
          <div class="settings-fieldset__title">
            <h2 class="p-1 text-color-gray-dark"><span>Change Location</span></h2>
          </div>
        </header>
        <div class="form__control form__control--vertical">
          <div class="form__field">
            <div class="text-field text-field--full-rounded" data-qa-role="dialog-add-job-title-field">
              <input type="text" id="spoofLatitude" placeholder="Latitude (Decimal Format)" class="text-field__input" maxlength="40" size="5" dir="auto" value="" />
            </div>
          </div>
        </div>
        <div class="form__control form__control--vertical">
          <div class="form__field">
            <div class="text-field text-field--full-rounded" data-qa-role="dialog-add-job-title-field">
              <input type="text" id="spoofLongitude" placeholder="Longitude (Decimal Format)" class="text-field__input" maxlength="40" size="5" dir="auto" value="" />
            </div>
          </div>
        </div>
      </section>
      <div class="encounters-filter__actions">
        <div class="encounters-filter__action">
          <div class="button button--narrow button--size-m color-primary button--filled" role="button" id="applyLocationSpoofer">
            <span class="button__content">
              <span class="button__text"><span class="action text-break-words"><span id="applySpoofLocation">Apply Location</span></span></span>
            </span>
          </div>
        </div>
      </div>
    </div>
  `;
        filters.prepend(div);
        document.querySelector('#applyLocationSpoofer').addEventListener('click', async () => {
            const body = JSON.stringify({
                $gpb: 'badoo.bma.BadooMessage',
                body: [
                    {
                        message_type: 4,
                        server_update_location: {
                            location: [
                                {
                                    latitude: +document.querySelector('#spoofLatitude').value,
                                    longitude: +document.querySelector('#spoofLongitude').value,
                                },
                            ],
                        },
                    },
                ],
                message_id: 1,
                message_type: 4,
                version: 1,
                is_background: false,
            });
            try {
                const resp = await window.fetch('/mwebapi.phtml?SERVER_UPDATE_LOCATION', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-Message-type': '4',
                        'x-use-session-cookie': '1',
                        'X-Pingback': calculateBumbleChecksum(body),
                    },
                    body,
                });
                document.querySelector('#applySpoofLocation').innerText = 'Location Set!';
                filters.querySelector('.color-primary[data-qa-role=button]').click();
            } catch (e) {
                window.alert(`Error setting location: ${e}`);
            }
        });
    }, 1000);

    setupBiggerProfilePictures();

    waitForKeyElements('.profile', actionFunction, false);

    initNewSection();

    // setupModifyRequestHeaders();
    // setupLocationIntercept();

    addConversationOption();

    addCustomCss();

    logger.info(`${GM_info.script.name} loaded`);
})();

// #region Helper Functions

function isObject(value) {
    return !!(value && typeof value === 'object' && !Array.isArray(value));
}

function findNestedObject(object = {}, keyToMatch = '') {
    if (isObject(object)) {
        const entries = Object.entries(object);

        for (let i = 0; i < entries.length; i += 1) {
            const [objectKey, objectValue] = entries[i];

            if (objectKey === keyToMatch) {
                return object;
            }

            if (isObject(objectValue)) {
                const child = findNestedObject(objectValue, keyToMatch);

                if (child !== null) {
                    return child;
                }
            } else if (Array.isArray(objectValue)) {
                for (let a = 0; a < objectValue.length; a++) {
                    const item = objectValue[a];

                    if (isObject(item)) {
                        const child = findNestedObject(item, keyToMatch);

                        if (child !== null) {
                            return child;
                        }
                    }
                }
            }
        }
    }

    return null;
}

let gestureOccured = false;

$(document).on('click pointerup mouseup', function (e) {
    gestureOccured = true;
});

async function playBeep() {
    let beep = new Audio('data:audio/mpeg;base64,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//PkRPscWgjcADEslLjcEbgCS9KQsiilgMzc5KVUt066PIOE3y82o9CWehRWhjnIhMCoamFTyK8WFTAWNCllWAqNERMVYDRcU4kKVEbAJI2bQpskQfAkRDyEiUFTRUlzrIopIpaVMrWQoD6FKeETSwqbimh6ERMEyopSBJGGVhEbFKSZKkiIhSoCQmXCp4VDJ8KkqRNLUK0NSaISWBMmm6VS/jG0NIkQhBkBjSpwTK5cfUcleERohQohkSkT2ZWtHyRNFSXL+gKOhYVIrQokTRUESVIEjbSzRCUExCzWdg1VTEFNRTMuMTAwVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV');

    try {
        if (gestureOccured) {
            await beep.play();
        }
    } catch (error) {}
}

function findKeyPathsFuzzy(obj, searchTerm) {
    const keyPaths = [];
    const visited = new Set();

    function searchKeys(obj, currentPath) {
        if (typeof obj !== 'object' || obj === null || visited.has(obj)) {
            return;
        }

        visited.add(obj);

        const keys = Object.keys(obj);

        for (const key of keys) {
            const newPath = currentPath ? `${currentPath}.${key}` : key;

            if (fuzzyMatch(key, searchTerm)) {
                keyPaths.push({
                    path: newPath,
                    value: obj[key],
                });
            }

            searchKeys(obj[key], newPath);
        }
    }

    searchKeys(obj, '');

    return keyPaths;
}

function fuzzyMatch(str, searchTerm) {
    // Perform fuzzy matching logic here
    // You can use any fuzzy matching algorithm/library you prefer

    // For example, a simple case-insensitive substring match
    return str.toLowerCase().includes(searchTerm.toLowerCase());
}

// #endregion Helper Functions

// #region Bumble Functions

let allKnownProjections = [10, 11, 71, 91, 93, 100, 200, 210, 220, 230, 231, 250, 280, 291, 300, 305, 310, 330, 340, 370, 380, 490, 493, 530, 540, 560, 570, 580, 582, 583, 584, 585, 590, 591, 592, 640, 662, 700, 732, 762, 763, 860, 880, 890, 911, 912, 930, 1140, 1150, 1160, 1161, 1262, 1423];

async function serverGetUser(userId) {
    let body = JSON.stringify({
        //
        $gpb: 'badoo.bma.BadooMessage',
        body: [
            {
                message_type: 403,
                server_get_user: {
                    user_id: userId,
                    user_field_filter: {
                        game_mode: 0,
                        projection: allKnownProjections,
                        request_music_services: { top_artists_limit: 10, supported_services: [29] },
                        request_albums: [
                            { person_id: userId, album_type: 2, offset: 1 },
                            { person_id: userId, album_type: 12, external_provider: 12 },
                        ],
                    },
                    client_source: 10,
                },
            },
        ],
        message_id: lastestMessageId++,
        message_type: 403,
        version: 1,
        is_background: false,
    });

    let res = await fetch('https://bumble.com/mwebapi.phtml?SERVER_GET_USER', {
        headers: {
            accept: '*/*',
            // 'accept-language': 'en-US,en;q=0.9',
            'content-type': 'application/json',
            // 'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"',
            // 'sec-ch-ua-mobile': '?0',
            // 'sec-ch-ua-platform': '"Windows"',
            // 'sec-fetch-dest': 'empty',
            // 'sec-fetch-mode': 'cors',
            // 'sec-fetch-site': 'same-origin',
            // 'x-message-type': '403',
            'x-pingback': calculateBumbleChecksum(body),
            'x-use-session-cookie': '1',
        },
        // referrer: 'https://bumble.com/app/connections',
        // referrerPolicy: 'origin-when-cross-origin',
        body: body,
        method: 'POST',
        // mode: 'cors',
        // credentials: 'include',
    });

    res = await res.json();

    return res;
}

function calculateBumbleChecksum(inputString) {
    inputString += 'whitetelevisionbulbelectionroofhorseflying';
    const hc = '0123456789abcdef';

    function rh(n) {
        let j,
            s = '';
        for (j = 0; j <= 3; j++) s += hc.charAt((n >> (j * 8 + 4)) & 0x0f) + hc.charAt((n >> (j * 8)) & 0x0f);
        return s;
    }

    function ad(x, y) {
        let l = (x & 0xffff) + (y & 0xffff);
        let m = (x >> 16) + (y >> 16) + (l >> 16);
        return (m << 16) | (l & 0xffff);
    }

    function rl(n, c) {
        return (n << c) | (n >>> (32 - c));
    }

    function cm(q, a, b, x, s, t) {
        return ad(rl(ad(ad(a, q), ad(x, t)), s), b);
    }

    function ff(a, b, c, d, x, s, t) {
        return cm((b & c) | (~b & d), a, b, x, s, t);
    }

    function gg(a, b, c, d, x, s, t) {
        return cm((b & d) | (c & ~d), a, b, x, s, t);
    }

    function hh(a, b, c, d, x, s, t) {
        return cm(b ^ c ^ d, a, b, x, s, t);
    }

    function ii(a, b, c, d, x, s, t) {
        return cm(c ^ (b | ~d), a, b, x, s, t);
    }

    function sb(x) {
        let i;
        let nblk = ((x.length + 8) >> 6) + 1;
        let blks = new Array(nblk * 16);
        for (i = 0; i < nblk * 16; i++) blks[i] = 0;
        for (i = 0; i < x.length; i++) blks[i >> 2] |= x.charCodeAt(i) << ((i % 4) * 8);
        blks[i >> 2] |= 0x80 << ((i % 4) * 8);
        blks[nblk * 16 - 2] = x.length * 8;
        return blks;
    }

    let i,
        x = sb(inputString),
        a = 1732584193,
        b = -271733879,
        c = -1732584194,
        d = 271733878,
        olda,
        oldb,
        oldc,
        oldd;

    for (i = 0; i < x.length; i += 16) {
        olda = a;
        oldb = b;
        oldc = c;
        oldd = d;
        a = ff(a, b, c, d, x[i + 0], 7, -680876936);
        d = ff(d, a, b, c, x[i + 1], 12, -389564586);
        c = ff(c, d, a, b, x[i + 2], 17, 606105819);
        b = ff(b, c, d, a, x[i + 3], 22, -1044525330);
        a = ff(a, b, c, d, x[i + 4], 7, -176418897);
        d = ff(d, a, b, c, x[i + 5], 12, 1200080426);
        c = ff(c, d, a, b, x[i + 6], 17, -1473231341);
        b = ff(b, c, d, a, x[i + 7], 22, -45705983);
        a = ff(a, b, c, d, x[i + 8], 7, 1770035416);
        d = ff(d, a, b, c, x[i + 9], 12, -1958414417);
        c = ff(c, d, a, b, x[i + 10], 17, -42063);
        b = ff(b, c, d, a, x[i + 11], 22, -1990404162);
        a = ff(a, b, c, d, x[i + 12], 7, 1804603682);
        d = ff(d, a, b, c, x[i + 13], 12, -40341101);
        c = ff(c, d, a, b, x[i + 14], 17, -1502002290);
        b = ff(b, c, d, a, x[i + 15], 22, 1236535329);
        a = gg(a, b, c, d, x[i + 1], 5, -165796510);
        d = gg(d, a, b, c, x[i + 6], 9, -1069501632);
        c = gg(c, d, a, b, x[i + 11], 14, 643717713);
        b = gg(b, c, d, a, x[i + 0], 20, -373897302);
        a = gg(a, b, c, d, x[i + 5], 5, -701558691);
        d = gg(d, a, b, c, x[i + 10], 9, 38016083);
        c = gg(c, d, a, b, x[i + 15], 14, -660478335);
        b = gg(b, c, d, a, x[i + 4], 20, -405537848);
        a = gg(a, b, c, d, x[i + 9], 5, 568446438);
        d = gg(d, a, b, c, x[i + 14], 9, -1019803690);
        c = gg(c, d, a, b, x[i + 3], 14, -187363961);
        b = gg(b, c, d, a, x[i + 8], 20, 1163531501);
        a = gg(a, b, c, d, x[i + 13], 5, -1444681467);
        d = gg(d, a, b, c, x[i + 2], 9, -51403784);
        c = gg(c, d, a, b, x[i + 7], 14, 1735328473);
        b = gg(b, c, d, a, x[i + 12], 20, -1926607734);
        a = hh(a, b, c, d, x[i + 5], 4, -378558);
        d = hh(d, a, b, c, x[i + 8], 11, -2022574463);
        c = hh(c, d, a, b, x[i + 11], 16, 1839030562);
        b = hh(b, c, d, a, x[i + 14], 23, -35309556);
        a = hh(a, b, c, d, x[i + 1], 4, -1530992060);
        d = hh(d, a, b, c, x[i + 4], 11, 1272893353);
        c = hh(c, d, a, b, x[i + 7], 16, -155497632);
        b = hh(b, c, d, a, x[i + 10], 23, -1094730640);
        a = hh(a, b, c, d, x[i + 13], 4, 681279174);
        d = hh(d, a, b, c, x[i + 0], 11, -358537222);
        c = hh(c, d, a, b, x[i + 3], 16, -722521979);
        b = hh(b, c, d, a, x[i + 6], 23, 76029189);
        a = hh(a, b, c, d, x[i + 9], 4, -640364487);
        d = hh(d, a, b, c, x[i + 12], 11, -421815835);
        c = hh(c, d, a, b, x[i + 15], 16, 530742520);
        b = hh(b, c, d, a, x[i + 2], 23, -995338651);
        a = ii(a, b, c, d, x[i + 0], 6, -198630844);
        d = ii(d, a, b, c, x[i + 7], 10, 1126891415);
        c = ii(c, d, a, b, x[i + 14], 15, -1416354905);
        b = ii(b, c, d, a, x[i + 5], 21, -57434055);
        a = ii(a, b, c, d, x[i + 12], 6, 1700485571);
        d = ii(d, a, b, c, x[i + 3], 10, -1894986606);
        c = ii(c, d, a, b, x[i + 10], 15, -1051523);
        b = ii(b, c, d, a, x[i + 1], 21, -2054922799);
        a = ii(a, b, c, d, x[i + 8], 6, 1873313359);
        d = ii(d, a, b, c, x[i + 15], 10, -30611744);
        c = ii(c, d, a, b, x[i + 6], 15, -1560198380);
        b = ii(b, c, d, a, x[i + 13], 21, 1309151649);
        a = ii(a, b, c, d, x[i + 4], 6, -145523070);
        d = ii(d, a, b, c, x[i + 11], 10, -1120210379);
        c = ii(c, d, a, b, x[i + 2], 15, 718787259);
        b = ii(b, c, d, a, x[i + 9], 21, -343485551);
        a = ad(a, olda);
        b = ad(b, oldb);
        c = ad(c, oldc);
        d = ad(d, oldd);
    }

    return rh(a) + rh(b) + rh(c) + rh(d);
}

/**
 *
 *
 * @author Michael Barros <[email protected]>
 * @param {string} className
 * @param {number} onlineStatus
 * @param {SVGSVGElement} onlineStatusElem
 * @return {*}
 */
function makeOnlineStatusSVG(className, onlineStatus, onlineStatusElem) {
    /** @type {SVGSVGElement} */
    let circle;

    if (!onlineStatusElem) {
        onlineStatusElem = document.createElementNS('http://www.w3.org/2000/svg', 'svg');

        onlineStatusElem.setAttribute('height', 80);
        onlineStatusElem.setAttribute('width', 80);

        onlineStatusElem.classList.add(className);
        onlineStatusElem.style.position = 'absolute';
        onlineStatusElem.style.zIndex = '9';
        onlineStatusElem.style.opacity = '.9';

        circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');

        circle.setAttribute('cx', 40);
        circle.setAttribute('cy', 40);
        circle.setAttribute('r', 7);
        circle.setAttribute('stroke', 'grey');
        circle.setAttribute('stroke-width', 1);

        onlineStatusElem.appendChild(circle);
    } else {
        circle = onlineStatusElem.querySelector('circle');
    }

    /** @type {string} */
    let fill;

    switch (onlineStatus) {
        case 1:
            // online
            fill = 'green';

            break;

        case 2:
            // ??
            fill = 'yellow';

            break;

        case 3:
            // offline
            fill = 'grey';

            break;

        default:
            // offline
            fill = 'grey';

            break;
    }

    circle.setAttribute('fill', fill);

    // onlineStatusElem.appendChild(circle);

    return onlineStatusElem;
}

function updateBackToBanner(encountersAvailable) {
    try {
        let elem = document.querySelectorAll('.sidebar-profile__name > div')[0]; // document.querySelectorAll('.sidebar-action-banner')[0].querySelectorAll('.font-weight-medium')[0].querySelectorAll('span')[0];

        let textContent = elem.textContent;

        textContent = textContent.replace(/\s+?\[\d+?\]/, '');

        textContent = `${textContent} [${encountersAvailable}]`;

        elem.textContent = textContent;
    } catch (error) {}
}

function updateMessagesWithDatetime(resp, user) {
    if (DEBUG_MESSAGES) {
        console.clear();
    }

    /**
     *
     *
     * @author Michael Barros <[email protected]>
     * @param {string} str
     * @returns {string}
     */
    function convert(str) {
        str = str.replace(/&#(?:x([\da-f]+)|(\d+));/gi, function (_, hex, dec) {
            return String.fromCharCode(dec || +('0x' + hex));
        });

        str = str
            .replace(/&nbsp;/gi, ' ')
            .replace(/&amp;/gi, '&')
            .replace(/&quot;/gi, `"`)
            .replace(/&lt;/gi, '<')
            .replace(/&gt;/gi, '>');

        return str;
    }

    /**
     *
     *
     * @author Michael Barros <[email protected]>
     * @param {string} userId
     * @param {[]} messages
     * @param {string} messageType
     * @param {HTMLElement} elem
     */
    function findMessage(userId, messages, messageType, elem) {
        for (let i = 0; i < messages.length; i++) {
            const message = messages[i];
            let gifSource = getGifSource(elem);
            let audioSource = getAudioSource(elem);

            if (messageType == 'sent' && message.from_person_id == userId) {
                if (gifSource.length > 0) {
                    let match = /embed\/(.+)/.exec(message.mssg);

                    if (match && gifSource[0].src.includes(match[1])) {
                        return message;
                    }
                } else if (audioSource.length > 0) {
                    if (message?.multimedia?.audio?.url == audioSource[0].src) {
                        return message;
                    }
                } else if (convert(message.mssg) == elem.textContent) {
                    return message;
                }
            } else if (messageType == 'received' && message.to_person_id == userId) {
                if (gifSource.length > 0) {
                    let match = /embed\/(.+)/.exec(message.mssg);

                    if (match && gifSource[0].src.includes(match[1])) {
                        return message;
                    }
                } else if (audioSource.length > 0) {
                    if (message?.multimedia?.audio?.url == audioSource[0].src) {
                        return message;
                    }
                } else if (convert(message.mssg) == elem.textContent) {
                    return message;
                }
            }
        }
    }

    /**
     *
     *
     * @author Michael Barros <[email protected]>
     * @param {HTMLElement} elem
     * @returns {HTMLSourceElement[]}
     */
    function getGifSource(elem) {
        return Array.from(elem.querySelectorAll('.message-gif > video > source'));
    }

    /**
     *
     *
     * @author Michael Barros <[email protected]>
     * @param {HTMLElement} elem
     * @returns {HTMLAudioElement[]}
     */
    function getAudioSource(elem) {
        return Array.from(elem.querySelectorAll('audio'));
    }

    let userId = user.user_id;

    /** @type {[]} */
    let messages = resp.body[0].client_open_chat.chat_messages;
    let index = 0;
    let messagesSelector = '.messages-list__conversation > .message > div > div > div > .message-bubble__text, .messages-list__conversation > .message > div > div > div > .message-gif__media, .messages-list__conversation > .message > div > div > .message-audio';

    async function arriveWorker(ev) {
        /** @type {HTMLElement} */
        let elem = ev;

        while (!(elem.classList.contains('message--out') || elem.classList.contains('message--in'))) {
            elem = elem.parentElement;
        }

        // let elem = ev.parentElement.parentElement.parentElement.parentElement;

        try {
            let sent = elem.className.includes('out');
            let received = elem.className.includes('in');
            let messageType = sent ? 'sent' : 'received';

            let foundMessage = findMessage(userId, messages, messageType, elem);

            if (DEBUG_MESSAGES) {
                logger.debug(`${sent ? '<-' : '->'} :: ${foundMessage ? foundMessage.mssg : null}`);
                logger.debug(elem);
                logger.debug('');
            }

            if (foundMessage) {
                try {
                    let date = new Date(0);

                    date.setUTCSeconds(foundMessage.date_created);

                    elem.setAttribute('title', moment(date).format('ddd MMM Do yyyy h:mm A'));
                } catch (error2) {
                    logger.error('[akkd.error2]', error2);
                }
            }
        } catch (error1) {
            logger.error('[akkd.error1]', error1);
        }

        index++;
    }

    // .messages-list__conversation > .message
    $(document).unbindArrive(messagesSelector);
    $(document).arrive(messagesSelector, arriveWorker);
}

/**
 *
 *
 * @author Michael Barros <[email protected]>
 * @param {string} selector
 * @param {string} clazz
 * @param {[]} matches
 */
async function updateOnlineStatus(selector, clazz, matches) {
    try {
        /** @type {HTMLElement[]} */
        let elems = (document.querySelector(selector) || { children: [] }).children;

        elems.forEach(async (elem) => {
            let onlineStatusElem = elem.querySelector(`.${clazz}`);
            let onlineStatusElemExists = onlineStatusElem != null;

            let uidElem = [elem, ...Array.from(elem.querySelectorAll('li, div'))].find((e) => e.hasAttribute('data-qa-uid'));

            let match = matches.find((match) => match.user_id === (uidElem ? uidElem.getAttribute('data-qa-uid') : null));

            if (!match) {
                return;
            }

            elem.setAttribute('data-qa-online-status', match.online_status);

            let div = makeOnlineStatusSVG(clazz, match.online_status, onlineStatusElem);

            if (!onlineStatusElemExists) {
                uidElem.append(div);
            }

            let user = bumbleUsersCurrent.find((user) => user.user_id === (uidElem ? uidElem.getAttribute('data-qa-uid') : null));

            if (user.time_since_last_seen_h != null && user.time_since_last_seen_h != undefined) {
                7;
                div.parentElement.setAttribute(
                    'title',
                    `Last seen: ${user.time_since_last_seen_h}
${user.last_seen_dt}`
                );
            }

            try {
                await playOnlineSound(user);
            } catch (error) {}
        });
    } catch (err) {
        logger.error(err);
    }
}

/**
 *
 *
 * @author Michael Barros <[email protected]>
 */
async function updateOnlineStatusChat() {
    return;

    try {
        let elem = $('.page__content > .messages-header > .messages-header__inner > .messages-header__content .header-2')[0];
        let userId = findKeyPathsFuzzy($('.page__content')[0], 'userId')[0].value;
        let name = findKeyPathsFuzzy($('.page__content')[0], 'chatUser')[0].value.name;

        let user = bumbleUsersNew.find((user) => user.user_id === userId);

        let color;

        switch (user.online_status) {
            case 1:
                // online
                color = 'green';

                break;

            case 2:
                // ??
                color = 'yellow';

                break;

            case 3:
                // offline
                color = 'grey';

                break;

            default:
                // offline
                color = 'grey';

                break;
        }

        elem.style.color = color;
    } catch (err) {}
}

/** @type {{ name: string; userId: string; timePlayed: number; }[]} */
let playedNames = [];

// #region Notify User

/**
 *
 *
 * @author Michael Barros <[email protected]>
 * @param {BumbleUser} user
 */
async function playOnlineSound(user) {
    if (GM_config.get('play_users_to_monitor_sound', true)) {
        /** @type {{ userId: string, name: string }[]} */
        let usersToMonitor = JSON.parse(GM_config.get('users_to_monitor'));

        for (let i = 0; i < usersToMonitor.length; i++) {
            const userId = usersToMonitor[i].userId;

            if (!findPlayedName(user.user_id) && user.online_status == 1 && user.user_id == userId) {
                let imgUrl = (await testUrl(user.profile_photo_preview_url)) ? user.profile_photo_preview_url : user.profile_photo_large_url;

                notifyUser(user.name, imgUrl, user.user_id);

                localStorage.setItem('users', ESSerializer.serialize(bumbleUsersCurrent));

                playedNames.push({
                    name: userId,
                    userId: user.user_id,
                    timePlayed: new Date().getTime(),
                });
            } else if (findPlayedName(user.user_id) && user.online_status !== 1 && user.user_id == userId) {
                playedNames = playedNames.filter((x) => x.userId !== user.user_id);
            }
        }
    }
}

async function testUrl(url) {
    try {
        const response = await fetch(url, { method: 'HEAD' });

        return response.ok;
    } catch (error) {
        logger.error(`Error testing ${url}: ${error.message}`);

        return false;
    }
}

function findPlayedName(userId) {
    return playedNames.find((x) => x.userId == userId);
}

/**
 *
 *
 * @author Michael Barros <[email protected]>
 * @param {string} userName
 * @param {string} imgUrl
 * @param {string} userId
 */
function notifyUser(userName, imgUrl, userId) {
    /** @type {NotificationOptions} */
    let notificationOptions = {
        body: `${userName} is online`,
        icon: imgUrl,
    };

    /** @type {Notification} */
    let notification;

    if (!('Notification' in window)) {
        window.focus();

        alert('This browser does not support desktop notification');

        return;
    } else if (Notification.permission === 'granted') {
        notification = new Notification('Bumble', notificationOptions);
    } else if (Notification.permission !== 'denied') {
        Notification.requestPermission(function (permission) {
            if (permission === 'granted') {
                notification = new Notification('Bumble', notificationOptions);
            }
        });
    }

    notification.onclick = async function () {
        window.focus();

        for (let i = 0; i < 5; i++) {
            setTimeoutEx(() => {
                openChat(userId);
            }, 100 * i);
        }
    };

    try {
        playBeep();
    } catch (error) {}
}

/**
 *
 *
 * @author Michael Barros <[email protected]>
 * @param {{ userId: string, name: string }[]} usersToMonitor
 * @param {string} userId
 * @returns {{ userId: string, name: string } | undefined}
 */
function findUserToMonitor(usersToMonitor, userId) {
    return usersToMonitor.find((user) => user.userId == userId);
}

function setupUserMonitorDropdown() {
    let selector = '.page__content';

    // Options for the observer (which mutations to observe)
    let config = { characterData: true, attributes: true, childList: true, subtree: true };

    // Callback function to execute when mutations are observed
    let callback = (mutationList, observer) => {
        if ($('.page__content > .messages-header > .messages-header__inner > .messages-header__content .header-2').length > 0) {
            let optionsContainer = $('.page__content > .messages-header > .messages-header__inner > .messages-header__menu .options');

            if (optionsContainer.length > 0) {
                optionsContainer = optionsContainer[0];

                if ($('#akkd-notify-option').length > 0) {
                    $('#akkd-notify-option')[0].remove();
                }

                let userId = findKeyPathsFuzzy($('.page__content')[0], 'userId')[0].value;
                let name = findKeyPathsFuzzy($('.page__content')[0], 'chatUser')[0].value.name;
                let usersToMonitor = JSON.parse(GM_config.get('users_to_monitor'));
                let user = findUserToMonitor(usersToMonitor, userId);

                let optionText = user ? 'Remove from monitor' : 'Add to monitor';

                let elem = document.createElement('div');

                elem.innerHTML = `
        <div class="option " data-qa-role="option" data-qa-value="FOLDER_ONLINE", id="akkd-notify-option">
            <div class="option__text">
                <div class="p-2 text-ellipsis text-break-words">
                    <span>${optionText}</span>
                </div>
            </div>
        </div>`;

                elem = elem.children[0];

                elem.addEventListener('click', async (ev) => {
                    let usersToMonitor = JSON.parse(GM_config.get('users_to_monitor'));

                    if (user) {
                        usersToMonitor = usersToMonitor.filter((u) => u.userId != userId);
                        playedNames = playedNames.filter((x) => x.userId !== userId);
                    } else {
                        usersToMonitor.push({ userId, name });
                    }

                    GM_config.set('users_to_monitor', JSON.stringify(usersToMonitor, null, 4));
                    GM_config.set('valid_users_to_monitor', GM_config.get('users_to_monitor'));
                    GM_config.save();
                });

                getWindow().akkd_observer2.disconnect();

                optionsContainer.append(elem);

                getWindow().akkd_observer2.observe($(selector)[0], config);

                updateOnlineStatusChat();
            }
        }
    };

    try {
        getWindow().akkd_observer2.disconnect();
    } catch (error) {}

    // Create an observer instance linked to the callback function
    getWindow().akkd_observer2 = new MutationObserver(callback);

    getWindow().akkd_observer2.observe($(selector)[0], config);
}

// #endregion Notify User

async function updateOnlineStatuses() {
    await updateUserLists();

    await updateEncountersLists();

    // Carousel
    await updateOnlineStatus('.scrollable-carousel__scroll', 'show-bumble-carousel-online', queue);

    // Messages
    await updateOnlineStatus('.scroll__inner', 'show-bumble-msgs-online', convos);

    // Chat
    updateOnlineStatusChat();
}

function setupUserMsgCarouselArrive() {
    $(document).arrive('.contact, .scrollable-carousel-item', async function (ev) {
        await updateOnlineStatuses();
    });
}

function deserializeUsers() {
    let bumbleUsersCurrentSerialized = localStorage.getItem('users');

    bumbleUsersCurrent = bumbleUsersCurrentSerialized ? ESSerializer.deserialize(bumbleUsersCurrentSerialized, [BumbleUser]) : [];

    return bumbleUsersCurrent;
}

/**
 *
 *
 * @author Michael Barros <[email protected]>
 * @param {[]} users
 * @returns {*}
 */
async function createBumbleUsers(users) {
    deserializeUsers();

    bumbleUsersNew = [];

    for (let i = 0; i < bumbleUsersCurrent.length; i++) {
        let user = bumbleUsersCurrent[i];

        user.updateLastSeen();

        // if (currentUser.length > 0) {

        // }

        // await playOnlineSound(user);

        // bumbleUsersNew.push(user);
    }

    for (let i = 0; i < users.length; i++) {
        let user = new BumbleUser(users[i]);
        let currentUser = bumbleUsersCurrent.filter((x) => x.user_id == user.user_id);

        if (currentUser.length > 0) {
            user = currentUser[0].updateProps(user);
        }

        await playOnlineSound(user);

        bumbleUsersNew.push(user);
    }

    for (let i = 0; i < bumbleUsersNew.length; i++) {
        const userNew = bumbleUsersNew[i];

        let currentUserIndex = bumbleUsersCurrent.findIndex((x) => x.user_id == userNew.user_id);

        if (currentUserIndex > -1) {
            bumbleUsersCurrent[currentUserIndex] = userNew;
        } else {
            bumbleUsersCurrent.push(userNew);
        }
    }

    localStorage.setItem('users', ESSerializer.serialize(bumbleUsersCurrent));

    getWindow().bumbleUsersCurrent = bumbleUsersCurrent;
    getWindow().bumbleUsersNew = bumbleUsersNew;

    firstBumbleCreations = false;
}

async function updateUserLists() {
    if (!updateing) {
        updateing = true;

        let body = JSON.stringify({
            $gpb: 'badoo.bma.BadooMessage',
            body: [
                {
                    message_type: 245,
                    server_get_user_list: {
                        user_field_filter: {
                            projection: [200, 210, 340, 230, 640, 580, 300, 860, 280, 590, 591, 250, 700, 762, 592, 880, 582, 930, 585, 583, 305, 330, 763, 1423, 584, 1262, 911, 912],
                        },
                        preferred_count: 1000,
                        folder_id: 0,
                    },
                },
            ],
            message_id: lastestMessageId++,
            message_type: 245,
            version: 1,
            is_background: false,
        });

        let res = await fetch('https://bumble.com/mwebapi.phtml?SERVER_GET_USER_LIST', {
            headers: {
                accept: '*/*',
                'accept-language': 'en-US,en;q=0.9',
                'content-type': 'application/json',
                'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"',
                'sec-ch-ua-mobile': '?0',
                'sec-ch-ua-platform': '"Windows"',
                'sec-fetch-dest': 'empty',
                'sec-fetch-mode': 'cors',
                'sec-fetch-site': 'same-origin',
                'x-message-type': '245',
                'x-pingback': calculateBumbleChecksum(body),
                'x-use-session-cookie': '1',
            },
            referrer: 'https://bumble.com/app/connections',
            referrerPolicy: 'origin-when-cross-origin',
            body: body,
            method: 'POST',
            mode: 'cors',
            credentials: 'include',
        });

        let resp = await res.json();

        try {
            let sections = resp.body[0].client_user_list.section;

            for (let i = 0; i < sections.length; i++) {
                let section = sections[i];
                let sectionName = section.name;

                if (section.users) {
                    await createBumbleUsers(section.users);

                    if (sectionName == 'Conversations') {
                        convos = [];

                        if (section.users) {
                            convos.push(...section.users);
                        }
                    } else if (sectionName == 'Match Queue') {
                        queue = [];

                        if (section.users) {
                            queue.push(...section.users);
                        }
                    }
                }
            }
        } catch (error) {}

        setTimeoutEx(() => {
            updateing = false;
        }, 5000);
    }
}

async function updateEncountersLists(force = false) {
    if (!updateingEncounters || force) {
        updateingEncounters = true;

        let body = JSON.stringify({
            $gpb: 'badoo.bma.BadooMessage',
            body: [
                {
                    message_type: 81,
                    server_get_encounters: {
                        number: 10,
                        context: 1,
                        user_field_filter: {
                            projection: [10, 11, 71, 91, 93, 100, 200, 210, 220, 230, 231, 250, 280, 291, 300, 305, 310, 330, 340, 370, 380, 490, 493, 530, 540, 560, 570, 580, 582, 583, 584, 585, 590, 591, 592, 640, 662, 700, 732, 762, 763, 860, 880, 890, 911, 912, 930, 1140, 1150, 1160, 1161, 1262, 1423],
                            request_albums: [
                                {
                                    album_type: 7,
                                },
                                {
                                    album_type: 12,
                                    external_provider: 12,
                                    count: 8,
                                },
                            ],
                            game_mode: 0,
                            request_music_services: {
                                top_artists_limit: 8,
                                supported_services: [29],
                                preview_image_size: {
                                    width: 120,
                                    height: 120,
                                },
                            },
                        },
                    },
                },
            ],
            message_id: lastestMessageId++,
            message_type: 81,
            version: 1,
            is_background: false,
        });

        let res = await fetch('https://bumble.com/mwebapi.phtml?SERVER_GET_ENCOUNTERS', {
            headers: {
                accept: '*/*',
                'accept-language': 'en-US,en;q=0.9',
                'content-type': 'application/json',
                'sec-ch-ua': '".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"',
                'sec-ch-ua-mobile': '?0',
                'sec-ch-ua-platform': '"Windows"',
                'sec-fetch-dest': 'empty',
                'sec-fetch-mode': 'cors',
                'sec-fetch-site': 'same-origin',
                'x-message-type': '81',
                'x-pingback': calculateBumbleChecksum(body),
                'x-use-session-cookie': '1',
            },
            referrer: 'https://bumble.com/app',
            referrerPolicy: 'origin-when-cross-origin',
            body: body,
            method: 'POST',
            mode: 'cors',
            credentials: 'include',
        });

        let resp = await res.json();

        try {
            numEncountersCalls++;

            if ('results' in resp.body[0].client_encounters) {
                encs = [];

                encs.push(...resp.body[0].client_encounters.results);

                quota = (resp.body[0].client_encounters.quota || {}).yes_votes_quota || 0;

                updateBackToBanner(encs.length);
            } else if ('user_substitutes' in resp.body[0].client_encounters) {
                updateBackToBanner(0);
            }

            // responseText = JSON.stringify(resp);
        } catch (error) {}

        setTimeoutEx(() => {
            updateingEncounters = false;
        }, 2000);
    }
}

function setupSidebarArrive() {
    $(document).arrive('.sidebar-action-banner', async function (ev) {
        await updateEncountersLists(true);
    });
}

function setupBiggerProfilePictures() {
    GM_addStyle(`.gallery-preview__media-image {
    max-width: 110% !important;
    max-height: 110% !important;
}

.gallery__preview {
    max-height: 100% !important;
}

.dialog-layout .gallery__close {
    height: 64px !important;
}
`);
}

function actionFunction(jNode) {
    let x = document.getElementsByClassName('profile__photo');

    for (let i = 0; i < x.length; i++) {
        let src = x[i].src;
        let slug = src.split('&size')[0];

        let elemHtml = `<li class="profile__badge">
  <div class="pill">
      <div class="pill__title">
          <div class="p-3 text-ellipsis font-weight-medium">
              <a href="${slug}" style="text-decoration:underline;color:#454650;" target="_blank">Pic ${i}</a>
          </div>
      </div>
  </div>
</li>
`;

        $('.profile__badges').append(elemHtml);
    }
}

function setupModifyRequestHeaders() {
    // hook and generate fake 'responseText'
    xhook.before(function (request) {
        let projection = findNestedObject(request.headers, 'projection');

        if (projection) {
            logger.debug(projection);

            // xhook.updateRequestHeaders(request, {
            //     'Cache-Control': 'no-store', // no-store', // , no-cache
            //     // pragma: 'no-cache',
            //     // Cache-Control: no-cache, no-transform
            // });
        }

        // if (request.url.includes('board-response')) {
        //     xhook.updateRequestHeaders(request, {
        //         'Cache-Control': 'no-store', // no-store', // , no-cache
        //         // pragma: 'no-cache',
        //         // Cache-Control: no-cache, no-transform
        //     });

        //     request.url = `${request.url}&t=${new Date().valueOf()}`;
        // }
    });
}

function initNewSection() {
    function setupNewSection() {
        try {
            let akkdSections = Array.from(document.querySelectorAll('.akkd-section'));

            if (akkdSections.length > 0) {
                akkdSections.forEach((elem) => {
                    elem.remove();
                });
            }

            let storySection = document.querySelectorAll('.encounters-story-profile')[0];
            let aboutSectionHeader = document.querySelectorAll('.encounters-story-section__heading')[0].cloneNode(true);
            let aboutSection = document.querySelectorAll('.encounters-story-about__badges')[0].cloneNode(true);

            let locationSectionHeader = document.querySelectorAll('.encounters-story-section.encounters-story-section--location')[0].firstChild.cloneNode(true);
            let locationSection = document.querySelectorAll('.location-widget.location-widget--align-center')[0].cloneNode(true);

            let childElems = [
                { elem: aboutSectionHeader, isTitle: true },
                { elem: aboutSection, isTitle: false },
                { elem: locationSectionHeader, isTitle: true },
                { elem: locationSection, isTitle: false },
            ];

            childElems.forEach((elem) => {
                elem.elem.classList.add('akkd-section');

                storySection.appendChild(elem.elem);

                elem.elem.style.paddingTop = '10px';

                if (!elem.isTitle) {
                    elem.elem.style.paddingBottom = '10px';
                }
            });

            Array.from(aboutSection.querySelectorAll('.encounters-story-about__badge')).forEach((elem) => {
                elem.style.margin = 'unset';
            });

            Array.from(locationSection.querySelectorAll('.header-2.text-color-black')).forEach((elem) => {
                elem.style.fontSize = '16px';
            });
        } catch (error) {}
    }

    function setupMutationObserver02(encountersUserFrame) {
        if (getWindow().akkd_observer) {
            try {
                getWindow().akkd_observer.disconnect();
            } catch (error) {}
        }

        // Options for the observer (which mutations to observe)
        let config = { attributes: true, childList: true, subtree: true };

        // Callback function to execute when mutations are observed
        let callback = (mutationList, observer) => {
            for (let m = 0; m < mutationList.length; m++) {
                let mutation = mutationList[m];

                for (let i = 0; i < mutation.addedNodes.length; i++) {
                    let addedNode = mutation.addedNodes[i];

                    try {
                        let classList = Array.from(addedNode.classList);

                        if (classList.includes('encounters-album__stories-container') || classList.includes('encounters-album anim-enter-done') || classList.includes('encounters-album__progress')) {
                            setupNewSection();
                        }
                    } catch (error) {}
                }
            }
        };

        // Create an observer instance linked to the callback function
        getWindow().akkd_observer = new MutationObserver(callback);

        // Start observing the target node for configured mutations
        // let encountersUserFrame = document.querySelectorAll('.encounters-user__frame')[0];

        getWindow().akkd_observer.observe(encountersUserFrame, config);
    }

    if (document.querySelectorAll('body').length == 0) {
        setTimeoutEx(() => {
            initNewSection();
        }, 100);
    } else {
        // Options for the observer (which mutations to observe)
        let config = { attributes: true, childList: true, subtree: true };

        // Callback function to execute when mutations are observed
        let callback = (mutationList, observer) => {
            for (let m = 0; m < mutationList.length; m++) {
                let mutation = mutationList[m];

                for (let i = 0; i < mutation.addedNodes.length; i++) {
                    let addedNode = mutation.addedNodes[i];

                    try {
                        if (Array.from(addedNode.classList).includes('encounters-user__frame')) {
                            setupNewSection();
                            setupMutationObserver02(addedNode);
                        }
                    } catch (error) {}
                }
            }
        };

        // Create an observer instance linked to the callback function
        let observer = new MutationObserver(callback);

        // Start observing the target node for configured mutations
        observer.observe(document.querySelectorAll('body')[0], config);

        setupNewSection();
    }
}

function setupLocationIntercept() {
    const watchPosition = unsafeWindow.navigator.geolocation.watchPosition;
    const handlers = {};

    unsafeWindow.navigator.geolocation.watchPosition = function (cb1, cb2, options) {
        // We need to return a handler synchronously, but decide whether we'll use the real watchPosition or not
        // asynchronously. So we create our own handler, and we'll associate it with the real one later.
        const handler = Math.floor(Math.random() * 10000);

        handlers[handler] = watchPosition.apply(navigator.geolocation, [
            (position) => {
                let latitude = 26.181744177358595;
                let longitude = -80.16515493392944;

                let newPosition = {
                    coords: {
                        accuracy: position.coords.accuracy,
                        altitude: position.coords.altitude,
                        altitudeAccuracy: position.coords.altitudeAccuracy,
                        heading: position.coords.heading,
                        latitude: latitude,
                        longitude: longitude,
                        speed: position.coords.speed,
                    },
                    timestamp: position.timestamp,
                };

                cb1(newPosition);
            },
            (error) => {
                cb2(error);
            },

            options,
        ]);

        return handler;
    };

    const clearWatch = unsafeWindow.navigator.geolocation.clearWatch;

    unsafeWindow.navigator.geolocation.clearWatch = function (handler) {
        if (handler in handlers) {
            clearWatch.apply(navigator.geolocation, [handlers[handler]]);

            delete handlers[handler];
        }
    };
}

let saveContainerLeft;
let saveContainerTop;

function createLastSeenTablePopup() {
    function generateFloatingTable(arr) {
        // Create the container element
        const container = document.createElement('div');
        container.style.position = 'fixed';
        container.style.top = saveContainerTop ? `${saveContainerTop}px` : '50%';
        container.style.left = saveContainerLeft ? `${saveContainerLeft}px` : '50%';
        container.style.transform = 'translate(-50%, -50%)';
        container.style.zIndex = '9999';
        container.style.overflow = 'none';
        container.style.maxHeight = '80vh';
        container.style.backgroundColor = '#333333';
        container.style.border = '1px solid black';
        container.style.minWidth = `460.3px !important`;
        container.id = 'akkd-users-table';

        // Create the title bar
        const titleBar = document.createElement('div');
        titleBar.style.cursor = 'move';
        titleBar.style.padding = '8px';
        titleBar.style.userSelect = 'none';
        titleBar.style.backgroundColor = '#ccc';
        titleBar.style.textAlign = 'center'; // Center text alignment
        titleBar.style.borderBottom = '1px solid black';
        titleBar.textContent = 'Matches';

        const container2 = document.createElement('div');
        container2.style.overflow = 'auto';
        container2.style.maxHeight = '70vh';
        container2.style.border = '1px solid black';

        // Create the table element
        const table = document.createElement('table');
        table.style.borderCollapse = 'collapse';
        // table.style.border = '1px solid black';

        // Create the table header row
        const headerRow = document.createElement('tr');
        const keys = Object.keys(arr[0]);
        keys.forEach((key) => {
            if (['name', 'last_seen'].includes(key)) {
                const th = document.createElement('th');
                th.textContent = key;
                th.style.border = '1px solid black';
                th.style.padding = '8px';
                headerRow.appendChild(th);
            }
        });
        table.appendChild(headerRow);

        createRows(arr, table);

        // Add table to the container
        container.appendChild(titleBar);
        container2.appendChild(table);
        container.appendChild(container2);

        let intervalId = setIntervalEx(() => {
            let users = getLatestUsers();

            // Remove all rows from the table
            while (table.rows.length > 1) {
                table.deleteRow(1);
            }

            createRows(users, table);
        }, 5000);

        // Create close button
        const closeButton = document.createElement('button');
        closeButton.textContent = 'Close';
        closeButton.style.margin = '16px';
        closeButton.addEventListener('click', () => {
            document.body.removeChild(container);

            try {
                clearIntervalEx(intervalId);
            } catch (error) {}
        });
        container.appendChild(closeButton);

        let isOpacityOn = true;

        // Create close button
        const opacityButton = document.createElement('button');
        opacityButton.textContent = 'Turn Opacity On/Off';
        opacityButton.style.margin = '16px';
        opacityButton.style.marginRight = 'auto';
        opacityButton.style.right = '16px';
        opacityButton.style.position = 'absolute';
        opacityButton.addEventListener('click', () => {
            isOpacityOn = !isOpacityOn;
        });
        container.appendChild(opacityButton);

        // Add event listeners for dragging the container
        let isDragging = false;
        let startX = 0;
        let startY = 0;

        titleBar.addEventListener('mousedown', (e) => {
            isDragging = true;
            startX = e.clientX - container.offsetLeft;
            startY = e.clientY - container.offsetTop;
        });

        document.addEventListener('mousemove', (e) => {
            if (isDragging) {
                const newLeft = e.clientX - startX;
                const newTop = e.clientY - startY;

                const containerWidth = container.offsetWidth;
                const containerHeight = container.offsetHeight;
                const windowWidth = window.innerWidth;
                const windowHeight = window.innerHeight;

                const maxLeft = windowWidth - containerWidth / 2;
                const maxTop = windowHeight - containerHeight / 2;

                const maxRight = maxLeft * 1;
                const maxBottom = maxTop * 1;

                const boundedLeft = Math.max(containerWidth / 2, Math.min(newLeft, maxLeft));
                const boundedTop = Math.max(containerHeight / 2, Math.min(newTop, maxTop));

                saveContainerTop = boundedTop;
                saveContainerLeft = boundedLeft;

                container.style.left = `${boundedLeft}px`;
                container.style.top = `${boundedTop}px`;
            }
        });

        document.addEventListener('mouseup', () => {
            isDragging = false;
        });

        container.addEventListener('mouseenter', () => {
            container.style.opacity = 1;
        });
        container.addEventListener('mouseleave', () => {
            if (isDragging) {
                return;
            }

            if (!isOpacityOn) return;

            container.style.opacity = 0.25;
        });

        // Add a mousemove event listener to the document
        document.addEventListener('mousemove', handleMouseMove);

        // Mousemove event handler
        function handleMouseMove(event) {
            // Check if the element contains the mouse coordinates
            if (container.contains(event.target)) {
                // Mouse is over the element
                container.style.opacity = 1;
            } else {
                // Mouse is not over the element
                if (isDragging) {
                    return;
                }

                if (!isOpacityOn) return;

                container.style.opacity = 0.25;
            }
        }

        // Add container to the body of the document
        document.body.appendChild(container);
    }

    function createRows(arr, table) {
        const keys = Object.keys(arr[0]);

        // Create table rows for each object
        arr.forEach((obj) => {
            const row = document.createElement('tr');
            keys.forEach((key) => {
                if (['name', 'last_seen'].includes(key)) {
                    const td = document.createElement('td');

                    if (key == 'name') {
                        const a = document.createElement('a');

                        // a.href = `javascript:openChat(${obj['user_id']});`;
                        a.href = '#';
                        a.addEventListener('click', () => {
                            openChat(obj['user_id']);
                        });
                        a.textContent = obj[key];
                        a.style.color = getColorForOnlineStatus(obj);
                        td.appendChild(a);
                    } else {
                        td.textContent = obj[key];
                    }

                    td.style.border = '1px solid black';
                    td.style.padding = '8px';
                    row.appendChild(td);
                }
            });
            table.appendChild(row);
        });
    }

    function sortObjectsWithNullLast(arr, key, order = 'asc') {
        const sortedArr = arr.slice(); // Create a shallow copy of the array

        sortedArr.sort((a, b) => {
            const valueA = a[key];
            const valueB = b[key];

            if (valueA === null && valueB !== null) {
                return 1; // `null` values are considered greater, so `a` comes after `b`
            } else if (valueA !== null && valueB === null) {
                return -1; // `null` values are considered greater, so `a` comes before `b`
            } else {
                // Both values are either `null` or non-`null`, use regular comparison
                if (order === 'asc') {
                    return valueA < valueB ? -1 : valueA > valueB ? 1 : 0;
                } else if (order === 'desc') {
                    return valueA < valueB ? 1 : valueA > valueB ? -1 : 0;
                } else {
                    throw new Error('Invalid sort order. Please provide "asc" or "desc".');
                }
            }
        });

        return sortedArr;
    }

    function logPropertiesInEvenColumns(arr) {
        const keys = Object.keys(arr[0]);

        // Calculate the maximum length of each property value
        const maxLengths = {};

        keys.forEach((key) => {
            maxLengths[key] = Math.max(...arr.map((obj) => String(obj[key]).length));
        });

        // Log the properties in even columns
        arr.forEach((obj) => {
            let output = '';
            keys.forEach((key, index) => {
                const value = String(obj[key]);
                const padding = ' '.repeat(maxLengths[key] - value.length);
                output += `${key}: ${value}${padding}  ${index % 2 !== 0 ? '\t' : ''}`;
            });
            logger.debug(output);
        });
    }

    function getLatestUsers() {
        let users = sortObjectsWithNullLast(bumbleUsersCurrent.slice(), 'time_since_last_seen', 'asc').map((x, index) => {
            return {
                name: x.name,
                last_seen: x.time_since_last_seen_h,
                user_id: x.user_id,
                online_status: x.online_status,
                time_since_last_seen: x.time_since_last_seen,
            };
        });

        return users;
    }

    function getColorForOnlineStatus(user) {
        if (user['time_since_last_seen'] != 0) return 'grey';

        switch (user['online_status']) {
            case 1:
                // online
                return 'green';

            case 2:
                // ??
                return 'yellow';

            case 3:
                // offline
                return 'grey';

            default:
                // offline
                return 'grey';
        }
    }

    generateFloatingTable(getLatestUsers());
}

// #region Conversation Option

function addConversationOption() {
    let isShowOnline = false;
    let showOnlineContactsIntervalId;

    $(document).arrive('.contact-tabs__section-header-dropdown', async function (ev) {
        let optionsContainer = document.querySelectorAll('.contact-tabs__section-header-dropdown > .dropdown')[0].querySelectorAll('.options')[0];
        let elem = document.createElement('div');

        elem.innerHTML = `<div class="option " data-qa-role="option" data-qa-value="FOLDER_ONLINE"><div class="option__text"><div class="p-2 text-ellipsis text-break-words">Online</div></div></div>`;

        elem = elem.children[0];

        elem.addEventListener('click', async (ev) => {
            isShowOnline = !isShowOnline;

            try {
                clearIntervalEx(showOnlineContactsIntervalId);
            } catch (error) {}

            if (isShowOnline) {
                $('.contact-tabs__section.contact-tabs__section--conversations .contact-tabs__section-title-text span')[0].style.color = 'green';

                await _showOnlyOnlineContactsScroll();

                showOnlineContactsIntervalId = setIntervalEx(async () => {
                    _showOnlyOnlineContacts();
                }, 1000);
            } else {
                $(document.querySelectorAll('.contact-tabs__section-content .scroll__inner')[0]).unbindArrive('.contact');

                _showAllContacts();

                $('.contact-tabs__section.contact-tabs__section--conversations .contact-tabs__section-title-text span')[0].style.color = '';
            }

            setTimeoutEx(() => {
                document.querySelectorAll('.contact-tabs__section-header-dropdown > .dropdown')[0].classList.remove('is-active');
            }, 1);

            document.querySelectorAll('.contact-tabs__section-header-dropdown > .dropdown')[0].classList.remove('is-active');
        });

        optionsContainer.append(elem);
    });
}

async function _showOnlyOnlineContactsScroll() {
    /** @type {HTMLElement} */
    let contactsContainer = document.querySelectorAll('.contact-tabs__section-content .scroll__inner')[0];

    let previousScrollTop;
    let tries = 0;
    let maxTries = 250;

    async function arriveWorker(ev) {
        // index++;

        if (!ev.classList.contains('is-loading')) {
            _showOnlyOnlineContacts();
        }
    }

    // .messages-list__conversation > .message
    $(contactsContainer).unbindArrive('.contact');

    // showOnlyOnlineContacts();

    do {
        previousScrollTop = contactsContainer.scrollTop;

        contactsContainer.scrollTo({ top: contactsContainer.scrollHeight, behavior: 'auto' });

        await wait(1);

        _showOnlyOnlineContacts();

        if (previousScrollTop != contactsContainer.scrollTop) {
            tries = 0;
        } else {
            tries++;
        }
    } while (previousScrollTop != contactsContainer.scrollTop || tries < maxTries);

    contactsContainer.scrollTo({ top: 0, behavior: 'auto' });

    // $(contactsContainer).unbindArrive('.contact');
    $(contactsContainer).arrive('.contact', arriveWorker);
}

async function _showAllContactsScroll() {
    /** @type {HTMLElement} */
    let contactsContainer = document.querySelectorAll('.contact-tabs__section-content .scroll__inner')[0];

    let previousScrollTop;
    let tries = 0;
    let maxTries = 250;

    async function arriveWorker(ev) {
        // index++;

        if (!ev.classList.contains('is-loading')) {
            _showOnlyOnlineContacts();
        }
    }

    // .messages-list__conversation > .message
    // $(contactsContainer).unbindArrive('.contact');

    // showOnlyOnlineContacts();

    do {
        previousScrollTop = contactsContainer.scrollTop;

        contactsContainer.scrollTo({ top: contactsContainer.scrollHeight, behavior: 'auto' });

        await wait(1);

        // _showOnlyOnlineContacts();

        if (previousScrollTop != contactsContainer.scrollTop) {
            tries = 0;
        } else {
            tries++;
        }
    } while (previousScrollTop != contactsContainer.scrollTop || tries < maxTries);

    contactsContainer.scrollTo({ top: 0, behavior: 'auto' });

    // $(contactsContainer).unbindArrive('.contact');
    // $(contactsContainer).arrive('.contact', arriveWorker);
}

function _showAllContacts() {
    /** @type {HTMLElement[]} */
    let contactElems = Array.from(document.querySelectorAll('.contact-tabs__section-content .scroll__inner .contact'));

    for (let i = 0; i < contactElems.length; i++) {
        const contactElem = contactElems[i];

        contactElem.style.display = 'flex';
    }
}

function _showOnlyOnlineContacts() {
    /** @type {HTMLElement[]} */
    let contactElems = Array.from(document.querySelectorAll('.contact-tabs__section-content .scroll__inner .contact'));

    for (let i = 0; i < contactElems.length; i++) {
        const contactElem = contactElems[i];

        let onlineStatus = parseInt(contactElem.getAttribute('data-qa-online-status'));

        if (onlineStatus != 1) {
            contactElem.style.display = 'none';
        } else {
            contactElem.style.display = 'flex';
        }
    }
}

// #endregion Conversation Option

function addCustomCss() {
    let cssStyles = [
        {
            css: /*css*/ `.contact.is-selected {
    pointer-events: auto !important;
    cursor: auto !important;
}

.scrollable-carousel-item.is-selected {
    pointer-events: auto !important;
    cursor: auto !important;
}

#akkd-users-table {
    min-width: 458.663px !important;
    transition: opacity 0.1s linear 0s;
}

div#akkd-users-table button {
    background-color: rgba(30, 30, 30, .55);
    padding: 8px;
    border-radius: 5px;
    transition: background-color 0.1s linear 0s;
}

div#akkd-users-table button:hover {
    background-color: rgba(30, 30, 30, .85);
}

div#akkd-users-table button:active {
    background-color: rgba(30, 30, 30, .35);
}
`,
            node: document.documentElement,
        },
    ];

    addStyles(cssStyles);
}

function setupConfig() {
    // demo: http://sizzlemctwizzle.github.io/GM_config/
    GM_config.init({
        id: `main-${location.host.replace(/\./g, '_')}`,
        title: 'Bumble Enhanced Config',

        fields: {
            play_users_to_monitor_sound: {
                label: 'Play Users To Monitor Sound',
                type: 'checkbox',
                default: true,
            },

            users_to_monitor: {
                label: 'Users To Monitor',
                type: 'textarea',
                title: 'Enter JSON array string',
                default: '["Example1", "Exmaple2"]',
                save: false, // This field's value will NOT be saved
            },

            valid_users_to_monitor: {
                type: 'hidden',
                default: '',
            },
        },

        events: {
            init: function () {
                // Set the value of the dummy field to the saved value
                GM_config.set('users_to_monitor', GM_config.get('valid_users_to_monitor'));
            },
            open: function () {
                // Use a listener to update the hidden field when the dummy field passes validation
                GM_config.fields['users_to_monitor'].node.addEventListener(
                    'change',
                    function () {
                        // get the current value of the visible field
                        var users_to_monitor = GM_config.get('users_to_monitor', true);

                        try {
                            JSON.parse(users_to_monitor);

                            // Only save valid CSS
                            GM_config.set('valid_users_to_monitor', users_to_monitor);
                        } catch (error) {}
                    },
                    false
                );
            },
            save: function (forgotten) {
                if (GM_config.isOpen) {
                    // If the values don't match then valid_users_to_monitor wasn't valid
                    if (forgotten.users_to_monitor == null || forgotten.users_to_monitor == undefined) {
                        GM_config.set('users_to_monitor', JSON.stringify(JSON.parse(GM_config.get('valid_users_to_monitor')), null, 4));
                    } else if (forgotten.users_to_monitor !== GM_config.get('valid_users_to_monitor')) {
                        GM_config.set('valid_users_to_monitor', '[]');
                        GM_config.set('users_to_monitor', '[]');
                    } else {
                        GM_config.set('users_to_monitor', JSON.stringify(JSON.parse(forgotten.users_to_monitor), null, 4));
                    }
                }
            },
            close: function () {
                logger.debug('users_to_monitor:           ', JSON.parse(GM_config.get('users_to_monitor')));
                logger.debug('play_users_to_monitor_sound:', GM_config.get('play_users_to_monitor_sound'));
                logger.debug('');
            },
            reset: function () {},
        },

        css: /*css*/ `
#main-bumble_com_field_users_to_monitor {
    width: calc(100% - 150px) !important;
    height: calc(100% - 150px) !important;
    resize: none;
}`,
    });

    let menuId = GM_registerMenuCommand(`Config`, () => {
        GM_config.open();
    });

    let menuId2 = GM_registerMenuCommand(`Last Seen Table`, () => {
        createLastSeenTablePopup();
    });
}

// #endregion Bumble Functions