1<!doctype html> 2<html lang="de"> 3 <head> 4 <meta charset="UTF-8" /> 5 <link rel="icon" type="image/png" href="/favicon.png" /> 6 <meta name="generator" content="Hostinger Horizons" /> 7 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 8
8<script type="application/ld+json"> 9{ 10 "@context": "https://schema.org", 11 "@type": "Organization", 12 "name": "e-raumwerk GmbH", 13 "url": "https://www.e-raumwerk.de", 14 "logo": "https://www.e-raumwerk.de/e7b07194-5662-4d8b-87af-061d3b6fa34c/b3d34833304ce2064e9f671f617e7604.png", 15 "description": "e-raumwerk ist Ihre spezialisierte Agentur für MSAaaS â Marketing & Sales Automation as a Service mit Evalanche. Wir helfen B2B-Unternehmen, Leads, MQLs und SQLs systematisch zu steigern.", 16 "address": { 17 "@type": "PostalAddress", 18 "addressCountry": "DE", 19 "addressRegion": "Nordrhein-Westfalen" 20 }, 21 "sameAs": [ 22 "https://www.linkedin.com/company/e-raumwerk", 23 "https://www.evalanche.com/de/partner/" 24 ] 25} 26</script>
26 27 28 <title>e-raumwerk GmbH | MSAaaS â Marketing & Sales Automation as a Service</title> 29 <meta name="description" content="MSAaaS â Marketing & Sales Automation as a Service"> 30 31 <meta property="og:type" content="website"> 32 <meta property="og:url" content="https://e-raumwerk.de/" /> 33 <meta property="og:description" content="MSAaaS â Marketing & Sales Automation as a Service" /> 34<meta name="robots" content="index,follow">
35<script id="Cookiebot" src="https://consent.cookiebot.com/uc.js" data-cbid="d3f49610-dcb8-410c-a045-c92f8d60ea0d" 36 data-blockingmode="auto" type="text/javascript"></script>
36 37
37<script type="module" crossorigin src="/assets/index-D_KqB5jY.js"></script>
37 38 <link rel="stylesheet" crossorigin href="/assets/index-BV-5UFlP.css"> 39
39<script type="module"> 40window.onerror = (message, source, lineno, colno, errorObj) => { 41 const errorDetails = errorObj ? JSON.stringify({ 42 name: errorObj.name, 43 message: errorObj.message, 44 stack: errorObj.stack, 45 source, 46 lineno, 47 colno, 48 }) : null; 49 50 window.parent.postMessage({ 51 type: 'horizons-runtime-error', 52 message, 53 error: errorDetails 54 }, '*'); 55}; 56</script>
56 57
57<script type="module"> 58const observer = new MutationObserver((mutations) => { 59 for (const mutation of mutations) { 60 for (const addedNode of mutation.addedNodes) { 61 if ( 62 addedNode.nodeType === Node.ELEMENT_NODE && 63 ( 64 addedNode.tagName?.toLowerCase() === 'vite-error-overlay' || 65 addedNode.classList?.contains('backdrop') 66 ) 67 ) { 68 handleViteOverlay(addedNode); 69 } 70 } 71 } 72}); 73 74observer.observe(document.documentElement, { 75 childList: true, 76 subtree: true 77}); 78 79function handleViteOverlay(node) { 80 if (!node.shadowRoot) { 81 return; 82 } 83 84 const backdrop = node.shadowRoot.querySelector('.backdrop'); 85 86 if (backdrop) { 87 const overlayHtml = backdrop.outerHTML; 88 const parser = new DOMParser(); 89 const doc = parser.parseFromString(overlayHtml, 'text/html'); 90 const messageBodyElement = doc.querySelector('.message-body'); 91 const fileElement = doc.querySelector('.file'); 92 const messageText = messageBodyElement ? messageBodyElement.textContent.trim() : ''; 93 const fileText = fileElement ? fileElement.textContent.trim() : ''; 94 const error = messageText + (fileText ? ' File:' + fileText : ''); 95 96 window.parent.postMessage({ 97 type: 'horizons-vite-error', 98 error, 99 }, '*'); 100 } 101} 102</script>
102 103
103<script type="module"> 104const originalConsoleError = console.error; 105const MATCH_LINE_COL_REGEX = /:(\d+):(\d+)\)?\s*$/; // regex to match the :lineNum:colNum 106const MATCH_AT_REGEX = /^\s*at\s+(?:async\s+)?(?:.*?\s+)?\(?/; // regex to remove the 'at' keyword and any 'async' or function name 107const MATCH_PATH_REGEX = /^\//; // regex to remove the leading slash 108 109function parseStackFrameLine(line) { 110 const lineColMatch = line.match(MATCH_LINE_COL_REGEX); 111 if (!lineColMatch) return null; 112 const [, lineNum, colNum] = lineColMatch; 113 const suffix = `:${lineNum}:${colNum}`; 114 const idx = line.lastIndexOf(suffix); 115 if (idx === -1) return null; 116 const before = line.substring(0, idx); 117 const path = before.replace(MATCH_AT_REGEX, '').trim(); 118 if (!path) return null; 119 120 try { 121 const pathname = new URL(path).pathname; 122 const filePath = pathname.replace(MATCH_PATH_REGEX, '') || pathname; 123 return `${filePath}:${lineNum}:${colNum}`; 124 } catch (e) { 125 const filePath = path.replace(MATCH_PATH_REGEX, '') || path; 126 return `${filePath}:${lineNum}:${colNum}`; 127 } 128} 129 130function getFilePathFromStack(stack, skipFrames = 0) { 131 if (!stack || typeof stack !== 'string') return null; 132 const lines = stack.split('\n').slice(1); 133 134 const frames = lines.map(line => parseStackFrameLine(line.replace(/\r$/, ''))).filter(Boolean); 135 136 return frames[skipFrames] ?? null; 137} 138 139console.error = function(...args) { 140 originalConsoleError.apply(console, args); 141 142 let errorString = ''; 143 let filePath = null; 144 145 for (let i = 0; i < args.length; i++) { 146 const arg = args[i]; 147 if (arg instanceof Error) { 148 filePath = getFilePathFromStack(arg.stack, 0); 149 errorString = `${arg.name}: ${arg.message}`; 150 if (filePath) { 151 errorString = `${errorString} at ${filePath}`; 152 } 153 break; 154 } 155 } 156 157 if (!errorString) { 158 errorString = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' '); 159 const stack = new Error().stack; 160 filePath = getFilePathFromStack(stack, 1); 161 if (filePath) { 162 errorString = `${errorString} at ${filePath}`; 163 } 164 } 165 166 window.parent.postMessage({ 167 type: 'horizons-console-error', 168 error: errorString 169 }, '*'); 170}; 171</script>
171 172
172<script type="module"> 173const originalFetch = window.fetch; 174 175window.fetch = function(...args) { 176 const url = args[0] instanceof Request ? args[0].url : args[0]; 177 178 // Skip WebSocket URLs 179 if (url.startsWith('ws:') || url.startsWith('wss:')) { 180 return originalFetch.apply(this, args); 181 } 182 183 return originalFetch.apply(this, args) 184 .then(async response => { 185 const contentType = response.headers.get('Content-Type') || ''; 186 187 // Exclude HTML document responses 188 const isDocumentResponse = 189 contentType.includes('text/html') || 190 contentType.includes('application/xhtml+xml'); 191 192 if (!response.ok && !isDocumentResponse) { 193 const responseClone = response.clone(); 194 const errorFromRes = await responseClone.text(); 195 const requestUrl = response.url; 196 console.error(`Fetch error from ${requestUrl}: ${errorFromRes}`); 197 } 198 199 return response; 200 }) 201 .catch(error => { 202 if (!url.match(/.html?$/i)) { 203 console.error(error); 204 } 205 206 throw error; 207 }); 208}; 209</script>
209 210
210<script type="module"> 211if (window.navigation && window.self !== window.top) { 212 window.navigation.addEventListener('navigate', (event) => { 213 const url = event.destination.url; 214 215 try { 216 const destinationUrl = new URL(url); 217 const destinationOrigin = destinationUrl.origin; 218 const currentOrigin = window.location.origin; 219 220 if (destinationOrigin === currentOrigin) { 221 return; 222 } 223 } catch (error) { 224 return; 225 } 226 227 window.parent.postMessage({ 228 type: 'horizons-navigation-error', 229 url, 230 }, '*'); 231 }); 232} 233</script>
233 234 </head> 235 <body> 236 <div id="root"></div> 237 </body> 238</html>
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.