1(function () { 2 'use strict'; 3 4 var initialized = false; 5 6 function isContactPage() { 7 return window.location.pathname.replace(/\/+$/, '') === '/contact'; 8 } 9 10 function findContactForm() { 11 var forms = document.querySelectorAll('form'); 12 for (var i = 0; i < forms.length; i++) { 13 var form = forms[i]; 14 var hasName = form.querySelector('input[formcontrolname="name"], input[name="name"], #name'); 15 var hasEmail = form.querySelector('input[formcontrolname="email"], input[name="email"], #email'); 16 var hasMessage = form.querySelector('textarea[formcontrolname="message"], textarea[name="message"], #message'); 17 if (hasName && hasEmail && hasMessage) return form; 18 } 19 return null; 20 } 21 22 function makeLink(href, label, primary) { 23 var link = document.createElement('a'); 24 link.href = href; 25 link.className = primary ? 'ws791-link ws791-link-primary' : 'ws791-link'; 26 link.textContent = label; 27 return link; 28 } 29 30 function hideLegacyBackButton(parent) { 31 var children = parent.children || []; 32 for (var i = 0; i < children.length; i++) { 33 var child = children[i]; 34 if (child.tagName !== 'A') continue; 35 var href = child.getAttribute('href') || ''; 36 if (href === '/' || href === '') { 37 child.classList.add('ws791-legacy-back'); 38 } 39 } 40 } 41 42 function addCategoryField(form) { 43 if (form.querySelector('select[formcontrolname="category"], #category, #ws791-category')) return; 44 45 var message = form.querySelector('textarea[formcontrolname="message"], textarea[name="message"], #message'); 46 if (!message) return; 47 48 var messageContainer = message.closest('.input-container') || message.parentNode; 49 if (!messageContainer || !messageContainer.parentNode) return; 50 51 var wrapper = document.createElement('div'); 52 wrapper.className = 'input-container ws791-category-field'; 53 wrapper.innerHTML = '' + 54 '<label for="ws791-category">What can we help with?</label>' + 55 '<select id="ws791-category">' + 56 '<option value="General question">General question</option>' + 57 '<option value="Billing or subscription">Billing or subscription</option>' + 58 '<option value="WavCash or loyalty balance">WavCash or loyalty balance</option>' + 59 '<option value="Artist earnings or payout">Artist earnings or payout</option>' + 60 '<option value="Account or login">Account or login</option>' + 61 '<option value="Technical issue">Technical issue</option>' + 62 '<option value="Privacy or legal request">Privacy or legal request</option>' + 63 '<option value="Other">Other</option>' + 64 '</select>'; 65 66 messageContainer.parentNode.insertBefore(wrapper, messageContainer); 67 68 form.addEventListener('submit', function () { 69 var select = form.querySelector('#ws791-category'); 70 var textarea = form.querySelector('textarea[formcontrolname="message"], textarea[name="message"], #message'); 71 if (!select || !textarea) return; 72 73 var prefix = '[Category: ' + select.value + ']\n'; 74 if (textarea.value.indexOf('[Category:') !== 0) { 75 textarea.value = prefix + textarea.value; 76 textarea.dispatchEvent(new Event('input', {bubbles: true})); 77 textarea.dispatchEvent(new Event('change', {bubbles: true})); 78 } 79 }, true); 80 } 81 82 function enhance() { 83 if (!isContactPage()) return false; 84 85 var form = findContactForm(); 86 if (!form || form.getAttribute('data-ws791') === '1') return false; 87 88 var parent = form.parentNode; 89 if (!parent) return false; 90 91 form.setAttribute('data-ws791', '1'); 92 form.classList.add('ws791-form'); 93 parent.classList.add('ws791-host'); 94 hideLegacyBackButton(parent); 95 96 var nav = document.createElement('nav'); 97 nav.className = 'ws791-nav'; 98 nav.setAttribute('aria-label', 'Contact page navigation'); 99 nav.appendChild(makeLink('/', 'Home', true)); 100 nav.appendChild(makeLink('/account/settings', 'Account Settings')); 101 nav.appendChild(makeLink('/wavcash-policy', 'WavCash Policy')); 102 nav.appendChild(makeLink('/pages/1/privacy-policy', 'Privacy Policy')); 103 104 var layout = document.createElement('div'); 105 layout.className = 'ws791-layout'; 106 107 var info = document.createElement('section'); 108 info.className = 'ws791-business'; 109 info.innerHTML = '' + 110 '<p class="ws791-eyebrow">Business information</p>' + 111 '<h1>Wavswap</h1>' + 112 '<p>Contact us about your account, subscription, credits, WavCash balance, privacy request or a technical issue.</p>' + 113 '<dl class="ws791-details">' + 114 '<div><dt>Chamber of Commerce (KVK)</dt><dd>88550796</dd></div>' + 115 '<div><dt>VAT identification number</dt><dd>NL004621983B94</dd></div>' + 116 '<div><dt>Correspondence address</dt><dd>Meeuwenplein 5, 1 hoog<br>1022 BK Amsterdam<br>Netherlands</dd></div>' + 117 '<div><dt>Email</dt><dd><a href="mailto:[email protected]">[email protected]</a></dd></div>' + 118 '<div><dt>Website</dt><dd><a href="https://wavswap.com">wavswap.com</a></dd></div>' + 119 '</dl>' + 120 '<div class="ws791-notice">' + 121 '<h2>WavCash and payout questions</h2>' + 122 '<p>WavCash withdrawals are not publicly available while regulatory and operational checks are being completed. You may still contact us about a balance or payment dispute.</p>' + 123 '<p class="ws791-safety"><strong>Security:</strong> Never send passwords, complete card details, identity documents, bank login details or recovery codes through this form.</p>' + 124 '</div>' + 125 '<div class="ws791-community" aria-labelledby="ws791-community-title">' + 126 '<p class="ws791-eyebrow">Wavswap community</p>' + 127 '<h2 id="ws791-community-title">Join our community</h2>' + 128 '<p>
128Meet other producers, share feedback and keep up with new sounds and tools.</p>' + 129 '<div class="ws791-community-links">' + 130 '<a class="ws791-community-link ws791-community-discord" href="https://discord.gg/Bz3nq3GJv" target="_blank" rel="noopener noreferrer">Join Discord</a>' + 131 '<a class="ws791-community-link ws791-community-reddit" href="https://www.reddit.com/r/Wavswap/" target="_blank" rel="noopener noreferrer">Visit Reddit</a>' + 132 '</div>' + 133 '</div>'; 134 135 var heading = form.querySelector('h1, h2'); 136 if (heading) heading.textContent = 'Contact Us'; 137 138 var intro = heading ? heading.nextElementSibling : null; 139 if (intro && intro.tagName === 'P') { 140 intro.textContent = 'Please use the form below to send us a message. We normally respond within 1â3 business days.'; 141 } 142 143 addCategoryField(form); 144 145 var submitButton = form.querySelector('button[type="submit"]'); 146 if (submitButton) submitButton.textContent = 'Send message'; 147 148 if (!form.querySelector('.ws791-privacy')) { 149 var privacy = document.createElement('p'); 150 privacy.className = 'ws791-privacy'; 151 privacy.innerHTML = 'We use the information you submit only to respond to your request and protect our services. <a href="/pages/1/privacy-policy">Read the Privacy Policy</a>.'; 152 if (submitButton && submitButton.parentNode) { 153 submitButton.parentNode.insertBefore(privacy, submitButton); 154 } else { 155 form.appendChild(privacy); 156 } 157 } 158 159 parent.insertBefore(nav, form); 160 parent.insertBefore(layout, form); 161 layout.appendChild(info); 162 layout.appendChild(form); 163 164 initialized = true; 165 return true; 166 } 167 168 function isAccountSettingsPage() { 169 return window.location.pathname.replace(/\/+$/, '') === '/account/settings'; 170 } 171 172 function addAccountSettingsSupportPanel() { 173 if (!isAccountSettingsPage()) return false; 174 if (document.querySelector('[data-ws791-support-panel="1"]')) return true; 175 176 var panels = document.querySelector('account-settings .panels') || 177 document.querySelector('.content.container .panels') || 178 document.querySelector('.panels'); 179 if (!panels) return false; 180 181 var panel = document.createElement('section'); 182 panel.className = 'panel account-settings-panel ws791-support-panel'; 183 panel.setAttribute('data-ws791-support-panel', '1'); 184 panel.setAttribute('aria-labelledby', 'ws791-support-title'); 185 panel.innerHTML = '' + 186 '<div class="panel-header">' + 187 '<div class="ws791-support-heading">' + 188 '<span class="ws791-support-icon" aria-hidden="true">?</span>' + 189 '<div>' + 190 '<span id="ws791-support-title" class="panel-header-title">Support centre</span>' + 191 '<span class="ws791-support-kicker">Account, artist and payment help</span>' + 192 '</div>' + 193 '</div>' + 194 '</div>' + 195 '<div class="panel-body">' + 196 '<p>Talk directly to Wavswap about account access, subscriptions, Artist Earnings, payout requests, WavCash, privacy or technical problems.</p>' + 197 '<div class="ws791-support-actions">' + 198 '<a class="ws791-support-button" href="/contact">Open support form</a>' + 199 '<span class="ws791-support-response">We normally reply within 1â3 business days.</span>' + 200 '</div>' + 201 '</div>'; 202 203 if (panels.firstChild) { 204 panels.insertBefore(panel, panels.firstChild); 205 } else { 206 panels.appendChild(panel); 207 } 208 return true; 209 } 210 211 function enhanceCurrentPage() { 212 var changed = false; 213 if (isContactPage()) changed = enhance() || changed; 214 if (isAccountSettingsPage()) changed = addAccountSettingsSupportPanel() || changed; 215 return changed; 216 } 217 218 function retry() { 219 initialized = false;
220 var attempts = 0; 221 var timer = window.setInterval(function () { 222 attempts++; 223 enhanceCurrentPage(); 224 if (attempts >= 120 || (!isContactPage() && !isAccountSettingsPage())) { 225 window.clearInterval(timer); 226 } 227 if (isContactPage() && document.querySelector('form[data-ws791="1"]')) { 228 window.clearInterval(timer); 229 } 230 if (isAccountSettingsPage() && document.querySelector('[data-ws791-support-panel="1"]')) { 231 window.clearInterval(timer); 232 } 233 }, 100); 234 } 235 236 function start() { 237 new MutationObserver(function () { 238 enhanceCurrentPage(); 239 }).observe(document.documentElement, {childList: true, subtree: true}); 240 retry(); 241 } 242 243 if (document.readyState === 'loading') { 244 document.addEventListener('DOMContentLoaded', start); 245 } else { 246 start(); 247 } 248 249 window.addEventListener('popstate', retry); 250})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.