PageSourceSearch

https://elfitnessflow.com/

html elfitnessflow.com collected 2026-10-02 16:09:56 UTC 9,161 bytes, 293 lines download raw bytes

1<!doctype html>
2<html lang="es">
3  <head>
4    <meta charset="UTF-8" />
5    <link rel="icon" type="image/png" href="https://horizons-cdn.hostinger.com/7cea2d54-5692-4a63-a8fe-21948c114e0c/9b8857fe878fbe4946ed2526c8dfd441.jpg" />
6    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7    <meta name="description" content="Fitness Flow con Laurenis Martínez: el podcast #1 de salud y fitness en Panamá. Movimiento, salud mental y bienestar con tecnología y ciencia — de Panamá para el mundo. Nuevos episodios cada miércoles." />
8    <meta name="keywords" content="podcast fitness, salud, fitness Panamá, bienestar, salud mental, movimiento, Laurenis Martínez, Fitness Flow, podcast en español, wellness" />
9    <meta name="author" content="Fitness Flow" />
10    <meta name="robots" content="index, follow" />
11    <meta property="og:type" content="website" />
12    <meta property="og:title" content="Fitness Flow — El Podcast #1 de Salud y Fitness en Panamá" />
13    <meta property="og:description" content="El podcast #1 de salud y fitness en Panamá. Movimiento, salud mental y bienestar con tecnología y ciencia — de Panamá para el mundo." />
14    <meta property="og:locale" content="es_PA" />
15    <title>Fitness Flow — El Podcast #1 de Salud y Fitness en Panamá</title>
16    
16<script type="module" crossorigin src="/assets/index-tDN17qvI.js"></script>
16
17    <link rel="stylesheet" crossorigin href="/assets/index-Bb60va6N.css">
18    
18<script type="module">
19window.onerror = (message, source, lineno, colno, errorObj) => {
20	const errorDetails = errorObj ? JSON.stringify({
21		name: errorObj.name,
22		message: errorObj.message,
23		stack: errorObj.stack,
24		source,
25		lineno,
26		colno,
27	}) : null;
28
29	window.parent.postMessage({
30		type: 'horizons-runtime-error',
31		message,
32		error: errorDetails
33	}, '*');
34};
35</script>
35
36    
36<script type="module">
37const observer = new MutationObserver((mutations) => {
38	for (const mutation of mutations) {
39		for (const addedNode of mutation.addedNodes) {
40			if (
41				addedNode.nodeType === Node.ELEMENT_NODE &&
42				(
43					addedNode.tagName?.toLowerCase() === 'vite-error-overlay' ||
44					addedNode.classList?.contains('backdrop')
45				)
46			) {
47				handleViteOverlay(addedNode);
48			}
49		}
50	}
51});
52
53observer.observe(document.documentElement, {
54	childList: true,
55	subtree: true
56});
57
58function handleViteOverlay(node) {
59	if (!node.shadowRoot) {
60		return;
61	}
62
63	const backdrop = node.shadowRoot.querySelector('.backdrop');
64
65	if (backdrop) {
66		const overlayHtml = backdrop.outerHTML;
67		const parser = new DOMParser();
68		const doc = parser.parseFromString(overlayHtml, 'text/html');
69		const messageBodyElement = doc.querySelector('.message-body');
70		const fileElement = doc.querySelector('.file');
71		const messageText = messageBodyElement ? messageBodyElement.textContent.trim() : '';
72		const fileText = fileElement ? fileElement.textContent.trim() : '';
73		const error = messageText + (fileText ? ' File:' + fileText : '');
74
75		window.parent.postMessage({
76			type: 'horizons-vite-error',
77			error,
78		}, '*');
79	}
80}
81</script>
81
82    
82<script type="module">
83const originalConsoleError = console.error;
84const MATCH_LINE_COL_REGEX = /:(\d+):(\d+)\)?\s*$/; // regex to match the :lineNum:colNum
85const MATCH_AT_REGEX = /^\s*at\s+(?:async\s+)?(?:.*?\s+)?\(?/; // regex to remove the 'at' keyword and any 'async' or function name
86const MATCH_PATH_REGEX = /^\//; // regex to remove the leading slash
87
88function parseStackFrameLine(line) {
89	const lineColMatch = line.match(MATCH_LINE_COL_REGEX);
90	if (!lineColMatch) return null;
91	const [, lineNum, colNum] = lineColMatch;
92	const suffix = `:${lineNum}:${colNum}`;
93	const idx = line.lastIndexOf(suffix);
94	if (idx === -1) return null;
95	const before = line.substring(0, idx);
96	const path = before.replace(MATCH_AT_REGEX, '').trim();
97	
98	if (!path) return null;
99
100	try {
101		const pathname = new URL(path).pathname;
102		const filePath = pathname.replace(MATCH_PATH_REGEX, '') || pathname;
103		return `${filePath}:${lineNum}:${colNum}`;
104	} catch (e) {
105		const filePath = path.replace(MATCH_PATH_REGEX, '') || path;
106		return `${filePath}:${lineNum}:${colNum}`;
107	}
108}
109
110function getFilePathFromStack(stack, skipFrames = 0) {
111	if (!stack || typeof stack !== 'string') return null;
112	const lines = stack.split('\n').slice(1);
113
114	const frames = lines.map(line => parseStackFrameLine(line.replace(/\r$/, ''))).filter(Boolean);
115
116	return frames[skipFrames] ?? null;
117}
118
119function formatConsoleMessage(args, skipStackFrames = 1) {
120	let messageString = '';
121	let filePath = null;
122
123	for (let i = 0; i < args.length; i++) {
124		const arg = args[i];
125		if (arg instanceof Error) {
126			filePath = getFilePathFromStack(arg.stack, 0);
127			messageString = `${arg.name}: ${arg.message}`;
128			if (filePath) {
129				messageString = `${messageString} at ${filePath}`;
130			}
131			break;
132		}
133	}
134
135	if (!messageString) {
136		messageString = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
137		const stack = new Error().stack;
138		filePath = getFilePathFromStack(stack, skipStackFrames);
139		if (filePath) {
140			messageString = `${messageString} at ${filePath}`;
141		}
142	}
143
144	return messageString;
145}
146
147console.error = function(...args) {
148	originalConsoleError.apply(console, args);
149
150	window.parent.postMessage({
151		type: 'horizons-console-error',
152		error: formatConsoleMessage(args, 1)
153	}, '*');
154};
155
156const originalConsoleWarn = console.warn;
157
158console.warn = function(...args) {
159	originalConsoleWarn.apply(console, args);
160
161	window.parent.postMessage({
162		type: 'horizons-console-warn',
163		warning: formatConsoleMessage(args, 1)
164	}, '*');
165};
166</script>
166
167    
167<script type="module">
168// Prevents authentication failures (PB returns 400) from crashing the app — use console.info, not console.error/PM2.
169// [urlPattern, bodyPattern] tuples; align with sandboxErrorUtils ERROR_BLACKLIST.
170const BENIGN_FETCH_ERRORS = [
171	[/hcgi\/platform\/api\/collections\/.*auth-with-password.*/i, /Failed to authenticate/i],
172	[/hcgi\/api\//i, /Insufficient credits/i],
173	// A user-supplied integration secret (Stripe/PayPal/Twilio/...) is not set yet — an expected setup state, not a bug to fix.
174	[/hcgi\/api\//i, /INTEGRATION_NOT_CONFIGURED/i],
175];
176
177function isBenignFetchError(url, body) {
178	return BENIGN_FETCH_ERRORS.some(([urlPattern, bodyPattern]) =>
179		urlPattern.test(url) && (!bodyPattern || bodyPattern.test(body)));
180}
181
182const PLATFORM_URL_PATTERN = /hcgi\/platform\//i;
183const VALIDATION_CODE_TEXT_PATTERN = /validation_/;
184
185function hasValidationCode(value) {
186	if (value == null) {
187		return false;
188	}
189	if (typeof value === 'string') {
190		return value.startsWith('validation_');
191	}
192	if (Array.isArray(value)) {
193		return value.some(hasValidationCode);
194	}
195	if (typeof value === 'object') {
196		return Object.values(value).some(hasValidationCode);
197	}
198	return false;
199}
200
201function isValidationFetchWarning(url, body) {
202	if (!PLATFORM_URL_PATTERN.test(url)) {
203		return false;
204	}
205	try {
206		return hasValidationCode(JSON.parse(body));
207	} catch {
208		return VALIDATION_CODE_TEXT_PATTERN.test(body);
209	}
210}
211
212const originalFetch = window.fetch;
213
214window.fetch = function(...args) {
215	const url = args[0] instanceof Request ? args[0].url : args[0];
216
217	// Skip WebSocket URLs
218	if (url.startsWith('ws:') || url.startsWith('wss:')) {
219		return originalFetch.apply(this, args);
220	}
221
222	return originalFetch.apply(this, args)
223		.then(async response => {
224			const contentType = response.headers.get('Content-Type') || '';
225
226			// Exclude HTML document responses
227			const isDocumentResponse =
228				contentType.includes('text/html') ||
229				contentType.includes('application/xhtml+xml');
230
231			// no-cors requests (e.g. Google Analytics/Ads beacons) always return an opaque
232			const isOpaqueResponse = response.type === 'opaque';
233
234			if (!response.ok && !isDocumentResponse && !isOpaqueResponse) {
235					const responseClone = response.clone();
236					const errorFromRes = await responseClone.text();
237					const requestUrl = response.url;
238					const errorMessage = `Fetch error from ${requestUrl}: ${errorFromRes}`;
239
240					if (isBenignFetchError(requestUrl, errorFromRes)) {
241						console.info(errorMessage);
242					} else if (isValidationFetchWarning(requestUrl, errorFromRes)) {
243						console.warn(errorMessage);
244					} else {
245						console.error(errorMessage);
246					}
247			}
248
249			return response;
250		})
251		.catch(error => {
252			if (!url.match(/.html?$/i)) {
253				// Cancelled in-flight fetch (e.g. preview reload) — not a server failure.
254				if (error?.name === 'AbortError') {
255					console.info(error);
256				} else {
257					console.error(error);
258				}
259			}
260
261			throw error;
262		});
263};
264</script>
264
265    
265<script type="module">
266if (window.navigation && window.self !== window.top) {
267	window.navigation.addEventListener('navigate', (event) => {
268		const url = event.destination.url;
269
270		try {
271			const destinationUrl = new URL(url);
272			const destinationOrigin = destinationUrl.origin;
273			const currentOrigin = window.location.origin;
274
275			if (destinationOrigin === currentOrigin) {
276				return;
277			}
278		} catch (error) {
279			return;
280		}
281
282		window.parent.postMessage({
283			type: 'horizons-navigation-error',
284			url,
285		}, '*');
286	});
287}
288</script>
288
289  </head>
290  <body>
291    <div id="root"></div>
292  </body>
293</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.