PageSourceSearch

https://raptorscleaning.com/

html raptorscleaning.com collected 2026-10-10 00:05:22 UTC 14,467 bytes, 418 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5  <meta charset="UTF-8" />
6  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
7  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8  <meta name="theme-color" content="#000000" />
9  <meta name="robots" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" />
10  <link rel="apple-touch-icon" href="/vite.svg" />
11
12  <!-- Primary Meta Tags -->
13  <title>Raptor The Luxury Brand | Premium Eaves, Window & Gutter Cleaning in the GTA</title>
14  <meta name="title" content="Raptor The Luxury Brand | Premium Eaves, Window & Gutter Cleaning in the GTA" />
15  <meta name="description" content="Raptor The Luxury Brand — the No.1 luxury home service brand in North America. Professional eaves cleaning, window cleaning, eavestrough cleaning, power washing & premium gutter protection across Hamilton, Ancaster, Burlington, Oakville, Milton, Mississauga & the GTA." />
16  <meta name="keywords" content="eaves cleaning, window cleaning, eavestrough cleaning, gutter cleaning, power washing, gutter protection, eaves guards, Alu-Rex, Hamilton, Ancaster, Burlington, Oakville, Milton, Mississauga, Toronto, GTA, Raptor The Luxury Brand" />
17  <meta name="author" content="Raptor The Luxury Brand" />
18  <meta name="rating" content="general" />
19  <meta name="distribution" content="global" />
20  <meta name="revisit-after" content="7 days" />
21
22  <!-- Geo Tags -->
23  <meta name="geo.region" content="CA-ON" />
24  <meta name="geo.placename" content="Hamilton, Ontario" />
25  <meta name="geo.position" content="43.2557;-79.8711" />
26  <meta name="ICBM" content="43.2557, -79.8711" />
27
28  <!-- Open Graph / Facebook -->
29  <meta property="og:type" content="website" />
30  <meta property="og:url" content="https://raptorscleaning.com/" />
31  <meta property="og:title" content="Raptor The Luxury Brand | Premium Eaves, Window & Gutter Cleaning" />
32  <meta property="og:description" content="The No.1 Luxury Service Brand in North America. Professional eaves cleaning, window cleaning, eavestrough cleaning, power washing & premium gutter protection across Hamilton, Ancaster & the GTA." />
33  <meta property="og:image" content="https://horizons-cdn.hostinger.com/fb7f01d3-cba8-4a66-a6db-4f79ac30e95a/5efa23145623c56aa0f185e3c1777171.png" />
34  <meta property="og:site_name" content="Raptor The Luxury Brand" />
35  <meta property="og:locale" content="en_CA" />
36
37  <!-- Twitter -->
38  <meta name="twitter:card" content="summary_large_image" />
39  <meta name="twitter:url" content="https://raptorscleaning.com/" />
40  <meta name="twitter:title" content="Raptor The Luxury Brand | Premium Eaves, Window & Gutter Cleaning" />
41  <meta name="twitter:description" content="The No.1 Luxury Service Brand in North America. Professional cleaning & gutter protection across Hamilton, Ancaster & the GTA." />
42  <meta name="twitter:image" content="https://horizons-cdn.hostinger.com/fb7f01d3-cba8-4a66-a6db-4f79ac30e95a/5efa23145623c56aa0f185e3c1777171.png" />
43
44  <!-- Canonical -->
45  <link rel="canonical" href="https://raptorscleaning.com/" />
46
47  <!-- Google Fonts Preconnect -->
48  <link rel="preconnect" href="https://fonts.googleapis.com">
49  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
50
51  <!-- Bebas Neue (Headings) & DM Sans (Body) -->
52  <link href="https://fonts.googleapis.com/css2?family=Bebas+Neue&family=DM+Sans:opsz,[email protected],400;500;700&display=swap" rel="stylesheet">
53
54  <!-- Organization + WebSite Structured Data -->
55  
55<script type="application/ld+json">
56  {
57    "@context": "https://schema.org",
58    "@graph": [
59      {
60        "@type": "Organization",
61        "@id": "https://raptorscleaning.com/#organization",
62        "name": "Raptor The Luxury Brand",
63        "alternateName": "Raptors Cleaning",
64        "url": "https://raptorscleaning.com/",
65        "logo": "https://horizons-cdn.hostinger.com/fb7f01d3-cba8-4a66-a6db-4f79ac30e95a/5efa23145623c56aa0f185e3c1777171.png",
66        "image": "https://horizons-cdn.hostinger.com/fb7f01d3-cba8-4a66-a6db-4f79ac30e95a/5efa23145623c56aa0f185e3c1777171.png",
67        "telephone": "+1-437-335-5568",
68        "email": "[email protected]",
69        "address": {
70          "@type": "PostalAddress",
71          "streetAddress": "542 Appleby Line",
72          "addressLocality": "Burlington",
73          "addressRegion": "ON",
74          "postalCode": "L7L 2Y3",
75          "addressCountry": "CA"
76        },
77        "geo": {
78          "@type": "GeoCoordinates",
79          "latitude": 43.3856,
80          "longitude": -79.7586
81        },
82        "areaServed": [
83          { "@type": "City", "name": "Burlington" },
84          { "@type": "City", "name": "Oakville" },
85          { "@type": "City", "name": "Milton" },
86          { "@type": "City", "name": "Mississauga" },
87          { "@type": "City", "name": "Hamilton" },
88          { "@type": "City", "name": "Ancaster" },
89          { "@type": "City", "name": "Brampton" },
90          { "@type": "City", "name": "Toronto" },
91          { "@type": "City", "name": "Markham" },
92          { "@type": "City", "name": "Richmond Hill" },
93          { "@type": "City", "name": "Vaughan" },
94          { "@type": "City", "name": "Newmarket" },
95          { "@type": "City", "name": "Aurora" },
96          { "@type": "City", "name": "Whitby" },
97          { "@type": "City", "name": "Oshawa" },
98          { "@type": "City", "name": "Ajax" },
99          { "@type": "City", "name": "Pickering" },
100          { "@type": "City", "name": "Scarborough" }
101        ],
102        "contactPoint": {
103          "@type": "ContactPoint",
104          "telephone": "+1-437-335-5568",
105          "contactType": "customer service",
106          "areaServed": "CA",
107          "availableLanguage": ["en"]
108        },
109        "sameAs": [
110          "https://www.facebook.com/raptorscleaning",
111          "https://www.instagram.com/raptorscleaning"
112        ]
113      },
114      {
115        "@type": "WebSite",
116        "@id": "https://raptorscleaning.com/#website",
117        "url": "https://raptorscleaning.com/",
118        "name": "Raptor The Luxury Brand",
119        "publisher": { "@id": "https://raptorscleaning.com/#organization" },
120        "inLanguage": "en-CA"
121      }
122    ]
123  }
124  </script>
124
125
126  <style>
127    /* Critical CSS for immediate font loading */
128    body {
129      /* Fallback stack ensures content is visible immediately */
130      font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
131      -webkit-font-smoothing: antialiased;
132      -moz-osx-font-smoothing: grayscale;
133    }
134
135    h1, h2, h3, h4, h5, h6 {
136      font-family: "Bebas Neue", sans-serif;
137    }
138  </style>
139  
139<script type="module" crossorigin src="/assets/index-Ow5fMCIk.js"></script>
139
140  <link rel="stylesheet" crossorigin href="/assets/index-p12-Pzhq.css">
141  
141<script type="module">
142window.onerror = (message, source, lineno, colno, errorObj) => {
143	const errorDetails = errorObj ? JSON.stringify({
144		name: errorObj.name,
145		message: errorObj.message,
146		stack: errorObj.stack,
147		source,
148		lineno,
149		colno,
150	}) : null;
151
152	window.parent.postMessage({
153		type: 'horizons-runtime-error',
154		message,
155		error: errorDetails
156	}, '*');
157};
158</script>
158
159  
159<script type="module">
160const observer = new MutationObserver((mutations) => {
161	for (const mutation of mutations) {
162		for (const addedNode of mutation.addedNodes) {
163			if (
164				addedNode.nodeType === Node.ELEMENT_NODE &&
165				(
166					addedNode.tagName?.toLowerCase() === 'vite-error-overlay' ||
167					addedNode.classList?.contains('backdrop')
168				)
169			) {
170				handleViteOverlay(addedNode);
171			}
172		}
173	}
174});
175
176observer.observe(document.documentElement, {
177	childList: true,
178	subtree: true
179});
180
181function handleViteOverlay(node) {
182	if (!node.shadowRoot) {
183		return;
184	}
185
186	const backdrop = node.shadowRoot.querySelector('.backdrop');
187
188	if (backdrop) {
189		const overlayHtml = backdrop.outerHTML;
190		const parser = new DOMParser();
191		const doc = parser.parseFromString(overlayHtml, 'text/html');
192		const messageBodyElement = doc.querySelector('.message-body');
193		const fileElement = doc.querySelector('.file');
194		const messageText = messageBodyElement ? messageBodyElement.textContent.trim() : '';
195		const fileText = fileElement ? fileElement.textContent.trim() : '';
196		const error = messageText + (fileText ? ' File:' + fileText : '');
197
198		window.parent.postMessage({
199			type: 'horizons-vite-error',
200			error,
201		}, '*');
202	}
203}
204</script>
204
205  
205<script type="module">
206const originalConsoleError = console.error;
207const MATCH_LINE_COL_REGEX = /:(\d+):(\d+)\)?\s*$/; // regex to match the :lineNum:colNum
208const MATCH_AT_REGEX = /^\s*at\s+(?:async\s+)?(?:.*?\s+)?\(?/; // regex to remove the 'at' keyword and any 'async' or function name
209const MATCH_PATH_REGEX = /^\//; // regex to remove the leading slash
210
211function parseStackFrameLine(line) {
212	const lineColMatch = line.match(MATCH_LINE_COL_REGEX);
213	if (!lineColMatch) return null;
214	const [, lineNum, colNum] = lineColMatch;
215	const suffix = `:${lineNum}:${colNum}`;
216	const idx = line.lastIndexOf(suffix);
217	if (idx === -1) return null;
218	const before = line.substring(0, idx);
219	const path = before.replace(MATCH_AT_REGEX, '').trim();
220	
221	if (!path) return null;
222
223	try {
224		const pathname = new URL(path).pathname;
225		const filePath = pathname.replace(MATCH_PATH_REGEX, '') || pathname;
226		return `${filePath}:${lineNum}:${colNum}`;
227	} catch (e) {
228		const filePath = path.replace(MATCH_PATH_REGEX, '') || path;
229		return `${filePath}:${lineNum}:${colNum}`;
230	}
231}
232
233function getFilePathFromStack(stack, skipFrames = 0) {
234	if (!stack || typeof stack !== 'string') return null;
235	const lines = stack.split('\n').slice(1);
236
237	const frames = lines.map(line => parseStackFrameLine(line.replace(/\r$/, ''))).filter(Boolean);
238
239	return frames[skipFrames] ?? null;
240}
241
242function formatConsoleMessage(args, skipStackFrames = 1) {
243	let messageString = '';
244	let filePath = null;
245
246	for (let i = 0; i < args.length; i++) {
247		const arg = args[i];
248		if (arg instanceof Error) {
249			filePath = getFilePathFromStack(arg.stack, 0);
250			messageString = `${arg.name}: ${arg.message}`;
251			if (filePath) {
252				messageString = `${messageString} at ${filePath}`;
253			}
254			break;
255		}
256	}
257
258	if (!messageString) {
259		messageString = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
260		const stack = new Error().stack;
261		filePath = getFilePathFromStack(stack, skipStackFrames);
262		if (filePath) {
263			messageString = `${messageString} at ${filePath}`;
264		}
265	}
266
267	return messageString;
268}
269
270console.error = function(...args) {
271	originalConsoleError.apply(console, args);
272
273	window.parent.postMessage({
274		type: 'horizons-console-error',
275		error: formatConsoleMessage(args, 1)
276	}, '*');
277};
278
279const originalConsoleWarn = console.warn;
280
281console.warn = function(...args) {
282	originalConsoleWarn.apply(console, args);
283
284	window.parent.postMessage({
285		type: 'horizons-console-warn',
286		warning: formatConsoleMessage(args, 1)
287	}, '*');
288};
289</script>
289
290  
290<script type="module">
291// Prevents authentication failures (PB returns 400) from crashing the app — use console.info, not console.error/PM2.
292// [urlPattern, bodyPattern] tuples; align with sandboxErrorUtils ERROR_BLACKLIST.
293const BENIGN_FETCH_ERRORS = [
294	[/hcgi\/platform\/api\/collections\/.*auth-with-password.*/i, /Failed to authenticate/i],
295	[/hcgi\/api\//i, /Insufficient credits/i],
296	// A user-supplied integration secret (Stripe/PayPal/Twilio/...) is not set yet — an expected setup state, not a bug to fix.
297	[/hcgi\/api\//i, /INTEGRATION_NOT_CONFIGURED/i],
298];
299
300function isBenignFetchError(url, body) {
301	return BENIGN_FETCH_ERRORS.some(([urlPattern, bodyPattern]) =>
302		urlPattern.test(url) && (!bodyPattern || bodyPattern.test(body)));
303}
304
305const PLATFORM_URL_PATTERN = /hcgi\/platform\//i;
306const VALIDATION_CODE_TEXT_PATTERN = /validation_/;
307
308function hasValidationCode(value) {
309	if (value == null) {
310		return false;
311	}
312	if (typeof value === 'string') {
313		return value.startsWith('validation_');
314	}
315	if (Array.isArray(value)) {
316		return value.some(hasValidationCode);
317	}
318	if (typeof value === 'object') {
319		return Object.values(value).some(hasValidationCode);
320	}
321	return false;
322}
323
324function isValidationFetchWarning(url, body) {
325	if (!PLATFORM_URL_PATTERN.test(url)) {
326		return false;
327	}
328	try {
329		return hasValidationCode(JSON.parse(body));
330	} catch {
331		return VALIDATION_CODE_TEXT_PATTERN.test(body);
332	}
333}
334
335const originalFetch = window.fetch;
336
337window.fetch = function(...args) {
338	const url = args[0] instanceof Request ? args[0].url : args[0];
339
340	// Skip WebSocket URLs
341	if (url.startsWith('ws:') || url.startsWith('wss:')) {
342		return originalFetch.apply(this, args);
343	}
344
345	return originalFetch.apply(this, args)
346		.then(async response => {
347			const contentType = response.headers.get('Content-Type') || '';
348
349			// Exclude HTML document responses
350			const isDocumentResponse =
351				contentType.includes('text/html') ||
352				contentType.includes('application/xhtml+xml');
353
354			// no-cors requests (e.g. Google Analytics/Ads beacons) always return an opaque
355			const isOpaqueResponse = response.type === 'opaque';
356
357			if (!response.ok && !isDocumentResponse && !isOpaqueResponse) {
358					const responseClone = response.clone();
359					const errorFromRes = await responseClone.text();
360					const requestUrl = response.url;
361					const errorMessage = `Fetch error from ${requestUrl}: ${errorFromRes}`;
362
363					if (isBenignFetchError(requestUrl, errorFromRes)) {
364						console.info(errorMessage);
365					} else if (isValidationFetchWarning(requestUrl, errorFromRes)) {
366						console.warn(errorMessage);
367					} else {
368						console.error(errorMessage);
369					}
370			}
371
372			return response;
373		})
374		.catch(error => {
375			if (!url.match(/.html?$/i)) {
376				// Cancelled in-flight fetch (e.g. preview reload) — not a server failure.
377				if (error?.name === 'AbortError') {
378					console.info(error);
379				} else {
380					console.error(error);
381				}
382			}
383
384			throw error;
385		});
386};
387</script>
387
388  
388<script type="module">
389if (window.navigation && window.self !== window.top) {
390	window.navigation.addEventListener('navigate', (event) => {
391		const url = event.destination.url;
392
393		try {
394			const destinationUrl = new URL(url);
395			const destinationOrigin = destinationUrl.origin;
396			const currentOrigin = window.location.origin;
397
398			if (destinationOrigin === currentOrigin) {
399				return;
400			}
401		} catch (error) {
402			return;
403		}
404
405		window.parent.postMessage({
406			type: 'horizons-navigation-error',
407			url,
408		}, '*');
409	});
410}
411</script>
411
412</head>
413
414<body>
415  <div id="root"></div>
416</body>
417
418</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.