4sp-dv 1.1.9 → 1.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -542,6 +542,21 @@
542
542
  pointer-events: auto;
543
543
  }
544
544
  </style>
545
+
546
+ <style>
547
+ .mac-slider {
548
+ -webkit-appearance: none; appearance: none; background: transparent;
549
+ }
550
+ .mac-slider::-webkit-slider-thumb {
551
+ -webkit-appearance: none; appearance: none; width: 20px; height: 20px;
552
+ background: black; border: 2px solid white; border-radius: 50%;
553
+ cursor: pointer; margin-top: -6px;
554
+ }
555
+ .mac-slider::-webkit-slider-runnable-track {
556
+ height: 0.5rem; border-radius: 0.5rem; background: #374151;
557
+ }
558
+ </style>
559
+
545
560
  </head>
546
561
  <body>
547
562
  <div id="lock-screen" class="w-full h-full flex flex-col items-center justify-center p-4">
@@ -679,6 +694,7 @@
679
694
  <div class="flex-grow">
680
695
  <div class="flex gap-4 mb-4 border-b border-[#333] pb-4">
681
696
  <button class="pfp-mode-btn active btn-toolbar-style" data-mode="letter">Letter Avatar</button>
697
+ <button class="pfp-mode-btn btn-toolbar-style" data-mode="mibi">Mibi Avatar</button>
682
698
  <button class="pfp-mode-btn btn-toolbar-style" data-mode="upload">Upload Image</button>
683
699
  </div>
684
700
 
@@ -696,7 +712,70 @@
696
712
  <button id="save-letter-pfp-btn" class="btn-toolbar-style btn-primary-override w-full justify-center">Set Letter Avatar</button>
697
713
  </div>
698
714
 
699
- <div id="pfp-upload-options" class="hidden">
715
+
716
+ <!-- Mibi Avatar Settings -->
717
+ <div id="pfpMibiSettings" class="hidden flex flex-col gap-4 mt-2">
718
+ <p class="text-sm font-light text-gray-400 mb-4">
719
+ Create your custom Mibi Avatar!
720
+ </p>
721
+ <button id="open-mac-menu-btn" class="btn-toolbar-style btn-primary-override">
722
+ <i class="fa-solid fa-paintbrush mr-2"></i> Open Mibi Avatar Creator
723
+ </button>
724
+
725
+ <div id="mibi-mac-menu" class="fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-50 hidden backdrop-blur-sm">
726
+ <div class="relative bg-black rounded-[1.25rem] shadow-2xl w-full max-w-5xl h-[85vh] flex flex-col overflow-hidden border border-[#333]">
727
+ <div class="flex justify-between items-center p-6 border-b border-[#333] bg-black">
728
+ <h3 class="text-2xl font-bold text-white">Mibi Avatar Creator</h3>
729
+ <button id="mac-close-x-btn" class="btn-toolbar-style w-10 h-10 flex items-center justify-center p-0">
730
+ <i class="fa-solid fa-xmark fa-xl"></i>
731
+ </button>
732
+ </div>
733
+ <div class="flex flex-grow overflow-hidden relative">
734
+ <div id="mac-preview-wrapper" class="w-1/2 flex flex-col items-center justify-center bg-[#0a0a0a] p-8 border-r border-[#333] transition-all duration-500 ease-in-out z-10">
735
+ <div class="relative h-64 md:h-80 aspect-square rounded-[1.25rem] overflow-hidden border-4 border-[#333] shadow-lg mb-6 transition-all duration-300 hover:border-dashed hover:border-white cursor-pointer flex-shrink-0" id="mac-preview-container" style="aspect-ratio: 1/1;">
736
+ <div id="mac-preview-bg" class="absolute inset-0 w-full h-full transition-colors duration-300"></div>
737
+ <div id="mac-layers-container" class="absolute inset-0 w-full h-full transition-transform duration-75 ease-out origin-center pointer-events-none">
738
+ <img id="mac-layer-head" src="mibi-avatars/head.png" class="absolute inset-0 w-full h-full object-contain z-10">
739
+ <img id="mac-layer-eyes" class="absolute inset-0 w-full h-full object-contain z-20 hidden">
740
+ <img id="mac-layer-mouth" class="absolute inset-0 w-full h-full object-contain z-20 hidden">
741
+ <img id="mac-layer-hat" class="absolute inset-0 w-full h-full object-contain z-30 hidden">
742
+ </div>
743
+ </div>
744
+ <div id="mac-sliders-container" class="hidden flex-col gap-6 w-full max-w-xs transition-opacity duration-300 opacity-0">
745
+ <div class="flex flex-col gap-2">
746
+ <label class="text-xs text-gray-400 uppercase tracking-wider font-bold">Size</label>
747
+ <input type="range" id="mac-size-slider" min="50" max="150" value="100" list="mac-size-ticks" class="mac-slider w-full h-2 bg-gray-700 rounded-[14px] appearance-none cursor-pointer">
748
+ </div>
749
+ <div class="flex flex-col gap-2">
750
+ <label class="text-xs text-gray-400 uppercase tracking-wider font-bold">Rotation</label>
751
+ <input type="range" id="mac-rotation-slider" min="-180" max="180" value="0" list="mac-rotation-ticks" class="mac-slider w-full h-2 bg-gray-700 rounded-[14px] appearance-none cursor-pointer">
752
+ </div>
753
+ <p class="text-center text-gray-500 text-xs mt-2"><i class="fa-solid fa-hand-pointer mr-1"></i> Drag avatar to position</p>
754
+ </div>
755
+ <p class="text-gray-500 text-sm font-mono mt-2" id="mac-preview-label">Click preview to adjust orientation</p>
756
+ </div>
757
+ <div id="mac-controls-wrapper" class="w-1/2 flex flex-col bg-black transition-transform duration-500 ease-in-out translate-x-0">
758
+ <div class="flex border-b border-[#333]">
759
+ <button class="mac-tab-btn flex-1 py-4 text-gray-400 hover:text-white hover:bg-[#252525] transition-colors border-b-2 border-transparent font-medium active-tab" data-tab="hats">Hats</button>
760
+ <button class="mac-tab-btn flex-1 py-4 text-gray-400 hover:text-white hover:bg-[#252525] transition-colors border-b-2 border-transparent font-medium" data-tab="eyes">Eyes</button>
761
+ <button class="mac-tab-btn flex-1 py-4 text-gray-400 hover:text-white hover:bg-[#252525] transition-colors border-b-2 border-transparent font-medium" data-tab="mouths">Mouths</button>
762
+ <button class="mac-tab-btn flex-1 py-4 text-gray-400 hover:text-white hover:bg-[#252525] transition-colors border-b-2 border-transparent font-medium" data-tab="bg">Color</button>
763
+ </div>
764
+ <div class="flex-grow overflow-y-auto p-6 custom-scrollbar" id="mac-options-container">
765
+ <div class="grid grid-cols-3 gap-4" id="mac-grid"></div>
766
+ </div>
767
+ </div>
768
+ </div>
769
+ <div class="p-6 border-t border-[#333] bg-black flex justify-end gap-4 items-center">
770
+ <button id="mac-reset-btn" class="btn-toolbar-style mr-auto px-4 py-2 rounded-[1.25rem]" title="Reset Avatar"><i class="fa-solid fa-rotate-left"></i></button>
771
+ <button id="mac-cancel-btn" class="btn-toolbar-style px-6 py-2 rounded-[1.25rem]">Cancel</button>
772
+ <button id="mac-confirm-btn" class="btn-toolbar-style btn-primary-override px-6 py-2 rounded-[1.25rem]"><i class="fa-solid fa-check mr-2"></i> Confirm Avatar</button>
773
+ </div>
774
+ </div>
775
+ </div>
776
+ </div>
777
+
778
+ <div id="pfp-upload-options" class="hidden">
700
779
  <input type="file" id="pfp-upload-input" accept="image/*" class="hidden"/>
