Mucklet Audio Notifier

Audio notifications, per-character sounds and auto-refreshing character metadata

Bu betiği kurabilmeniz için Tampermonkey, Greasemonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

Bu betiği kurabilmeniz için Tampermonkey ya da Violentmonkey gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği kurabilmeniz için Tampermonkey ya da Userscripts gibi bir kullanıcı betiği eklentisini kurmanız gerekmektedir.

Bu betiği indirebilmeniz için ayrıca Tampermonkey gibi bir eklenti kurmanız gerekmektedir.

Bu betiği yüklemek için bir betik yöneticisi eklentisi yüklemeniz gerekecektir.

(Zaten bir betik yöneticim var, hadi yükleyelim!)

Bu stili yüklemek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için Stylus gibi bir uzantı kurmanız gerekir.

Bu stili yükleyebilmek için Stylus gibi bir uzantı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

Bu stili yüklemek için bir kullanıcı stili yöneticisi uzantısı kurmanız gerekir.

Bu stili yükleyebilmek için bir kullanıcı stili yöneticisi uzantısı yüklemeniz gerekir.

(Zateb bir user-style yöneticim var, yükleyeyim!)

// ==UserScript==
// @name         Mucklet Audio Notifier
// @name:de      Mucklet Audio Benachrichtigungen
// @namespace    https://forum.wolfery.com/u/felinex/
// @version      2.1.0
// @description  Audio notifications, per-character sounds and auto-refreshing character metadata
// @description:de Audio-Benachrichtigungen, Sounds pro Charakter und automatische Aktualisierung von Charakter-Metadaten
// @icon         https://mucklet.com/mucklet-logo.svg
// @license      All Rights Reserved
// @author       Felinex Gloomfort
// @match        https://wolfery.com/*
// @match        https://test.wolfery.com/*
// @match        https://mucklet.com/*
// @match        https://*.mucklet.com/*
// @grant        none
// ==/UserScript==
(function() {"use strict";console.log("[AudioNotifier] Script loaded (v2.1.0).");const e="https://actions.google.com/sounds/v1/alarms/beep_short.ogg",t="AudioNotifierSettings",n=1048576;let a=0,r=0,o=!1,i=!1;const l={muteWhenWindowFocused:!1,muteForActiveChar:!1,playOnFocusedChar:!0,soundDefault:null,soundMention:null,soundPrivate:null,soundFocusChar:null,charSounds:{}};let c=function(){try{const e=localStorage.getItem(t);if(!e)return{...l,charSounds:{}};const n=JSON.parse(e);return{...l,...n,charSounds:y(n.charSounds)}}catch(e){return console.error("[AudioNotifier] Failed to load settings",e),{...l,charSounds:{}}}}(),s=!1,d=!1,u=0,m=null;function h(e){return String(e||"").trim().replace(/\s+/g," ").toLowerCase()}function p(e){return"name:"+h(e)}function f(e){return"id:"+String(e)}function y(e){const t={},n=e&&"object"==typeof e?e:{};return Object.keys(n).forEach(e=>{const a=function(e,t){return t&&"object"==typeof t&&!Array.isArray(t)?{name:String(t.name||e.replace(/^name:/,"")).trim(),charId:null!=t.charId?String(t.charId):null!=t.id?String(t.id):null,avatar:t.avatar||null,sound:t.sound||null,alwaysPlay:!!t.alwaysPlay}:{name:String(e.replace(/^name:/,"")).trim(),charId:null,avatar:null,sound:"string"==typeof t?t:null,alwaysPlay:!1}}(e,n[e]),r=a.charId?f(a.charId):p(a.name||e);t[r]=a}),t}function g(){try{localStorage.setItem(t,JSON.stringify(c))}catch(e){console.error("[AudioNotifier] Failed to save settings",e)}}function v(e){try{return window.app&&"function"==typeof window.app.getModule?window.app.getModule(e):null}catch(e){return null}}function C(e){(function(e){return!!m||!!function(e){const t=v("playerTabs");if(!t||"function"!=typeof t.addTab)return!1;if(t.getTabs&&t.getTabs().get&&t.getTabs().get("audioNotifier"))return!1;let n=null,a=null;function r(t){let n=null;return{render:a=>(n=document.createElement("button"),n.type="button",n.className="iconbtn medium default-400 audio-notifier-player-tab-button",n.title=e.tabTitle,n.setAttribute("aria-label",e.tabTitle),n.innerHTML='<i class="fa fa-volume-up" aria-hidden="true"></i>',n.addEventListener("click",e=>{t(),e.stopPropagation()}),a.appendChild(n),n),unrender(){n&&n.parentNode&&n.parentNode.removeChild(n),n=null}}}function o(){return{render:t=>(n=t,a=b(e),t.appendChild(a),W(),a),unrender(){a&&a.parentNode&&a.parentNode.removeChild(a),a=null,n=null}}}try{return t.addTab({id:"audioNotifier",sortOrder:1e4,tabFactory:e=>r(e),factory:(t,n,a)=>({component:o(),title:e.title})}),m={mode:"hook",dispose:()=>{"function"==typeof t.removeTab&&t.removeTab("audioNotifier")}},console.log("[AudioNotifier] Registered via playerTabs.addTab()"),!0}catch(e){return console.debug("[AudioNotifier] playerTabs.addTab() failed:",e),!1}}(e)})(e)||(u++,u<40&&setTimeout(()=>C(e),500))}function b(e,t){const a=document.createElement("div");a.className="pad-bottom-l audio-notifier-panel",a.style.padding="16px";const r=document.createElement("div");r.style.display="flex",r.style.alignItems="center",r.style.justifyContent="space-between",r.style.gap="8px",r.style.marginTop="12px",r.style.marginBottom="12px";const o=document.createElement("h3");if(o.className="margin-bottom-m",o.style.margin="0",o.textContent=e.title,r.appendChild(o),"function"==typeof t){const n=document.createElement("button");n.type="button",n.className="btn small",n.textContent=e.closeBtn,n.addEventListener("click",()=>t()),r.appendChild(n)}a.appendChild(r),a.appendChild(w(e.muteWhenFocused,c.muteWhenWindowFocused,e=>{c.muteWhenWindowFocused=e,g()})),a.appendChild(w(e.muteForActiveChar,c.muteForActiveChar,e=>{c.muteForActiveChar=e,g()})),a.appendChild(w(e.playOnFocusCmd,c.playOnFocusedChar,e=>{c.playOnFocusedChar=e,g()}));const i=document.createElement("h3");i.className="margin-bottom-s",i.style.marginTop="15px",i.textContent=e.hdrDefault,a.appendChild(i),a.appendChild(S(e.soundDefault,"soundDefault",e));const l=document.createElement("h3");return l.className="margin-bottom-s",l.style.marginTop="15px",l.textContent=e.hdrCategories,a.appendChild(l),a.appendChild(S(e.soundMention,"soundMention",e,!0)),a.appendChild(S(e.soundPrivate,"soundPrivate",e,!0)),a.appendChild(S(e.soundFocusChar,"soundFocusChar",e,!0)),a.appendChild(function(e){const t=document.createElement("div");t.style.marginTop="15px";const a=document.createElement("h3");a.className="margin-bottom-s",a.textContent=e.hdrCharSounds,t.appendChild(a);const r=document.createElement("div");r.className="margin-bottom-s",r.style.fontSize="12px",r.style.opacity="0.8",r.textContent=e.searchHint,t.appendChild(r);const o=document.createElement("div");o.style.display="grid",o.style.gridTemplateColumns="1fr auto",o.style.gap="5px",o.style.marginBottom="6px";const i=document.createElement("input");i.type="text",i.placeholder=e.charSearchPlaceholder,l=i,l.style.flex="1",l.style.padding="4px",l.style.background="#1d2233",l.style.color="#fff",l.style.border="1px solid #303753",l.style.borderRadius="4px",l.style.minWidth="0";var l;const s=document.createElement("button");s.className="btn small",s.textContent=e.searchBtn,o.appendChild(i),o.appendChild(s),t.appendChild(o);const d=document.createElement("div");d.style.marginBottom="10px",t.appendChild(d);const u=document.createElement("div");t.appendChild(u);const m=document.createElement("input");m.type="file",m.accept="audio/*",m.style.display="none",t.appendChild(m);let h=null;const y=async()=>{const t=i.value.trim();if(!t)return;d.innerHTML=`<div style="font-size:12px;opacity:.8;padding:4px 0;">${e.searching}</div>`;v(await x(t))};function v(t){d.innerHTML="",t.length?t.slice(0,8).forEach(t=>{const n=document.createElement("div");n.style.display="grid",n.style.gridTemplateColumns="28px 1fr auto",n.style.gap="6px",n.style.alignItems="center",n.style.padding="4px 0",n.style.borderBottom="1px solid rgba(255,255,255,0.05)";const a=document.createElement("div");if(a.style.width="28px",a.style.height="28px",a.style.borderRadius="4px",a.style.overflow="hidden",a.style.background="rgba(255,255,255,0.08)",t.avatar){const e=document.createElement("img");e.src=t.avatar,e.alt=t.name,e.style.width="100%",e.style.height="100%",e.style.objectFit="cover",a.appendChild(e)}const r=document.createElement("div");r.style.minWidth="0";const o=document.createElement("div");o.style.fontSize="12px",o.style.fontWeight="600",o.style.whiteSpace="nowrap",o.style.overflow="hidden",o.style.textOverflow="ellipsis",o.textContent=t.name;const i=document.createElement("div");i.style.fontSize="11px",i.style.opacity="0.75",i.style.whiteSpace="nowrap",i.style.overflow="hidden",i.style.textOverflow="ellipsis",i.textContent=t.charId?`ID ${t.charId}`:e.byName,r.appendChild(o),r.appendChild(i);const l=document.createElement("button");l.className="btn small",l.textContent=e.chooseBtn,l.onclick=()=>{h=t,m.click()},n.appendChild(a),n.appendChild(r),n.appendChild(l),d.appendChild(n)}):d.innerHTML=`<div style="font-size:12px;opacity:.8;padding:4px 0;">${e.noResults}</div>`}function C(){u.innerHTML="";const t=Object.keys(c.charSounds);t.length&&(t.sort((e,t)=>{const n=c.charSounds[e]?.name||"",a=c.charSounds[t]?.name||"";return n.localeCompare(a)}),t.forEach(t=>{const a=c.charSounds[t];if(!a)return;const r=document.createElement("div");r.className="audio-notifier-char-row",r.style.display="grid",r.style.gridTemplateColumns="28px 1fr auto",r.style.gap="6px",r.style.alignItems="center",r.style.background="rgba(0,0,0,0.18)",r.style.padding="5px",r.style.borderRadius="4px",r.style.marginBottom="5px",r.dataset.entryKey=t,r.dataset.charId=a.charId?String(a.charId):"",r.dataset.charName=a.name||"";const o=document.createElement("div");if(o.style.width="28px",o.style.height="28px",o.style.borderRadius="4px",o.style.overflow="hidden",o.style.background="rgba(255,255,255,0.08)",a.avatar){const e=document.createElement("img");e.className="audio-notifier-char-row-avatar",e.src=a.avatar,e.alt=a.name||t,e.style.width="100%",e.style.height="100%",e.style.objectFit="cover",o.appendChild(e)}const i=document.createElement("div");i.style.minWidth="0";const l=document.createElement("div");l.className="audio-notifier-char-row-title",l.style.fontSize="12px",l.style.fontWeight="600",l.style.whiteSpace="nowrap",l.style.overflow="hidden",l.style.textOverflow="ellipsis",l.textContent=a.name||t;const s=document.createElement("div");s.style.fontSize="11px",s.style.opacity="0.75",s.style.whiteSpace="nowrap",s.style.overflow="hidden",s.style.textOverflow="ellipsis",s.textContent=a.charId?`ID ${a.charId}`:e.byName;const d=document.createElement("label");d.className="checkbox",d.style.display="flex",d.style.alignItems="center",d.style.gap="4px",d.style.fontSize="11px",d.style.marginTop="2px";const m=document.createElement("input");m.type="checkbox",m.checked=!!a.alwaysPlay,m.addEventListener("change",e=>{a.alwaysPlay=e.target.checked,g()});const h=document.createElement("span");h.textContent=e.alwaysPlay,d.appendChild(m),d.appendChild(h),i.appendChild(l),i.appendChild(s),i.appendChild(d);const p=document.createElement("div");p.style.display="flex",p.style.gap="4px",p.style.alignItems="center";const f=document.createElement("input");f.type="file",f.accept="audio/*",f.style.display="none",f.addEventListener("change",t=>{const r=t.target.files&&t.target.files[0];if(!r)return;if(r.size>n)return alert(e.sizeWarning);const o=new FileReader;o.onloadend=()=>{a.sound=o.result,g(),C(),f.value=""},o.readAsDataURL(r)});const y=document.createElement("button");y.className="btn small",y.textContent=e.replaceBtn,y.onclick=()=>f.click();const v=document.createElement("button");v.className="btn small primary",v.textContent=e.testBtn,v.onclick=()=>z(a.sound||L("soundDefault"),!0);const b=document.createElement("button");b.className="btn small error",b.textContent=e.resetBtn,b.onclick=()=>{delete c.charSounds[t],g(),C()},p.appendChild(f),p.appendChild(y),p.appendChild(v),p.appendChild(b),r.appendChild(o),r.appendChild(i),r.appendChild(p),u.appendChild(r)}))}return s.addEventListener("click",y),i.addEventListener("keydown",e=>{"Enter"===e.key&&(e.preventDefault(),y())}),m.addEventListener("change",t=>{const a=t.target.files&&t.target.files[0];if(!a||!h)return;if(a.size>n)return alert(e.sizeWarning);const r=new FileReader;r.onloadend=()=>{const e=h,t=e.charId?f(e.charId):p(e.name);c.charSounds[t]={name:e.name,charId:e.charId||null,avatar:e.avatar||null,sound:r.result,alwaysPlay:!1},g(),h=null,m.value="",d.innerHTML="",i.value="",C()},r.readAsDataURL(a)}),C(),t}(e)),a}function w(e,t,n){const a=document.createElement("div");a.className="margin-bottom-m";const r=document.createElement("label");r.className="checkbox",r.style.display="flex",r.style.alignItems="center",r.style.cursor="pointer";const o=document.createElement("input");o.type="checkbox",o.checked=t,o.addEventListener("change",e=>n(e.target.checked));const i=document.createElement("span");return i.textContent=e,i.style.marginLeft="8px",r.appendChild(o),r.appendChild(i),a.appendChild(r),a}function S(e,t,a,r=!1){const o=document.createElement("div");o.className="margin-bottom-m",o.style.display="flex",o.style.alignItems="center",o.style.justifyContent="space-between",o.style.gap="5px";const i=document.createElement("span");i.style.flex="1",i.style.fontSize="14px";const l=()=>{const n=null!==c[t];i.innerHTML=`${e} [${n?"Custom":r?"Fallback":"System Default"}]`};l();const s=document.createElement("div");s.style.display="flex",s.style.gap="5px";const d=document.createElement("input");d.type="file",d.accept="audio/*",d.style.display="none";const u=document.createElement("button");u.className="btn small",u.textContent=a.uploadBtn,u.onclick=()=>d.click();const m=document.createElement("button");m.className="btn small primary",m.textContent=a.testBtn,m.onclick=()=>z(L(t),!0);const h=document.createElement("button");return h.className="btn small error",h.textContent=a.resetBtn,h.onclick=()=>{c[t]=null,g(),l()},d.addEventListener("change",e=>{const r=e.target.files&&e.target.files[0];if(!r)return;if(r.size>n)return alert(a.sizeWarning);const o=new FileReader;o.onloadend=()=>{c[t]=o.result,g(),l(),z(c[t],!0),d.value=""},o.readAsDataURL(r)}),s.appendChild(d),s.appendChild(u),s.appendChild(h),s.appendChild(m),o.appendChild(i),o.appendChild(s),o}async function x(e){const t=String(e||"").trim();if(!t)return[];const n=function(){const e=v("player")||window.player||window.muckletClient?.player||null,t=v("charsAwake")||window.charsAwake||window.muckletClient?.charsAwake||null;return e&&t?{player:e,charsAwake:t}:null}();if(!n)return console.debug("[AudioNotifier] SearchChar modules not available"),[];const{player:a,charsAwake:r}=n;let o=null;if(t.split(/\s+/).length>1&&a?.getPlayer)try{o=await a.getPlayer().call("getChar",{charName:t})}catch(e){(function(e){return!(!e||"core.charNotFound"!==e.code&&"core.charNotFound"!==e.errorCode&&"core.charNotFound"!==e.message)})(e)||console.debug("[AudioNotifier] getChar failed",e)}const i="function"==typeof a?.getActiveChar?a.getActiveChar():null,l="function"==typeof r?.getWatches?r.getWatches():null,c=l&&l.props?Object.keys(l.props).map(e=>l.props[e]?.char).filter(Boolean):[];return A([o?[o]:null,"function"==typeof a?.getChars?a.getChars():null,i?.inRoom?.chars||null,"function"==typeof r?.getCollection?r.getCollection():null,c]).filter(e=>e&&function(e,t){const n=k(I(e)),a=k(t).split(/\s+/).filter(Boolean);return!(!n||!a.length)&&a.every(e=>n.includes(e))}(e,t)).map(e=>N(e)).filter(Boolean).sort(function(e){const t=k(e);return(e,n)=>{const a=k(e.name||""),r=k(n.name||""),o=a===t?1:0,i=r===t?1:0;if(o!==i)return i-o;const l=a.startsWith(t)?1:0,c=r.startsWith(t)?1:0;if(l!==c)return c-l;const s=a.indexOf(t),d=r.indexOf(t),u=-1===s?9999:s,m=-1===d?9999:d;return u!==m?u-m:a.localeCompare(r)}}(t)).slice(0,10)}function A(e){const t=[],n=new Set;for(const a of e)for(const e of E(a)){if(!e)continue;const a=null!=e.id?String(e.id):null,r=I(e),o=a?`id:${a}`:`name:${k(r)}`;o&&!n.has(o)&&(n.add(o),t.push(e))}return t}function E(e){return e?Array.isArray(e)?e.filter(Boolean):"function"==typeof e.toArray?e.toArray().filter(Boolean):e.props&&"object"==typeof e.props?Object.values(e.props).filter(Boolean):e.models&&Array.isArray(e.models)?e.models.filter(Boolean):e.items&&Array.isArray(e.items)?e.items.filter(Boolean):[]:[]}function N(e){if(!e)return null;const t=`${e.name||""} ${e.surname||""}`.trim()||e.fullName||e.label||null;return t?{name:t,charId:null!=e.id?String(e.id):null,avatar:F(e)||null}:null}function I(e){return e&&(`${e.name||""} ${e.surname||""}`.trim()||e.fullName||e.label)||""}function k(e){return String(e||"").normalize("NFD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/\s+/g," ").trim()}function F(e){const t=[e&&e.avatar&&e.avatar.href,e&&e.avatar&&e.avatar.url,e&&e.avatar&&e.avatar.src,e&&e.icon&&e.icon.href,e&&e.icon&&e.icon.url,e&&e.icon&&e.icon.src,e&&e.avatarUrl,e&&e.iconUrl,e&&e.avatar,e&&e.icon,e&&e.image&&e.image.href,e&&e.image&&e.image.url,e&&e.imageUrl,e&&e.portrait&&e.portrait.href,e&&e.img&&e.img.href,e&&e.img&&e.img.url,e&&e.imgUrl].filter(e=>"string"==typeof e&&e.trim());for(const e of t){const t=T(e);if(t)return t}return null}function T(e){const t=String(e||"").trim();return t?/^https?:\/\/file\.wolfery\.com\/core\/char\/avatar\//i.test(t)?B(t):/^https?:\/\/file\.wolfery\.com\/core\/char\/img\//i.test(t)?B(t.replace(/\/core\/char\/img\//i,"/core/char/avatar/")):/^\/core\/char\/avatar\//i.test(t)?B("https://file.wolfery.com"+t):/^\/core\/char\/img\//i.test(t)?B("https://file.wolfery.com"+t.replace(/\/core\/char\/img\//i,"/core/char/avatar/")):/^[a-z0-9]+$/i.test(t)?`https://file.wolfery.com/core/char/avatar/${t}?thumb=l`:/\/char\/avatar\//i.test(t)?B(t):/\/char\/img\//i.test(t)?B(t.replace(/\/char\/img\//i,"/char/avatar/")):null:null}function B(e){const t=String(e||"").replace(/[?&]thumb=[^&]+/gi,"");return t+(t.includes("?")?"&thumb=l":"?thumb=l")}function L(t){return c[t]?c[t]:c.soundDefault?c.soundDefault:e}async function O(e){if(!e)return null;const t={name:String(e.name||"").trim(),charId:null!=e.charId?String(e.charId):null,avatar:e.avatar||null,sound:e.sound||null,alwaysPlay:!!e.alwaysPlay},n=await async function(e){const t=v("player"),n=v("charsAwake"),a=t&&"function"==typeof t.getActiveChar?t.getActiveChar():null,r=A(["function"==typeof t?.getChars?t.getChars():null,a?.inRoom?.chars||null,"function"==typeof n?.getCollection?n.getCollection():null]);if(e.charId){const t=r.find(t=>String(t?.id)===String(e.charId));if(t)return N(t)}if(e.name){const t=(await x(e.name)).find(t=>h(t.name)===h(e.name));if(t)return t}return null}(t);return n?{...t,name:n.name||t.name,charId:n.charId||t.charId,avatar:n.avatar||t.avatar}:t}function P(e){const t=e.target;if(!(t instanceof HTMLImageElement))return;if(!t.classList.contains("audio-notifier-char-row-avatar"))return;const n=t.closest(".audio-notifier-char-row");if(!(n instanceof HTMLElement))return;const a=n.dataset.entryKey||"";let r=a?c.charSounds[a]:null;r||(r=D(n)),r&&O(r).then(e=>{if(!e)return;const o=a||(r.charId?f(r.charId):p(r.name)),i=e.charId?f(e.charId):p(e.name||o);o!==i&&delete c.charSounds[o],c.charSounds[i]=e,g(),M(n,i,e),e.avatar&&t.src!==e.avatar&&(t.src=e.avatar)}).catch(e=>{console.debug("[AudioNotifier] Failed to refresh avatar after image error",e)})}function D(e){const t=e.dataset.charId||"",n=e.dataset.charName||"";if(t){const e=c.charSounds[f(t)];if(e)return e}if(n){const e=c.charSounds[p(n)];if(e)return e}return null}function W(){document.querySelectorAll(".audio-notifier-char-row").forEach(e=>{if(!(e instanceof HTMLElement))return;const t=e.dataset.entryKey||"",n=c.charSounds[t]||D(e);if(!n)return;M(e,n.charId?f(n.charId):p(n.name||t),n)})}function M(e,t,n){e.dataset.entryKey=t,e.dataset.charId=n.charId?String(n.charId):"",e.dataset.charName=n.name||"";const a=e.querySelector(".audio-notifier-char-row-title");a&&(a.textContent=n.name||t);const r=e.querySelector(".audio-notifier-char-row-avatar");r instanceof HTMLImageElement&&n.avatar&&(r.src=n.avatar,r.alt=n.name||t)}function z(t,n=!1){const r=Date.now();if(n||!(r-a<1e3)){n||(a=r);try{const n=new Audio(t||e);n.volume=.5,n.play().catch(e=>{console.error("[AudioNotifier] Playback failed. Browser blocking autoplay?",e)})}catch(e){console.error("[AudioNotifier] Invalid audio source",e)}}}document.addEventListener("click",function e(){new Audio("data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA").play().catch(()=>{}),document.removeEventListener("click",e)},{once:!0}),window.addEventListener("beforeunload",function(){if(m&&"function"==typeof m.dispose)try{m.dispose()}catch(e){console.debug("[AudioNotifier] Failed to dispose custom UI",e)}m=null}),setTimeout(function e(){if(r++,void 0===window.app)return void(r<60&&setTimeout(e,500));const t=v("charLog");t?(o||(!function(){const e=navigator.language.startsWith("de");C({title:e?"Audio Notifier (Benutzerskript)":"Audio Notifier (Userscript)",tabTitle:e?"Audio Notifier öffnen":"Open Audio Notifier",muteWhenFocused:e?"Ton deaktivieren, wenn das Fenster fokussiert ist":"Disable sound when the window is focused",muteForActiveChar:e?"Ton für aktiven Charakter deaktivieren (Ignoriert bei Fokusverlust)":"Disable sound for active character (Ignored if window loses focus)",playOnFocusCmd:e?"Ton abspielen, wenn fokussierter Charakter schreibt (/focus)":"Play sound when a focused character writes (/focus)",hdrDefault:e?"1. Standard-Sound":"1. Default Sound",soundDefault:e?"Allgemeiner Ton":"Global Default Sound",hdrCategories:e?"2. Spezifische Kategorien (Optional)":"2. Specific Categories (Optional)",soundMention:e?"Erwähnungen":"Mentions",soundPrivate:e?"Private Nachrichten":"Private Messages",soundFocusChar:e?"Fokussierte Charaktere":"Focused characters",hdrCharSounds:e?"3. Sound pro Charakter":"3. Per-character sounds",charSearchPlaceholder:e?"Name suchen...":"Search name...",searchBtn:e?"Suchen":"Search",chooseBtn:"Sound",uploadBtn:e?"Wählen":"Browse",replaceBtn:e?"Neu":"Replace",testBtn:"▶️",resetBtn:"✖",closeBtn:e?"Schließen":"Close",sizeWarning:e?"Datei zu groß (max 1MB).":"File too large (max 1MB).",noResults:e?"Keine Treffer":"No results",searching:e?"Suche...":"Searching...",searchHint:e?"Suche per Name, speichere ID + Avatar.":"Search by name, store ID + avatar.",alwaysPlay:e?"Immer":"Always",byId:"ID",byName:"Name",noSound:e?"Kein Sound":"No sound"})}(),o=!0),i||(!function(e){e.addEventModifier({id:"userscriptSoundNotifier",sortOrder:50,callback:(e,t,n)=>{if(n.muted)return;if(e.char&&e.char.id===t.id)return;const a=document.hasFocus();if(c.muteWhenWindowFocused&&a)return;if(c.muteForActiveChar&&a){const e=v("player"),n=e&&"function"==typeof e.getActiveChar?e.getActiveChar():null;if(n&&n.id===t.id)return}let r=function(e){if(!e)return null;const t=null!=e.id?String(e.id):null;if(t){const e=f(t);if(c.charSounds[e])return e}const n=h(`${e.name||""} ${e.surname||""}`.trim()),a=h(e.name||"");return Object.keys(c.charSounds).find(e=>{const r=c.charSounds[e];if(!r)return!1;if(r.charId&&t&&String(r.charId)===t)return!0;const o=h(r.name||e.replace(/^name:/,""));return o&&(o===n||o===a)})||null}(e.char);r&&e.char&&(r=function(e,t){const n=c.charSounds[e];if(!n||!t)return e;const a=`${t.name||""} ${t.surname||""}`.trim()||n.name,r=null!=t.id?String(t.id):n.charId,o=F(t)||n.avatar;if(n.name=a,n.charId=r,n.avatar=o,r){const t=f(r);if(t!==e)return c.charSounds[t]={...n},delete c.charSounds[e],g(),t}return g(),e}(r,e.char));const o=r?c.charSounds[r]:null;let i=!1,l=null;if(o&&o.alwaysPlay&&o.sound&&function(e){return["say","pose","ooc","whisper","message","address"].includes(e.type)}(e)&&(i=!0,l=o.sound),!i&&n.mentioned&&(i=!0,l=L("soundMention")),!i&&function(e,t,n){return!!["whisper","message","address"].includes(e.type)&&(!!n.targeted||(!(!e.target||e.target.id!==t.id)||!!Array.isArray(e.targets)&&e.targets.some(e=>e&&e.id===t.id)))}(e,t,n)&&(i=!0,l=L("soundPrivate")),!i&&c.playOnFocusedChar&&e.char){const n=v("charFocus");n&&"function"==typeof n.hasFocus&&n.hasFocus(t.id,e.char.id)&&(i=!0,l=L("soundFocusChar"))}i&&o&&o.sound&&(l=o.sound),i&&z(l)}})}(t),i=!0),s||(s=!0,function(){const e=Object.entries(c.charSounds||{});if(!e.length)return;Promise.all(e.map(async([e,t])=>{const n=await O(t);return n?[e,n]:null})).then(e=>{let t=!1;for(const n of e){if(!n)continue;const[e,a]=n,r=a.charId?f(a.charId):p(a.name||e),o=JSON.stringify(c.charSounds[e]||null),i=JSON.stringify(a);e!==r&&(delete c.charSounds[e],t=!0),o==i&&c.charSounds[r]||(c.charSounds[r]=a,t=!0)}t&&g(),W()}).catch(e=>{console.debug("[AudioNotifier] Failed to refresh stored character metadata",e)})}()),d||(d=!0,document.addEventListener("error",P,!0),setTimeout(W,1200))):r<60&&setTimeout(e,500)},1e3);})();