701
780
 
702
781
  <button id="trigger-upload-btn" class="btn-toolbar-style mb-4 w-full justify-center">
@@ -879,7 +958,7 @@
879
958
  "messenger-v2": { "name": "Messenger", "icon": "fa-solid fa-comments", "url": "messenger-v2.html" },
880
959
  "games": { "name": "GAMES", "icon": "fa-solid fa-gamepad", "url": "games.html" },
881
960
  "velium": { "name": "Velium", "icon": "fa-solid fa-music", "url": "velium.html" },
882
- "securly-tester": { "name": "Securly Tester", "icon": "fa-solid fa-shield-halved", "url": "securly-tester.html" },
961
+ "vana": { "name": "Humanity", "icon": "fa-solid fa-robot", "url": "vana.html" },
883
962
  "settings": { "name": "Settings", "icon": "fa-solid fa-gear", "url": "settings.html" }
884
963
  };
885
964
 
@@ -1116,8 +1195,12 @@
1116
1195
 
1117
1196
  const docRef = doc(db, 'analytics', sessionId);
1118
1197
 
1198
+ // --- FIX: Determine userId before writing ---
1199
+ const currentUid = (auth.currentUser && auth.currentUser.uid) ? auth.currentUser.uid : 'anonymous';
1200
+
1119
1201
  // Using Firestore functions imported at top
1120
1202
  setDoc(docRef, {
1203
+ userId: currentUid, // <--- ADDED THIS FIELD
1121
1204
  sessionId: sessionId,
1122
1205
  userAgent: navigator.userAgent,
1123
1206
  lastActive: serverTimestamp(),
@@ -0,0 +1,200 @@
1
+ (async function() {
2
+ console.log("[Admin Keybinds] Script Loaded");
3
+
4
+ // Firebase Config
5
+ const firebaseConfig = {
6
+ apiKey: "AIzaSyAZBKAckVa4IMvJGjcyndZx6Y1XD52lgro",
7
+ authDomain: "project-zirconium.firebaseapp.com",
8
+ projectId: "project-zirconium",
9
+ storageBucket: "project-zirconium.firebasestorage.app",
10
+ messagingSenderId: "1096564243475",
11
+ appId: "1:1096564243475:web:6d0956a70125eeea1ad3e6",
12
+ measurementId: "G-1D4F692C1Q"
13
+ };
14
+
15
+ // Dynamic Imports
16
+ const [
17
+ { initializeApp, getApp },
18
+ { getAuth, onAuthStateChanged },
19
+ { getFirestore, doc, getDoc, setDoc, onSnapshot }
20
+ ] = await Promise.all([
21
+ import("https://www.gstatic.com/firebasejs/10.12.2/firebase-app.js"),
22
+ import("https://www.gstatic.com/firebasejs/10.12.2/firebase-auth.js"),
23
+ import("https://www.gstatic.com/firebasejs/10.12.2/firebase-firestore.js")
24
+ ]);
25
+
26
+ // Initialize Firebase
27
+ let app;
28
+ try {
29
+ app = getApp(); // Try to get the default app
30
+ console.log("[Admin Keybinds] Attached to existing default app.");
31
+ } catch (e) {
32
+ console.log("[Admin Keybinds] Default app not found, initializing new one.");
33
+ app = initializeApp(firebaseConfig);
34
+ }
35
+
36
+ const auth = getAuth(app);
37
+ const db = getFirestore(app);
38
+
39
+ // State
40
+ let isAdmin = false;
41
+ let adminUnsubscribe = null;
42
+ let toasterTimeout = null;
43
+
44
+ const OWNER_EMAIL = "4simpleproblems@gmail.com";
45
+
46
+ // Standardized Notification CSS (Matches soundboard.html exactly)
47
+ const style = document.createElement('style');
48
+ style.textContent = `
49
+ #admin-status-toaster {
50
+ position: fixed;
51
+ bottom: 20px;
52
+ left: 50%;
53
+ transform: translateX(-50%) translateY(20px);
54
+ z-index: 10000000;
55
+ background-color: rgba(13, 13, 13, 0.95);
56
+ backdrop-filter: blur(5px);
57
+ padding: 0.75rem 1.5rem;
58
+ border-radius: 18px;
59
+ border: 1px solid #333;
60
+ font-size: 0.85rem;
61
+ color: #fff;
62
+ opacity: 0;
63
+ pointer-events: none;
64
+ transition: opacity 0.3s ease, transform 0.3s ease;
65
+ font-family: 'Geist', sans-serif;
66
+ display: flex;
67
+ align-items: center;
68
+ gap: 10px;
69
+ }
70
+ #admin-status-toaster.visible {
71
+ opacity: 1;
72
+ transform: translateX(-50%) translateY(0);
73
+ }
74
+ `;
75
+ document.head.appendChild(style);
76
+
77
+ // Create Toaster Element
78
+ const statusToaster = document.createElement('div');
79
+ statusToaster.id = 'admin-status-toaster';
80
+ document.body.appendChild(statusToaster);
81
+
82
+ // Visual Feedback Helper (Matching soundboard.html)
83
+ function showAdminToast(message, type = 'info') {
84
+ statusToaster.innerHTML = '';
85
+
86
+ let iconHtml = '';
87
+ if (type === 'error' || type === 'red') {
88
+ statusToaster.style.borderColor = '#ef4444';
89
+ iconHtml = '<i class="fa-solid fa-circle-exclamation text-red-500"></i>';
90
+ } else if (type === 'success' || type === 'green') {
91
+ statusToaster.style.borderColor = '#22c55e';
92
+ iconHtml = '<i class="fa-solid fa-check-circle text-green-500"></i>';
93
+ } else {
94
+ statusToaster.style.borderColor = '#333';
95
+ iconHtml = '<i class="fa-solid fa-info-circle text-blue-400"></i>';
96
+ }
97
+
98
+ statusToaster.innerHTML = `${iconHtml}<span>${message}</span>`;
99
+ statusToaster.classList.add('visible');
100
+
101
+ if (toasterTimeout) clearTimeout(toasterTimeout);
102
+ toasterTimeout = setTimeout(() => statusToaster.classList.remove('visible'), 2000);
103
+ }
104
+
105
+ function cleanupListeners() {
106
+ if (adminUnsubscribe) {
107
+ adminUnsubscribe();
108
+ adminUnsubscribe = null;
109
+ }
110
+ isAdmin = false;
111
+ }
112
+
113
+ // Toggle Config Function
114
+ async function toggleConfig(field, name) {
115
+ if (!isAdmin) {
116
+ console.warn("[Admin Keybinds] Access denied. Not an admin.");
117
+ return;
118
+ }
119
+
120
+ console.log(`[Admin Keybinds] Toggling ${name}...`);
121
+ const configRef = doc(db, 'config', 'soundboard');
122
+
123
+ try {
124
+ const snap = await getDoc(configRef);
125
+ let currentVal = true; // Default to true if not set
126
+ if (snap.exists()) {
127
+ const data = snap.data();
128
+ if (data[field] !== undefined) {
129
+ currentVal = data[field];
130
+ }
131
+ }
132
+
133
+ const newVal = !currentVal;
134
+ await setDoc(configRef, { [field]: newVal }, { merge: true });
135
+
136
+ const statusColor = newVal ? "green" : "red";
137
+ const statusText = newVal ? "ENABLED" : "DISABLED";
138
+ showAdminToast(`${name}: ${statusText}`, statusColor);
139
+
140
+ } catch (err) {
141
+ console.error(`[Admin Keybinds] Error toggling ${name}:`, err);
142
+ showAdminToast(`Error: ${err.message}`, "error");
143
+ }
144
+ }
145
+
146
+ // Keybind Listener
147
+ document.addEventListener('keydown', async (e) => {
148
+ // Only run if admin, Shift key, and Ctrl key are pressed
149
+ if (!isAdmin || !e.shiftKey || !e.ctrlKey) return;
150
+
151
+ // Shift + Ctrl + E: Explicit Sounds
152
+ if (e.key.toLowerCase() === 'e') {
153
+ e.preventDefault();
154
+ e.stopPropagation(); // Ensure it stops here
155
+ toggleConfig('explicitEnabled', 'Explicit Sounds');
156
+ }
157
+
158
+ // Shift + Ctrl + F: Third Party Sounds
159
+ if (e.key.toLowerCase() === 'f') {
160
+ e.preventDefault();
161
+ e.stopPropagation();
162
+ toggleConfig('thirdPartyEnabled', 'Third Party Sounds');
163
+ }
164
+ }, { capture: true }); // Use capture to intercept before inputs
165
+
166
+ // Auth & Role Check
167
+ onAuthStateChanged(auth, (user) => {
168
+ if (user) {
169
+ if (user.email && user.email.toLowerCase() === OWNER_EMAIL) {
170
+ console.log(`[Admin Keybinds] Owner recognized: ${OWNER_EMAIL}`);
171
+ isAdmin = true;
172
+ return;
173
+ }
174
+
175
+ if (adminUnsubscribe) adminUnsubscribe();
176
+
177
+ adminUnsubscribe = onSnapshot(doc(db, 'admins', user.uid), (docSnap) => {
178
+ if (docSnap.exists()) {
179
+ const data = docSnap.data();
180
+ const role = (data.role || '').toLowerCase();
181
+
182
+ if (role === 'admin' || role === 'superadmin') {
183
+ if (!isAdmin) console.log("[Admin Keybinds] Admin privileges active.");
184
+ isAdmin = true;
185
+ } else {
186
+ isAdmin = false;
187
+ }
188
+ } else {
189
+ isAdmin = false;
190
+ }
191
+ }, (error) => {
192
+ console.error("[Admin Keybinds] Admin check error:", error);
193
+ isAdmin = false;
194
+ });
195
+ } else {
196
+ cleanupListeners();
197
+ }
198
+ });
199
+
200
+ })();
@@ -0,0 +1,2 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).BareMux={})}(this,(function(e){"use strict";const t=globalThis.fetch,r=globalThis.SharedWorker,a=globalThis.localStorage,o=globalThis.navigator.serviceWorker,s=MessagePort.prototype.postMessage,n={prototype:{send:WebSocket.prototype.send},CLOSED:WebSocket.CLOSED,CLOSING:WebSocket.CLOSING,CONNECTING:WebSocket.CONNECTING,OPEN:WebSocket.OPEN};async function c(){const e=(await self.clients.matchAll({type:"window",includeUncontrolled:!0})).map((async e=>{const t=await function(e){let t=new MessageChannel;return new Promise((r=>{e.postMessage({type:"getPort",port:t.port2},[t.port2]),t.port1.onmessage=e=>{r(e.data)}}))}(e);return await i(t),t})),t=Promise.race([Promise.any(e),new Promise(((e,t)=>setTimeout(t,1e3,new TypeError("timeout"))))]);try{return await t}catch(e){if(e instanceof AggregateError)throw console.error("bare-mux: failed to get a bare-mux SharedWorker MessagePort as all clients returned an invalid MessagePort."),new Error("All clients returned an invalid MessagePort.");return console.warn("bare-mux: failed to get a bare-mux SharedWorker MessagePort within 1s, retrying"),await c()}}function i(e){const t=new MessageChannel,r=new Promise(((e,r)=>{t.port1.onmessage=t=>{"pong"===t.data.type&&e()},setTimeout(r,1500)}));return s.call(e,{message:{type:"ping"},port:t.port2},[t.port2]),r}function l(e,t){const a=new r(e,"bare-mux-worker");return t&&o.addEventListener("message",(t=>{if("getPort"===t.data.type&&t.data.port){console.debug("bare-mux: recieved request for port from sw");const a=new r(e,"bare-mux-worker");s.call(t.data.port,a.port,[a.port])}})),a.port}let h=null;function d(){if(null===h){const e=new MessageChannel,t=new ReadableStream;let r;try{s.call(e.port1,t,[t]),r=!0}catch(e){r=!1}return h=r,r}return h}class p{constructor(e){this.channel=new BroadcastChannel("bare-mux"),e instanceof MessagePort||e instanceof Promise?this.port=e:this.createChannel(e,!0)}createChannel(e,t){if(self.clients)this.port=c(),this.channel.onmessage=e=>{"refreshPort"===e.data.type&&(this.port=c())};else if(e&&SharedWorker){if(!e.startsWith("/")&&!e.includes("://"))throw new Error("Invalid URL. Must be absolute or start at the root.");this.port=l(e,t),console.debug("bare-mux: setting localStorage bare-mux-path to",e),a["bare-mux-path"]=e}else{if(!SharedWorker)throw new Error("Unable to get a channel to the SharedWorker.");{const e=a["bare-mux-path"];if(console.debug("bare-mux: got localStorage bare-mux-path:",e),!e)throw new Error("Unable to get bare-mux workerPath from localStorage.");this.port=l(e,t)}}}async sendMessage(e,t){this.port instanceof Promise&&(this.port=await this.port);try{await i(this.port)}catch{return console.warn("bare-mux: Failed to get a ping response from the worker within 1.5s. Assuming port is dead."),this.createChannel(),await this.sendMessage(e,t)}const r=new MessageChannel,a=[r.port2,...t||[]],o=new Promise(((e,t)=>{r.port1.onmessage=r=>{const a=r.data;"error"===a.type?t(a.error):e(a)}}));return s.call(this.port,{message:e,port:r.port2},a),await o}}class u extends EventTarget{constructor(e,t=[],r,a){super(),this.protocols=t,this.readyState=n.CONNECTING,this.url=e.toString(),this.protocols=t;const o=e=>{this.protocols=e,this.readyState=n.OPEN;const t=new Event("open");this.dispatchEvent(t)},s=async e=>{const t=new MessageEvent("message",{data:e});this.dispatchEvent(t)},c=(e,t)=>{this.readyState=n.CLOSED;const r=new CloseEvent("close",{code:e,reason:t});this.dispatchEvent(r)},i=()=>{this.readyState=n.CLOSED;const e=new Event("error");this.dispatchEvent(e)};this.channel=new MessageChannel,this.channel.port1.onmessage=e=>{"open"===e.data.type?o(e.data.args[0]):"message"===e.data.type?s(e.data.args[0]):"close"===e.data.type?c(e.data.args[0],e.data.args[1]):"error"===e.data.type&&i()},r.sendMessage({type:"websocket",websocket:{url:e.toString(),protocols:t,requestHeaders:a,channel:this.channel.port2}},[this.channel.port2])}send(...e){if(this.readyState===n.CONNECTING)throw new DOMException("Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.");let t=e[0];t.buffer&&(t=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength)),s.call(this.channel.port1,{type:"data",data:t},t instanceof ArrayBuffer?[t]:[])}close(e,t){s.call(this.channel.port1,{type:"close",closeCode:e,closeReason:t})}}function w(e,t,r){console.error(`error while processing '${r}': `,t),e.postMessage({type:"error",error:t})}function f(e){for(let t=0;t<e.length;t++){const r=e[t];if(!"!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~".includes(r))return!1}return!0}const g=["ws:","wss:"],y=[101,204,205,304],b=[301,302,303,307,308];class m{constructor(e){this.worker=new p(e)}createWebSocket(e,t=[],r,a){try{e=new URL(e)}catch(t){throw new DOMException(`Faiiled to construct 'WebSocket': The URL '${e}' is invalid.`)}if(!g.includes(e.protocol))throw new DOMException(`Failed to construct 'WebSocket': The URL's scheme must be either 'ws' or 'wss'. '${e.protocol}' is not allowed.`);Array.isArray(t)||(t=[t]),t=t.map(String);for(const e of t)if(!f(e))throw new DOMException(`Failed to construct 'WebSocket': The subprotocol '${e}' is invalid.`);a=a||{};return new u(e,t,this.worker,a)}async fetch(e,r){const a=new Request(e,r),o=r?.headers||a.headers,s=o instanceof Headers?Object.fromEntries(o):o,n=a.body;let c=new URL(a.url);if(c.protocol.startsWith("blob:")){const e=await t(c),r=new Response(e.body,e);return r.rawHeaders=Object.fromEntries(e.headers),r}for(let e=0;;e++){let t=(await this.worker.sendMessage({type:"fetch",fetch:{remote:c.toString(),method:a.method,headers:s,body:n||void 0}},n?[n]:[])).fetch,o=new Response(y.includes(t.status)?void 0:t.body,{headers:new Headers(t.headers),status:t.status,statusText:t.statusText});o.rawHeaders=t.headers,o.rawResponse=t,o.finalURL=c.toString();const i=r?.redirect||a.redirect;if(!b.includes(o.status))return o;switch(i){case"follow":{const t=o.headers.get("location");if(20>e&&null!==t){c=new URL(t,c);continue}throw new TypeError("Failed to fetch")}case"error":throw new TypeError("Failed to fetch");case"manual":return o}}}}console.debug("bare-mux: running v2.1.7 (build c56d286)"),e.BareClient=m,e.BareMuxConnection=class{constructor(e){this.worker=new p(e)}async getTransport(){return(await this.worker.sendMessage({type:"get"})).name}async setTransport(e,t,r){await this.setManualTransport(`\n\t\t\tconst { default: BareTransport } = await import("${e}");\n\t\t\treturn [BareTransport, "${e}"];\n\t\t`,t,r)}async setManualTransport(e,t,r){if("bare-mux-remote"===e)throw new Error("Use setRemoteTransport.");await this.worker.sendMessage({type:"set",client:{function:e,args:t}},r)}async setRemoteTransport(e,t){const r=new MessageChannel;r.port1.onmessage=async t=>{const r=t.data.port,a=t.data.message;if("fetch"===a.type)try{e.ready||await e.init(),await async function(e,t,r){const a=await r.request(new URL(e.fetch.remote),e.fetch.method,e.fetch.body,e.fetch.headers,null);if(!d()&&a.body instanceof ReadableStream){const e=new Response(a.body);a.body=await e.arrayBuffer()}a.body instanceof ReadableStream||a.body instanceof ArrayBuffer?s.call(t,{type:"fetch",fetch:a},[a.body]):s.call(t,{type:"fetch",fetch:a})}(a,r,e)}catch(e){w(r,e,"fetch")}else if("websocket"===a.type)try{e.ready||await e.init(),await async function(e,t,r){const[a,o]=r.connect(new URL(e.websocket.url),e.websocket.protocols,e.websocket.requestHeaders,(t=>{s.call(e.websocket.channel,{type:"open",args:[t]})}),(t=>{t instanceof ArrayBuffer?s.call(e.websocket.channel,{type:"message",args:[t]},[t]):s.call(e.websocket.channel,{type:"message",args:[t]})}),((t,r)=>{s.call(e.websocket.channel,{type:"close",args:[t,r]})}),(t=>{s.call(e.websocket.channel,{type:"error",args:[t]})}));e.websocket.channel.onmessage=e=>{"data"===e.data.type?a(e.data.data):"close"===e.data.type&&o(e.data.closeCode,e.data.closeReason)},s.call(t,{type:"websocket"})}(a,r,e)}catch(e){w(r,e,"websocket")}},await this.worker.sendMessage({type:"set",client:{function:"bare-mux-remote",args:[r.port2,t]}},[r.port2])}getInnerPort(){return this.worker.port}},e.BareWebSocket=u,e.WebSocketFields=n,e.WorkerConnection=p,e.browserSupportsTransferringStreams=d,e.default=m,e.maxRedirects=20,e.validProtocol=f,Object.defineProperty(e,"__esModule",{value:!0})}));
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,2 @@
1
+ const e=20,t=globalThis.fetch,r=globalThis.SharedWorker,a=globalThis.localStorage,s=globalThis.navigator.serviceWorker,o=MessagePort.prototype.postMessage,n={prototype:{send:WebSocket.prototype.send},CLOSED:WebSocket.CLOSED,CLOSING:WebSocket.CLOSING,CONNECTING:WebSocket.CONNECTING,OPEN:WebSocket.OPEN};async function c(){const e=(await self.clients.matchAll({type:"window",includeUncontrolled:!0})).map((async e=>{const t=await function(e){let t=new MessageChannel;return new Promise((r=>{e.postMessage({type:"getPort",port:t.port2},[t.port2]),t.port1.onmessage=e=>{r(e.data)}}))}(e);return await i(t),t})),t=Promise.race([Promise.any(e),new Promise(((e,t)=>setTimeout(t,1e3,new TypeError("timeout"))))]);try{return await t}catch(e){if(e instanceof AggregateError)throw console.error("bare-mux: failed to get a bare-mux SharedWorker MessagePort as all clients returned an invalid MessagePort."),new Error("All clients returned an invalid MessagePort.");return console.warn("bare-mux: failed to get a bare-mux SharedWorker MessagePort within 1s, retrying"),await c()}}function i(e){const t=new MessageChannel,r=new Promise(((e,r)=>{t.port1.onmessage=t=>{"pong"===t.data.type&&e()},setTimeout(r,1500)}));return o.call(e,{message:{type:"ping"},port:t.port2},[t.port2]),r}function l(e,t){const a=new r(e,"bare-mux-worker");return t&&s.addEventListener("message",(t=>{if("getPort"===t.data.type&&t.data.port){console.debug("bare-mux: recieved request for port from sw");const a=new r(e,"bare-mux-worker");o.call(t.data.port,a.port,[a.port])}})),a.port}let h=null;function d(){if(null===h){const e=new MessageChannel,t=new ReadableStream;let r;try{o.call(e.port1,t,[t]),r=!0}catch(e){r=!1}return h=r,r}return h}class p{constructor(e){this.channel=new BroadcastChannel("bare-mux"),e instanceof MessagePort||e instanceof Promise?this.port=e:this.createChannel(e,!0)}createChannel(e,t){if(self.clients)this.port=c(),this.channel.onmessage=e=>{"refreshPort"===e.data.type&&(this.port=c())};else if(e&&SharedWorker){if(!e.startsWith("/")&&!e.includes("://"))throw new Error("Invalid URL. Must be absolute or start at the root.");this.port=l(e,t),console.debug("bare-mux: setting localStorage bare-mux-path to",e),a["bare-mux-path"]=e}else{if(!SharedWorker)throw new Error("Unable to get a channel to the SharedWorker.");{const e=a["bare-mux-path"];if(console.debug("bare-mux: got localStorage bare-mux-path:",e),!e)throw new Error("Unable to get bare-mux workerPath from localStorage.");this.port=l(e,t)}}}async sendMessage(e,t){this.port instanceof Promise&&(this.port=await this.port);try{await i(this.port)}catch{return console.warn("bare-mux: Failed to get a ping response from the worker within 1.5s. Assuming port is dead."),this.createChannel(),await this.sendMessage(e,t)}const r=new MessageChannel,a=[r.port2,...t||[]],s=new Promise(((e,t)=>{r.port1.onmessage=r=>{const a=r.data;"error"===a.type?t(a.error):e(a)}}));return o.call(this.port,{message:e,port:r.port2},a),await s}}class w extends EventTarget{constructor(e,t=[],r,a){super(),this.protocols=t,this.readyState=n.CONNECTING,this.url=e.toString(),this.protocols=t;const s=e=>{this.protocols=e,this.readyState=n.OPEN;const t=new Event("open");this.dispatchEvent(t)},o=async e=>{const t=new MessageEvent("message",{data:e});this.dispatchEvent(t)},c=(e,t)=>{this.readyState=n.CLOSED;const r=new CloseEvent("close",{code:e,reason:t});this.dispatchEvent(r)},i=()=>{this.readyState=n.CLOSED;const e=new Event("error");this.dispatchEvent(e)};this.channel=new MessageChannel,this.channel.port1.onmessage=e=>{"open"===e.data.type?s(e.data.args[0]):"message"===e.data.type?o(e.data.args[0]):"close"===e.data.type?c(e.data.args[0],e.data.args[1]):"error"===e.data.type&&i()},r.sendMessage({type:"websocket",websocket:{url:e.toString(),protocols:t,requestHeaders:a,channel:this.channel.port2}},[this.channel.port2])}send(...e){if(this.readyState===n.CONNECTING)throw new DOMException("Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.");let t=e[0];t.buffer&&(t=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength)),o.call(this.channel.port1,{type:"data",data:t},t instanceof ArrayBuffer?[t]:[])}close(e,t){o.call(this.channel.port1,{type:"close",closeCode:e,closeReason:t})}}function u(e,t,r){console.error(`error while processing '${r}': `,t),e.postMessage({type:"error",error:t})}function g(e){for(let t=0;t<e.length;t++){const r=e[t];if(!"!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~".includes(r))return!1}return!0}const f=["ws:","wss:"],y=[101,204,205,304],b=[301,302,303,307,308];class m{constructor(e){this.worker=new p(e)}async getTransport(){return(await this.worker.sendMessage({type:"get"})).name}async setTransport(e,t,r){await this.setManualTransport(`\n\t\t\tconst { default: BareTransport } = await import("${e}");\n\t\t\treturn [BareTransport, "${e}"];\n\t\t`,t,r)}async setManualTransport(e,t,r){if("bare-mux-remote"===e)throw new Error("Use setRemoteTransport.");await this.worker.sendMessage({type:"set",client:{function:e,args:t}},r)}async setRemoteTransport(e,t){const r=new MessageChannel;r.port1.onmessage=async t=>{const r=t.data.port,a=t.data.message;if("fetch"===a.type)try{e.ready||await e.init(),await async function(e,t,r){const a=await r.request(new URL(e.fetch.remote),e.fetch.method,e.fetch.body,e.fetch.headers,null);if(!d()&&a.body instanceof ReadableStream){const e=new Response(a.body);a.body=await e.arrayBuffer()}a.body instanceof ReadableStream||a.body instanceof ArrayBuffer?o.call(t,{type:"fetch",fetch:a},[a.body]):o.call(t,{type:"fetch",fetch:a})}(a,r,e)}catch(e){u(r,e,"fetch")}else if("websocket"===a.type)try{e.ready||await e.init(),await async function(e,t,r){const[a,s]=r.connect(new URL(e.websocket.url),e.websocket.protocols,e.websocket.requestHeaders,(t=>{o.call(e.websocket.channel,{type:"open",args:[t]})}),(t=>{t instanceof ArrayBuffer?o.call(e.websocket.channel,{type:"message",args:[t]},[t]):o.call(e.websocket.channel,{type:"message",args:[t]})}),((t,r)=>{o.call(e.websocket.channel,{type:"close",args:[t,r]})}),(t=>{o.call(e.websocket.channel,{type:"error",args:[t]})}));e.websocket.channel.onmessage=e=>{"data"===e.data.type?a(e.data.data):"close"===e.data.type&&s(e.data.closeCode,e.data.closeReason)},o.call(t,{type:"websocket"})}(a,r,e)}catch(e){u(r,e,"websocket")}},await this.worker.sendMessage({type:"set",client:{function:"bare-mux-remote",args:[r.port2,t]}},[r.port2])}getInnerPort(){return this.worker.port}}class k{constructor(e){this.worker=new p(e)}createWebSocket(e,t=[],r,a){try{e=new URL(e)}catch(t){throw new DOMException(`Faiiled to construct 'WebSocket': The URL '${e}' is invalid.`)}if(!f.includes(e.protocol))throw new DOMException(`Failed to construct 'WebSocket': The URL's scheme must be either 'ws' or 'wss'. '${e.protocol}' is not allowed.`);Array.isArray(t)||(t=[t]),t=t.map(String);for(const e of t)if(!g(e))throw new DOMException(`Failed to construct 'WebSocket': The subprotocol '${e}' is invalid.`);a=a||{};return new w(e,t,this.worker,a)}async fetch(e,r){const a=new Request(e,r),s=r?.headers||a.headers,o=s instanceof Headers?Object.fromEntries(s):s,n=a.body;let c=new URL(a.url);if(c.protocol.startsWith("blob:")){const e=await t(c),r=new Response(e.body,e);return r.rawHeaders=Object.fromEntries(e.headers),r}for(let e=0;;e++){let t=(await this.worker.sendMessage({type:"fetch",fetch:{remote:c.toString(),method:a.method,headers:o,body:n||void 0}},n?[n]:[])).fetch,s=new Response(y.includes(t.status)?void 0:t.body,{headers:new Headers(t.headers),status:t.status,statusText:t.statusText});s.rawHeaders=t.headers,s.rawResponse=t,s.finalURL=c.toString();const i=r?.redirect||a.redirect;if(!b.includes(s.status))return s;switch(i){case"follow":{const t=s.headers.get("location");if(20>e&&null!==t){c=new URL(t,c);continue}throw new TypeError("Failed to fetch")}case"error":throw new TypeError("Failed to fetch");case"manual":return s}}}}console.debug("bare-mux: running v2.1.7 (build c56d286)");export{k as BareClient,m as BareMuxConnection,w as BareWebSocket,n as WebSocketFields,p as WorkerConnection,d as browserSupportsTransferringStreams,k as default,e as maxRedirects,g as validProtocol};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,136 @@
1
+ !(function () {
2
+ "use strict";
3
+ const e = MessagePort.prototype.postMessage;
4
+ let t = null;
5
+ function a(e, t, a) {
6
+ console.error(`error while processing '${a}': `, t),
7
+ e.postMessage({ type: "error", error: t });
8
+ }
9
+ async function n(a, n, s) {
10
+ const o = await s.request(
11
+ new URL(a.fetch.remote),
12
+ a.fetch.method,
13
+ a.fetch.body,
14
+ a.fetch.headers,
15
+ null
16
+ );
17
+ if (
18
+ !(function () {
19
+ if (null === t) {
20
+ const a = new MessageChannel(),
21
+ n = new ReadableStream();
22
+ let s;
23
+ try {
24
+ e.call(a.port1, n, [n]), (s = !0);
25
+ } catch (e) {
26
+ s = !1;
27
+ }
28
+ return (t = s), s;
29
+ }
30
+ return t;
31
+ })() &&
32
+ o.body instanceof ReadableStream
33
+ ) {
34
+ const e = new Response(o.body);
35
+ o.body = await e.arrayBuffer();
36
+ }
37
+ o.body instanceof ReadableStream || o.body instanceof ArrayBuffer
38
+ ? e.call(n, { type: "fetch", fetch: o }, [o.body])
39
+ : e.call(n, { type: "fetch", fetch: o });
40
+ }
41
+ let s = null,
42
+ o = "";
43
+ function c() {
44
+ return new Error("there are no bare clients", {
45
+ cause:
46
+ "No BareTransport was set. Try creating a BareMuxConnection and calling setTransport() or setManualTransport() on it before using BareClient.",
47
+ });
48
+ }
49
+ function r(t, a) {
50
+ const n = s;
51
+ let o = [a];
52
+ t.fetch?.body && o.push(t.fetch.body),
53
+ t.websocket?.channel && o.push(t.websocket.channel),
54
+ e.call(n, { message: t, port: a }, o);
55
+ }
56
+ function l(t) {
57
+ t.onmessage = async (t) => {
58
+ const l = t.data.port,
59
+ i = t.data.message;
60
+ if ("ping" === i.type) e.call(l, { type: "pong" });
61
+ else if ("set" === i.type)
62
+ try {
63
+ const t = async function () {}.constructor;
64
+ if ("bare-mux-remote" === i.client.function)
65
+ (s = i.client.args[0]),
66
+ (o = `bare-mux-remote (${i.client.args[1]})`);
67
+ else {
68
+ const e = new t(i.client.function),
69
+ [a, n] = await e();
70
+ (s = new a(...i.client.args)), (o = n);
71
+ }
72
+ console.log("set transport to ", s, o), e.call(l, { type: "set" });
73
+ } catch (e) {
74
+ a(l, e, "set");
75
+ }
76
+ else if ("get" === i.type) l.postMessage({ type: "get", name: o });
77
+ else if ("fetch" === i.type)
78
+ try {
79
+ if (!s) throw c();
80
+ if (s instanceof MessagePort) return void r(i, l);
81
+ s.ready || (await s.init()), await n(i, l, s);
82
+ } catch (e) {
83
+ a(l, e, "fetch");
84
+ }
85
+ else if ("websocket" === i.type)
86
+ try {
87
+ if (!s) throw c();
88
+ if (s instanceof MessagePort) return void r(i, l);
89
+ s.ready || (await s.init()),
90
+ await (async function (t, a, n) {
91
+ const [s, o] = n.connect(
92
+ new URL(t.websocket.url),
93
+ t.websocket.protocols,
94
+ t.websocket.requestHeaders,
95
+ (a) => {
96
+ e.call(t.websocket.channel, { type: "open", args: [a] });
97
+ },
98
+ (a) => {
99
+ a instanceof ArrayBuffer
100
+ ? e.call(
101
+ t.websocket.channel,
102
+ { type: "message", args: [a] },
103
+ [a]
104
+ )
105
+ : e.call(t.websocket.channel, {
106
+ type: "message",
107
+ args: [a],
108
+ });
109
+ },
110
+ (a, n) => {
111
+ e.call(t.websocket.channel, { type: "close", args: [a, n] });
112
+ },
113
+ (a) => {
114
+ e.call(t.websocket.channel, { type: "error", args: [a] });
115
+ }
116
+ );
117
+ (t.websocket.channel.onmessage = (e) => {
118
+ "data" === e.data.type
119
+ ? s(e.data.data)
120
+ : "close" === e.data.type &&
121
+ o(e.data.closeCode, e.data.closeReason);
122
+ }),
123
+ e.call(a, { type: "websocket" });
124
+ })(i, l, s);
125
+ } catch (e) {
126
+ a(l, e, "websocket");
127
+ }
128
+ };
129
+ }
130
+ new BroadcastChannel("bare-mux").postMessage({ type: "refreshPort" }),
131
+ (self.onconnect = (e) => {
132
+ l(e.ports[0]);
133
+ }),
134
+ console.debug("bare-mux: running v2.1.7 (build c56d286)");
135
+ })();
136
+ //# sourceMappingURL=worker.js.map
@@ -1248,7 +1248,7 @@
1248
1248
  allGames = [...strongdogGames, ...othersGames];
1249
1249
  }
1250
1250
 
1251
- allGames = allGames.filter(g => !['bitlife', 'soundboard'].some(term => g.name.toLowerCase().includes(term)));
1251
+ allGames = allGames.filter(g => !['bitlife', 'soundboard', 'five nights at e'].some(term => g.name.toLowerCase().includes(term)));
1252
1252
 
1253
1253
  searchableGames = [];
1254
1254
  allGames.forEach(game => {