PageSourceSearch

https://farthinghalearms.com/

html farthinghalearms.com collected 2026-10-07 21:29:06 UTC 36,554 bytes, 928 lines download raw bytes

1<!DOCTYPE html >
2<html prefix="og: http://ogp.me/ns#" data-bs-theme="light">
3<head>
4  <title>Farthinghale Arms</title>
5  
5<script>var baseurl="https://hub.farthinghalearms.com";</script>
5
6  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
7<base href="https://hub.farthinghalearms.com/" />
8<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, user-scalable=0" />
9
10<meta name="application-name" content="hubzilla" />
11<meta name="generator" content="hubzilla" />
12<meta name="theme-color" content="rgb(248, 249, 250)" />
13
14<link rel="stylesheet" href="https://hub.farthinghalearms.com/library/jRange/jquery.range.css?v=11.4.1" type="text/css" media="screen">
15<link rel="stylesheet" href="https://hub.farthinghalearms.com/view/css/conversation.css?v=11.4.1" type="text/css" media="screen">
16<link rel="stylesheet" href="https://hub.farthinghalearms.com/view/css/widgets.css?v=11.4.1" type="text/css" media="screen">
17<link rel="stylesheet" href="https://hub.farthinghalearms.com/view/css/colorbox.css?v=11.4.1" type="text/css" media="screen">
18<link rel="stylesheet" href="https://hub.farthinghalearms.com/library/justifiedGallery/justifiedGallery.min.css?v=11.4.1" type="text/css" media="screen">
19<link rel="stylesheet" href="https://hub.farthinghalearms.com/library/datetimepicker/jquery.datetimepicker.css?v=11.4.1" type="text/css" media="screen">
20<link rel="stylesheet" href="https://hub.farthinghalearms.com/vendor/twbs/bootstrap-icons/font/bootstrap-icons.min.css?v=11.4.1" type="text/css" media="screen">
21<link rel="stylesheet" href="https://hub.farthinghalearms.com/library/bootstrap-tagsinput/bootstrap-tagsinput.css?v=11.4.1" type="text/css" media="screen">
22<link rel="stylesheet" href="https://hub.farthinghalearms.com/library/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css?v=11.4.1" type="text/css" media="screen">
23<link rel="stylesheet" href="https://hub.farthinghalearms.com/view/css/default.css?v=11.4.1" type="text/css" media="screen">
24<link rel="stylesheet" href="https://hub.farthinghalearms.com/view/css/mod_home.css?v=11.4.1" type="text/css" media="screen">
25<link rel="stylesheet" href="https://hub.farthinghalearms.com/view/theme/redbasic/php/style.css?v=11.4.1" type="text/css" media="screen">
26
27<script>
28
29	var aStr = {
30
31		'delitem'     : "Delete this item?",
32		'itemdel'     : "Item deleted",
33		'comment'     : "Comment",
34		'divgrowmore' : "expand",
35		'divgrowless' : "collapse",
36		'pwshort'     : "Password too short",
37		'pwnomatch'   : "Passwords do not match",
38		'everybody'   : "everybody",
39		'passphrase'  : "Secret Passphrase",
40		'passhint'    : "Passphrase hint",
41		'permschange' : "Notice: Permissions have changed but have not yet been submitted.",
42		'closeAll'    : "close all",
43		'nothingnew'  : "Nothing new here",
44		'rating_desc' : "Rate This Channel (this is public)",
45		'rating_val'  : "Rating",
46		'rating_text' : "Describe (optional)",
47		'submit'      : "Submit",
48		'linkurl'     : "Please enter a link URL",
49		'leavethispage' : "Unsaved changes. Are you sure you wish to leave this page?",
50		'location'    : "Location",
51		'lovely'      : "lovely",
52		'wonderful'   : "wonderful",
53		'fantastic'   : "fantastic",
54		'great'       : "great",
55		'nick_invld1' : "Your chosen nickname was either already taken or not valid. Please use our suggestion (",
56		'nick_invld2' : ") or enter a new one.",
57		'nick_valid'  : "Thank you, this nickname is valid.",
58		'name_empty'  : "A channel name is required.",
59		'name_ok1'    : "This is a ",
60		'name_ok2'    : " channel name",
61		'to_reply'    : "Back to reply",
62		'pinned'      : "Pinned",
63		'pin_item'    : "Pin to the top",
64		'unpin_item'  : "Unpin from the top",
65		'dblclick_to_exit_zoom'  : "Double click to exit zoom",
66
67		'monthNames' : [ "January","February","March","April","May","June","July","August","September","October","November","December" ],
68		'monthNamesShort' : [ "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" ],
69		'dayNames' : ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
70		'dayNamesShort' : ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
71		'today' : "today",
72		'month' : "month",
73		'week' : "week",
74		'day' : "day",
75		'allday' : "All day",
76
77		// mod cloud
78		'download_info' : "Please stand by while your download is being prepared.",
79
80		// mod register
81		'email_not_valid' : "Email address not valid",
82		'email_required' : "Required"
83
84	};
85
86</script>
86
87
88
89<script src="https://hub.farthinghalearms.com/view/js/jquery.js?v=11.4.1"></script>
vendor: 2 bytes, line 89
89
90<script src="https://hub.farthinghalearms.com/library/datetimepicker/jquery.datetimepicker.js?v=11.4.1"></script>
vendor: 2 bytes, line 90
90
91<script src="https://hub.farthinghalearms.com/library/justifiedGallery/jquery.justifiedGallery.min.js?v=11.4.1"></script>
vendor: 2 bytes, line 91
91
92<script src="https://hub.farthinghalearms.com/library/textcomplete/textcomplete.min.js?v=11.4.1"></script>
vendor: 2 bytes, line 92
92
93<script src="https://hub.farthinghalearms.com/view/js/autocomplete.js?v=11.4.1"></script>
vendor: 2 bytes, line 93
93
94<script src="https://hub.farthinghalearms.com/library/readmore.js/readmore.js?v=11.4.1"></script>
vendor: 2 bytes, line 94
94
95<script src="https://hub.farthinghalearms.com/library/libsodium/browsers/sodium.js?v=11.4.1"></script>
vendor: 2 bytes, line 95
95
96<script src="https://hub.farthinghalearms.com/view/js/acl.js?v=11.4.1"></script>
vendor: 2 bytes, line 96
96
97<script src="https://hub.farthinghalearms.com/view/js/webtoolkit.base64.js?v=11.4.1"></script>
vendor: 2 bytes, line 97
97
98<script src="https://hub.farthinghalearms.com/view/js/crypto.js?v=11.4.1"></script>
vendor: 2 bytes, line 98
98
99<script src="https://hub.farthinghalearms.com/library/jRange/jquery.range.js?v=11.4.1"></script>
vendor: 2 bytes, line 99
99
100<script src="https://hub.farthinghalearms.com/library/colorbox/jquery.colorbox-min.js?v=11.4.1"></script>
vendor: 2 bytes, line 100
100
101<script src="https://hub.farthinghalearms.com/library/jquery.AreYouSure/jquery.are-you-sure.js?v=11.4.1"></script>
vendor: 2 bytes, line 101
101
102<script src="https://hub.farthinghalearms.com/library/tableofcontents/jquery.toc.js?v=11.4.1"></script>
vendor: 2 bytes, line 102
102
103<script src="https://hub.farthinghalearms.com/library/Sortable/Sortable.min.js?v=11.4.1"></script>
vendor: 2 bytes, line 103
103
104<script src="https://hub.farthinghalearms.com/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js?v=11.4.1"></script>
vendor: 2 bytes, line 104
104
105<script src="https://hub.farthinghalearms.com/library/bootstrap-tagsinput/bootstrap-tagsinput.js?v=11.4.1"></script>
vendor: 2 bytes, line 105
105
106<script src="https://hub.farthinghalearms.com/library/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js?v=11.4.1"></script>
vendor: 2 bytes, line 106
106
107<script src="https://hub.farthinghalearms.com/view/theme/redbasic/js/redbasic.js?v=11.4.1"></script>
107
108
109<link rel="manifest" href="/manifest.json" />
110<link rel="shortcut icon" href="https://hub.farthinghalearms.com/images/hubzilla.svg" />
111<link rel="apple-touch-icon" href="/images/app/hz-192.png" />
112
113
114<script>
115	var lang = 'en';
116	var updateInterval = 80000;
117	var sse_enabled = 0;
118	var localUser = false;
119	var zid = null;
120	var justifiedGalleryActive = false;
121		var channelId = false;	var auto_save_draft = false;
122	var module = 'home';</script>
122
123
124
125
126<script>$(document).ready(function() { $("#nav-search-text").search_autocomplete('https://hub.farthinghalearms.com/acl');});</script>
126<script type="text/javascript" src="https://hub.farthinghalearms.com/addon/openstreetmap/openstreetmap.js"></script>
vendor: 2 bytes, line 126
126
127<script src="https://hub.farthinghalearms.com/view/js/main.js?v=11.4.1"></script>
127
128</head>
129<body  >
130		<header><div id="toast-container" class="vstack gap-3 m-3 position-fixed top-0 end-0"></div>
131</header>
132	<nav id="navbar-top" class="navbar navbar-expand-lg sticky-top bg-body-tertiary mb-4" >
133	<div class="container-fluid flex-nowrap">
134				<div class="navbar-text d-lg-none navbar-banner">Farthinghale Arms</div>
135				<div class="navbar-toggler-right">
136						<button id="expand-aside" type="button" class="d-lg-none navbar-toggler border-0">
137				<i class="bi bi-arrow-right-circle generic-icons" id="expand-aside-icon"></i>
138			</button>
139						<button id="menu-btn" class="navbar-toggler border-0" type="button" data-bs-toggle="offcanvas" data-bs-target="#app-bin">
140				<i class="bi bi-three-dots-vertical generic-icons"></i>
141			</button>
142		</div>
143		<div class="collapse navbar-collapse justify-content-between" id="navbar-collapse-1">
144			<ul class="navbar-nav">
145								<li class="nav-item d-lg-flex">
146										<a class="nav-link" href="#" title="Sign in" data-bs-toggle="modal" data-bs-target="#nav-login">
147					Login
148					</a>
149									</li>
150															</ul>
151
152			<div class="navbar-text navbar-banner">Farthinghale Arms</div>
153
154			<ul id="nav-right" class="navbar-nav">
155				<li class="nav-item collapse clearfix" id="nav-search" data-bs-theme="light">
156					<form class="form-inline" method="get" action="search" role="search">
157						<input class="form-control form-control-sm mt-1 me-2" id="nav-search-text" type="text" value="" placeholder="@name, #tag, ?doc, content" name="search" title="Search site @name, !forum, #tag, ?docs, content" onclick="this.submit();" onblur="closeMenu('nav-search'); openMenu('nav-search-btn');"/>
158					</form>
159					<div id="nav-search-spinner" class="spinner-wrapper">
160						<div class="spinner s"></div>
161					</div>
162				</li>
163				<li class="nav-item" id="nav-search-btn">
164					<a class="nav-link" href="#nav-search" title="Search site @name, !forum, #tag, ?docs, content" onclick="openMenu('nav-search'); closeMenu('nav-search-btn'); $('#nav-search-text').focus(); return false;"><i class="bi bi-search generic-icons"></i></a>
165				</li>
166																<li class="nav-item dropdown" id="app-menu">
167					<a class="nav-link" href="#" data-bs-toggle="offcanvas" data-bs-target="#app-bin" aria-controls="app-bin"><i class="bi bi-three-dots-vertical generic-icons"></i></a>
168				</li>
169			</ul>
170		</div>
171			</div>
172</nav>
173<div class="offcanvas offcanvas-end" tabindex="-1" id="app-bin" aria-labelledby="app-bin-label">
174	<div class="offcanvas-header">
175
176				<div class="hstack gap-1 d-lg-none pt-1 pb-1">
177						<a class="btn btn-primary btn-sm text-white" href="#" title="Sign in" data-bs-toggle="modal" data-bs-target="#nav-login">
178				Login
179			</a>
180						
181		</div>
182		<div class="nav d-lg-flex w-100"></div>
183				<div class="hstack gap-1">
184						<button id="theme-switch" type="button" class="btn btn-outline-secondary border-0"><i id="theme-switch-icon" class="bi bi-moon"></i></button>
185						<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
186		</div>
187
188	</div>
189	<div class="offcanvas-body">
190								<div class="text-uppercase text-muted nav-link">
191			System Apps
192		</div>
193		<div class="nav nav-pills flex-column">
194							<a class="nav-link" href="https://hub.farthinghalearms.com/directory" data-papp="eyJ2ZXJzaW9uIjoiNCIsInVybCI6IiRiYXNldXJsXC9kaXJlY3RvcnksICRiYXNldXJsXC9z
195ZXR0aW5nc1wvZGlyZWN0b3J5IiwibmFtZSI6IkRpcmVjdG9yeSIsInBob3RvIjoiaWNvbjpk
196aWFncmFtLTMiLCJjYXRlZ29yaWVzIjoibmF2X2ZlYXR1cmVkX2FwcCwgTmV0d29ya2luZyIs
197ImRlc2MiOiJNZW1iZXJzIGRpcmVjdG9yeSBvZiB0aGUgWm90IG5ldHdvcmsuIiwidHlwZSI6
198InN5c3RlbSIsInBsdWdpbiI6IiJ9
199" data-icon="diagram-3" data-url="https://hub.farthinghalearms.com/directory" data-name="Directory"><i class="generic-icons-nav bi bi-diagram-3"></i>Directory</a>
200
201							<a class="nav-link" href="https://hub.farthinghalearms.com/help" data-papp="eyJ2ZXJzaW9uIjoiNCIsInVybCI6IiRiYXNldXJsXC9oZWxwIiwibmFtZSI6IkhlbHAiLCJw
202aG90byI6Imljb246cXVlc3Rpb24tbGciLCJjYXRlZ29yaWVzIjoibmF2X2ZlYXR1cmVkX2Fw
203cCwgU3lzdGVtIiwiZGVzYyI6IlRoZSBIdWJ6aWxsYSBoZWxwIHBhZ2VzLiIsInR5cGUiOiJz
204eXN0ZW0iLCJwbHVnaW4iOiIifQ==
205" data-icon="question-lg" data-url="https://hub.farthinghalearms.com/help" data-name="Help"><i class="generic-icons-nav bi bi-question-lg"></i>Help</a>
206
207							<a class="nav-link" href="https://hub.farthinghalearms.com/lang" data-papp="eyJ2ZXJzaW9uIjoiNCIsInVybCI6IiRiYXNldXJsXC9sYW5nIiwibmFtZSI6Ikxhbmd1YWdl
208IiwicGhvdG8iOiJpY29uOnRyYW5zbGF0ZSIsImNhdGVnb3JpZXMiOiJTeXN0ZW0iLCJkZXNj
209IjoiQSBzaW1wbGUgbGFuZ3VhZ2Ugc2VsZWN0b3IuIiwidHlwZSI6InN5c3RlbSIsInBsdWdp
210biI6IiJ9
211" data-icon="translate" data-url="https://hub.farthinghalearms.com/lang" data-name="Language"><i class="generic-icons-nav bi bi-translate"></i>Language</a>
212
213							<a class="nav-link" href="https://hub.farthinghalearms.com/randprof" data-papp="eyJ2ZXJzaW9uIjoiNCIsInVybCI6IiRiYXNldXJsXC9yYW5kcHJvZiIsIm5hbWUiOiJSYW5k
214b20gQ2hhbm5lbCIsInRhcmdldCI6InJhbmRwcm9mIiwicGhvdG8iOiJpY29uOnNodWZmbGUi
215LCJjYXRlZ29yaWVzIjoiTmV0d29ya2luZyIsImRlc2MiOiJWaXNpdCBhIHJhbmRvbSBjaGFu
216bmVsIGluIHRoZSBuZXR3b3JrLiIsInR5cGUiOiJzeXN0ZW0iLCJwbHVnaW4iOiIifQ==
217" data-icon="shuffle" data-url="https://hub.farthinghalearms.com/randprof" data-name="Random Channel"><i class="generic-icons-nav bi bi-shuffle"></i>Random Channel</a>
218
219							<a class="nav-link" href="https://framagit.org/hubzilla/core/issues" data-papp="eyJ2ZXJzaW9uIjoiMyIsInVybCI6Imh0dHBzOlwvXC9mcmFtYWdpdC5vcmdcL2h1YnppbGxh
220XC9jb3JlXC9pc3N1ZXMiLCJuYW1lIjoiUmVwb3J0IEJ1ZyIsInBob3RvIjoiaWNvbjpidWci
221LCJjYXRlZ29yaWVzIjoiU3lzdGVtIiwiZGVzYyI6IlByb3ZpZGVzIGEgbGluayB0byB0aGUg
222SHViemlsbGEgYnVnIHRyYWNrZXIuIiwidHlwZSI6InN5c3RlbSIsInBsdWdpbiI6IiJ9
223" data-icon="bug" data-url="https://framagit.org/hubzilla/core/issues" data-name="Report Bug"><i class="generic-icons-nav bi bi-bug"></i>Report Bug</a>
224
225							<a class="nav-link" href="https://hub.farthinghalearms.com/search" data-papp="eyJ2ZXJzaW9uIjoiMyIsInVybCI6IiRiYXNldXJsXC9zZWFyY2giLCJuYW1lIjoiU2VhcmNo
226IiwicGhvdG8iOiJpY29uOnNlYXJjaCIsImRlc2MiOiJBIHNlcGFyYXRlIHNlYXJjaCBhcHAg
227dG8gbG9vayB1cCBjb250ZW50LCBjaGFubmVscywgdGFncywgZG9jdW1lbnRhdGlvbiBvciBy
228ZW1vdGUgY29udGVudCBkZXBlbmRpbmcgb24gdGhlIHNlYXJjaCBzdHJpbmcgcHJlZml4LiIs
229InR5cGUiOiJzeXN0ZW0iLCJwbHVnaW4iOiIifQ==
230" data-icon="search" data-url="https://hub.farthinghalearms.com/search" data-name="Search"><i class="generic-icons-nav bi bi-search"></i>Search</a>
231
232					</div>
233			</div>
234</div>
235	<main>
236		<div class="content">
237			<div class="columns">
238				<aside id="region_1" class="d-none d-lg-block"><div class="aside_spacer_top_left"></div><div class="aside_spacer_left"><div id="left_aside_wrapper" class="aside_wrapper">
239<script>
240	var sse_bs_active = false;
241	var sse_offset = 0;
242	var sse_type;
243	var sse_partial_result = false;
244	var sse_rmids = [];
245	var sse_fallback_interval;
246	var sse_sys_only = 1;
247
248	document.addEventListener("DOMContentLoaded", function() {
249		let notificationsWrapper = document.getElementById('notifications_wrapper');
250		let notificationsParent = notificationsWrapper ? notificationsWrapper.parentElement.id : null;
251		let notificationsBtn = document.querySelectorAll('.notifications-btn');
252
253		// Event listener for notifications button
254		if (notificationsBtn) {
255			notificationsBtn.forEach(function (element) {
256				element.addEventListener('click', function(e) {
257					e.preventDefault();
258					e.stopPropagation();
259
260					// Remove the 'd-none' class to show the notifications wrapper
261					notificationsWrapper.classList.remove('d-none');
262
263					// Check if the notifications wrapper has the 'fs' class
264					if (notificationsWrapper.classList.contains('fs')) {
265						// Prepend the notifications wrapper back to its original parent and hide it
266						document.getElementById(notificationsParent).appendChild(notificationsWrapper);
267						notificationsWrapper.classList.add('d-none');
268					} else {
269						// Otherwise, prepend the notifications wrapper to 'main'
270						document.querySelector('main').prepend(notificationsWrapper);
271					}
272
273					// Toggle the 'fs' class
274					notificationsWrapper.classList.toggle('fs');
275				});
276			});
277		}
278
279		// Event listener for clicking a notification
280		document.addEventListener('click', function(event) {
281			if (event.target.closest('a') && event.target.closest('a').classList.contains('notification')) {
282				if (notificationsWrapper.classList.contains('fs')) {
283					// Move notifications wrapper back to its original parent and hide it
284					notificationsWrapper.classList.remove('fs');
285					notificationsWrapper.classList.add('d-none');
286					document.getElementById(notificationsParent).appendChild(notificationsWrapper);
287
288				}
289			}
290		});
291
292		if(sse_enabled) {
293			if(typeof(window.SharedWorker) === 'undefined') {
294				// notifications with multiple tabs open will not work very well in this scenario
295				let evtSource = new EventSource('/sse');
296
297				evtSource.addEventListener('notifications', function(e) {
298					let obj = JSON.parse(e.data);
299					sse_handleNotifications(obj, false, false);
300				}, false);
301
302				document.addEventListener('visibilitychange', function() {
303					if (!document.hidden) {
304						sse_offset = 0;
305						sse_bs_init();
306					}
307				}, false);
308
309			}
310			else {
311				let myWorker = new SharedWorker('/view/js/sse_worker.js', localUser);
312
313				myWorker.port.onmessage = function(e) {
314					obj = e.data;
315					console.log(obj);
316					sse_handleNotifications(obj, false, false);
317				}
318
319				myWorker.onerror = function(e) {
320					myWorker.port.close();
321				}
322
323				myWorker.port.start();
324			}
325		}
326		else {
327			if (!document.hidden) {
328				sse_fallback();
329				sse_fallback_interval = setInterval(sse_fallback, updateInterval);
330			}
331
332			document.addEventListener('visibilitychange', function() {
333				if (document.hidden) {
334					clearInterval(sse_fallback_interval);
335				}
336				else {
337					sse_offset = 0;
338					sse_bs_init();
339					sse_fallback_interval = setInterval(sse_fallback, updateInterval);
340				}
341
342			}, false);
343		}
344
345		document.querySelectorAll('.notification-link').forEach(function (element) {
346			element.addEventListener('click', function (element) {
347				sse_bs_notifications(element, true, false);
348			});
349		});
350
351		document.querySelectorAll('.notification-filter').forEach(function (element) {
352			element.addEventListener('keypress', function(e) {
353				if (e.which == 13) { // Enter key
354					this.blur();
355					sse_offset = 0;
356
357					// Clear the content of the menu
358					document.getElementById("nav-" + sse_type + "-menu").innerHTML = '';
359
360					// Show the loading element
361					document.getElementById("nav-" + sse_type + "-loading").style.display = 'block';
362
363					// Get the value from the input element
364					var cn_val = document.getElementById('cn-' + sse_type + '-input') ? document.getElementById('cn-' + sse_type + '-input').value.toString().toLowerCase() : '';
365
366					// Send a GET request using the Fetch API
367					fetch('/sse_bs/' + sse_type + '/' + sse_offset + '?nquery=' + encodeURIComponent(cn_val))
368						.then(response => response.json())
369						.then(obj => {
370							console.log('sse: bootstraping ' + sse_type);
371							console.log(obj);
372
373							sse_bs_active = false;
374							sse_partial_result = true;
375							sse_offset = obj[sse_type].offset;
376
377							if (sse_offset < 0) {
378								document.getElementById("nav-" + sse_type + "-loading").style.display = 'none';
379							}
380
381							sse_handleNotifications(obj, true, false);
382						})
383						.catch(error => {
384							console.error('Error fetching data:', error);
385						});
386				}
387			});
388		});
389
390		document.querySelectorAll('.notifications-textinput-clear').forEach(function (element) {
391			element.addEventListener('click', function(e) {
392				if (!sse_partial_result) return;
393
394				// Clear the content of the menu
395				document.getElementById("nav-" + sse_type + "-menu").innerHTML = '';
396
397				// Show the loading element
398				document.getElementById("nav-" + sse_type + "-loading").style.display = 'block';
399
400				// Send a GET request using the Fetch API
401				fetch('/sse_bs/' + sse_type)
402					.then(response => response.json())
403					.then(obj => {
404						console.log('sse: bootstraping ' + sse_type);
405						console.log(obj);
406
407						sse_bs_active = false;
408						sse_partial_result = false;
409						sse_offset = obj[sse_type].offset;
410						if (sse_offset < 0) {
411							document.getElementById("nav-" + sse_type + "-loading").style.display = 'none';
412						}
413
414						sse_handleNotifications(obj, true, false);
415					})
416					.catch(error => {
417						console.error('Error fetching data:', error);
418					});
419			});
420		});
421
422		document.querySelectorAll('.notification-content').forEach(function(element) {
423			element.addEventListener('scroll', function() {
424				if (this.scrollTop > this.scrollHeight - this.clientHeight - (this.scrollHeight / 7)) {
425					sse_bs_notifications(sse_type, false, true);
426				}
427			});
428		});
429
430		
431	});
432
433	document.addEventListener('hz:sse_setNotificationsStatus', function(e) {
434		sse_setNotificationsStatus(e.detail);
435	});
436
437	document.addEventListener('hz:sse_bs_init', function() {
438		sse_bs_init();
439	});
440
441	document.addEventListener('hz:sse_bs_counts', function() {
442		sse_bs_counts();
443	});
444
445
446	function sse_bs_init() {
447		// Check if 'notification_open' exists in sessionStorage or if sse_type is defined
448		if (sessionStorage.getItem('notification_open') !== null || typeof sse_type !== 'undefined') {
449			if (typeof sse_type === 'undefined') {
450				sse_type = sessionStorage.getItem('notification_open');
451			}
452
453			// Add the 'show' class to the appropriate element
454			let subNav = document.getElementById("nav-" + sse_type + "-sub");
455			if (subNav) {
456				subNav.classList.add('show');
457			}
458
459			// Call the sse_bs_notifications function
460			sse_bs_notifications(sse_type, true, false);
461		} else {
462			// Call the sse_bs_counts function if conditions are not met
463			sse_bs_counts();
464		}
465	}
466
467	function sse_bs_counts() {
468		if (sse_bs_active || sse_sys_only) {
469			return;
470		}
471
472		sse_bs_active = true;
473
474		// Use the fetch API to send the POST request with the data
475		fetch('/sse_bs', {
476			method: 'POST',
477			body: new URLSearchParams({sse_rmids: sse_rmids})
478		})
479		.then(response => response.json())  // Parse the JSON response
480		.then(obj => {
481			console.log(obj);
482			sse_bs_active = false;
483			sse_rmids = [];
484			sse_handleNotifications(obj, true, false);
485		})
486		.catch(error => {
487			console.error('Error:', error);
488			sse_bs_active = false;
489		});
490	}
491
492	function sse_bs_notifications(e, replace, followup) {
493		if (sse_bs_active || sse_sys_only) {
494			return;
495		}
496
497		let manual = false;
498
499		if (typeof replace === 'undefined') {
500			replace = e.data.replace;
501		}
502
503		if (typeof followup === 'undefined') {
504			followup = e.data.followup;
505		}
506
507		if (typeof e === 'string') {
508			sse_type = e;
509		} else {
510			manual = true;
511			sse_offset = 0;
512			sse_type = e.target.dataset.sse_type;
513		}
514
515		if (typeof sse_type === 'undefined') {
516			return;
517		}
518
519		if (followup || !manual || !document.getElementById('notification-link-' + sse_type).classList.contains('collapsed')) {
520
521			if (sse_offset >= 0) {
522				document.getElementById("nav-" + sse_type + "-loading").style.display = 'block';
523			}
524
525			sessionStorage.setItem('notification_open', sse_type);
526
527			if (sse_offset !== -1 || replace) {
528				let cn_val = (document.getElementById('cn-' + sse_type + '-input') && sse_partial_result)
529					? document.getElementById('cn-' + sse_type + '-input').value.toString().toLowerCase()
530					: '';
531
532				document.getElementById("nav-" + sse_type + "-loading").style.display = 'block';
533
534				sse_bs_active = true;
535
536				// Send POST request using fetch API
537				fetch('/sse_bs/' + sse_type + '/' + sse_offset, {
538					method: 'POST',
539					body: new URLSearchParams({
540						sse_rmids: sse_rmids,
541						nquery: encodeURIComponent(cn_val)
542					})
543				})
544				.then(response => response.json())  // Parse the JSON response
545				.then(obj => {
546					console.log('sse: bootstraping ' + sse_type);
547					console.log(obj);
548					sse_bs_active = false;
549					sse_rmids = [];
550					document.getElementById("nav-" + sse_type + "-loading").style.display = 'none';
551
552					if (typeof obj[sse_type] !== 'undefined') {
553						sse_offset = obj[sse_type].offset;
554					}
555
556					sse_handleNotifications(obj, replace, followup);
557				})
558				.catch(error => {
559					console.error('Error:', error);
560					sse_bs_active = false;
561				});
562			} else {
563				document.getElementById("nav-" + sse_type + "-loading").style.display = 'none';
564			}
565		} else {
566			sessionStorage.removeItem('notification_open');
567		}
568	}
569
570	function sse_handleNotifications(obj, replace, followup) {
571
572		// Notice and info notifications
573		if (obj.notice) {
574			obj.notice.notifications.forEach(notification => {
575				toast(notification, 'danger');
576			});
577		}
578
579		if (obj.info) {
580			obj.info.notifications.forEach(notification => {
581				toast(notification, 'info');
582			});
583		}
584
585		if (sse_sys_only) {
586			return;
587		}
588
589		let	all_notifications = Object.keys(obj);
590
591		all_notifications.forEach(type => {
592			if (typeof obj[type] === 'undefined') {
593				return;
594			}
595
596			let count = Number(obj[type].count);
597
598			// Show notifications and update count
599			let updateElement = document.querySelector('.' + type + '-update');
600			let buttonElement = document.querySelector('.' + type + '-button');
601			let subElement = document.getElementById('nav-' + type + '-sub');
602
603			if (count) {
604				if (buttonElement) buttonElement.style.display = 'block';  // Fade-in effect replaced by display block
605				if (replace || followup) {
606					updateElement.textContent = count >= 100 ? '99+' : count;
607				} else {
608					count = count + Number(updateElement.textContent.replace(/\++$/, ''));
609					updateElement.textContent = count >= 100 ? '99+' : count;
610				}
611			} else {
612				if (updateElement) updateElement.textContent = '0';
613				if (subElement) subElement.classList.remove('show');
614				if (buttonElement) {
615					buttonElement.style.display = 'none'; // Fade-out effect replaced by display none
616					sse_setNotificationsStatus(null);
617				}
618			}
619
620			if (obj[type].notifications.length) {
621				sse_handleNotificationsItems(type, obj[type].notifications, replace, followup);
622			}
623		});
624
625		sse_setNotificationsStatus(null);
626
627		if (typeof obj[sse_type] !== 'undefined') {
628			// Load more notifications if visible notifications count becomes low
629			if (sse_type && sse_offset !== -1) {
630				let menu = document.getElementById('nav-' + sse_type + '-menu');
631				if (menu && menu.querySelectorAll('.notification:not(.tt-filter-active):not(.cn-filter-active)').length < 15) {
632					sse_bs_notifications(sse_type, false, true);
633				}
634			}
635		}
636	}
637
638	function sse_handleNotificationsItems(notifyType, data, replace, followup) {
639		let notifications_tpl = decodeURIComponent(document.querySelector("#nav-notifications-template[rel=template]").innerHTML.replace('data-src', 'src'));
640		let notify_menu = document.getElementById("nav-" + notifyType + "-menu");
641		let notify_loading = document.getElementById("nav-" + notifyType + "-loading");
642		let notify_count = document.getElementsByClassName(notifyType + "-update");
643
644		if (notify_menu === null) {
645			return;
646		}
647
648		
649		if (replace && !followup) {
650			notify_menu.innerHTML = '';  // Clear menu
651			notify_loading.style.display = 'none';  // Hide loading
652		}
653
654		data.forEach(notification => {
655			// Special handling for network notifications
656			if (!replace && !followup && notification.thread_top && notifyType === 'network') {
657				document.dispatchEvent(new CustomEvent('hz:handleNetworkNotificationsItems', { detail: notification }));
658			}
659
660			// Prepare HTML using the template
661			let html = notifications_tpl.format(
662				notification.notify_link,
663				notification.photo,
664				notification.name,
665				notification.addr,
666				notification.message,
667				notification.when,
668				notification.hclass,
669				notification.b64mid,
670				notification.notify_id,
671				notification.thread_top,
672				notification.unseen,
673				notification.private_forum,
674				encodeURIComponent(notification.mids),
675				notification.body
676			);
677
678			// Append the new notification HTML to the menu
679			notify_menu.insertAdjacentHTML('beforeend', html);
680		});
681
682		// Sort notifications by date
683		if (!replace && !followup) {
684			let notifications = Array.from(notify_menu.getElementsByClassName('notification'));
685
686			notifications.sort((a, b) => {
687				let dateA = new Date(a.dataset.when).getTime();
688				let dateB = new Date(b.dataset.when).getTime();
689
690								return dateB - dateA; // Sort in descending order
691							});
692
693			notifications.forEach(notification => notify_menu.appendChild(notification));
694		}
695
696
697		// Filter thread_top notifications if the filter is active
698		let filterThreadTop = document.getElementById('tt-' + notifyType + '-only');
699		if (filterThreadTop && filterThreadTop.classList.contains('active')) {
700			let notifications = notify_menu.querySelectorAll('[data-thread_top="false"]');
701			notifications.forEach(notification => notification.classList.add('tt-filter-active'));
702		}
703
704		// Filter notifications based on the input field
705		let filterInput = document.getElementById('cn-' + notifyType + '-input');
706		if (filterInput) {
707			let filter = filterInput.value.toString().toLowerCase();
708			if (filter) {
709				if (filter.indexOf('%') === 0) filter = filter.substring(1);  // Remove the percent if it exists
710				let notifications = notify_menu.querySelectorAll('.notification');
711				notifications.forEach(notification => {
712					let cn = notification.dataset.contact_name.toString().toLowerCase();
713					let ca = notification.dataset.contact_addr.toString().toLowerCase();
714					if (cn.indexOf(filter) === -1 && ca.indexOf(filter) === -1) {
715						notification.classList.add('cn-filter-active');
716					} else {
717						notification.classList.remove('cn-filter-active');
718					}
719				});
720			}
721		}
722
723		// Update relative time for notifications
724		updateRelativeTime('.autotime-narrow');
725	}
726
727
728	function sse_updateNotifications(mid) {
729		// Find the notification elements based on its 'data-b64mid' or href attribute.
730		// The latter will match reactions where b64mid will contain the uuid of its thread parent (reacted on) instead of its own.
731		let notifications = document.querySelectorAll(`.notification[data-b64mid='${mid}'], .notification[href*='display/${mid}']`);
732
733		notifications.forEach(notification => {
734			let type = notification.parentElement.id.split('-')[1];
735
736			// Skip processing if the type is 'notify' and the conditions don't match
737			if (type === 'notify' && (mid !== bParam_mid || sse_type !== 'notify')) {
738				return true;
739			}
740
741			notification.remove();
742		});
743	}
744
745
746	function sse_setNotificationsStatus(data) {
747		let primary_notifications = ['dm', 'home', 'intros', 'register', 'notify', 'files'];
748		let nlinks = document.getElementById('notifications').querySelectorAll('.notification-link');
749		let primary_available = false;
750		let any_available = false;
751
752		// Loop through all notifications and check their visibility
753		nlinks.forEach(nlink => {
754			let type = nlink.dataset.sse_type;
755			let button = document.querySelector(`.${type}-button`);
756			if (button && getComputedStyle(button).display === 'block') {
757				any_available = true;
758				if (primary_notifications.indexOf(type) > -1) {
759					primary_available = true;
760				}
761			}
762		});
763
764		// Update notification button icons based on the primary notification availability
765		let notificationIcons = document.querySelectorAll('.notifications-btn-icon');
766
767		if (notificationIcons) {
768			let iconClass = primary_available ? 'bi-exclamation-triangle' : 'bi-exclamation-circle';
769			let iconToRemove = primary_available ? 'bi-exclamation-circle' : 'bi-exclamation-triangle';
770
771			notificationIcons.forEach(notificationIcon => {
772				notificationIcon.classList.replace(iconToRemove, iconClass);
773			});
774		}
775
776		// Update visibility of notification button and sections
777		let notificationsBtn = document.querySelectorAll('.notifications-btn');
778		let noNotifications = document.querySelector('#no_notifications');
779		let notifications = document.querySelector('#notifications');
780		let navbarCollapse = document.querySelector('#navbar-collapse-1');
781
782		if (any_available) {
783			notificationsBtn.forEach(btn => {
784				btn.style.opacity = 1;
785			});
786			noNotifications.style.display = 'none';
787			notifications.style.display = 'block';
788		} else {
789			if (notificationsBtn) {
790				notificationsBtn.forEach(btn => {
791					btn.style.opacity = 0.5;
792				});
793			}
794			if (navbarCollapse) navbarCollapse.classList.remove('show');
795			noNotifications.style.display = 'block';
796			notifications.style.display = 'none';
797		}
798
799		// Handle specific notifications if 'data' is provided
800		if (data) {
801			data.forEach(function (nmid) {
802				sse_rmids.push(nmid);
803				sse_updateNotifications(nmid);
804			});
805		}
806	}
807
808	function sse_fallback() {
809		fetch('/sse')
810			.then(response => response.json())
811			.then(obj => {
812				if (!obj) return;
813
814				console.log('sse fallback');
815				console.log(obj);
816
817				sse_handleNotifications(obj, false, false);
818			})
819			.catch(error => {
820				console.error('Error fetching SSE data:', error);
821			});
822	}
823
824</script>
824
825
826
827</div></div></aside>
828				<section id="region_2">
829<div class="generic-content-wrapper">
830			<div class="section-title-wrapper">
831			<h2 class="">Welcome to Farthinghale Arms</h2>
832		</div>
833		<div class="section-content-wrapper">
834		<form action="https://hub.farthinghalearms.com/" id="main_login" method="post" >
835	<input type="hidden" name="auth-params" value="login" />
836	<div>
837			<div id="id_main_login_username_wrapper" class="mb-3">
838		<label for="id_main_login_username" id="label_main_login_username">
839			Nickname		</label>
840		<input
841			class="form-control"
842			name="main_login_username"
843			id="id_main_login_username"
844			type="text"
845			value=""
846						>
847		<small id="help_main_login_username" class="form-text text-muted">
848			
849		</small>
850	</div>
851			<div class="mb-3">
852		<label for="id_main_login_password">Password</label>
853		<input class="form-control" type="password" name="main_login_password" id="id_main_login_password" value="">		<small id="help_main_login_password" class="form-text text-muted"></small>
854	</div>
855			<div id="main_login_remember_container" class="clearfix onoffswitch checkbox mb-3">
856		<label for="id_main_login_remember">Remember me</label>
857		<div class="float-end"><input type="checkbox" name="main_login_remember" id="id_main_login_remember" value="1"   ><label class="switchlabel" for='id_main_login_remember'> <span class="onoffswitch-inner" data-on='Yes' data-off='No'></span><span class="onoffswitch-switch"></span></label></div>
858		<small class="form-text text-muted"></small>
859	</div>
860		<button type="submit" name="submit" class="btn btn-primary">Login</button>
861				<hr>
862		<a href="rmagic" class="btn btn-outline-success">Remote Authentication</a>
863		<a href="https://hub.farthinghalearms.com/pubsites" title="Create an account to access services and applications" class="register-link float-end">Register</a>
864	</div>
865		<input type="hidden" name="0" value="" />
866	</form>
867<script type="text/javascript"> $(document).ready(function() { $("#id_main_login_username").focus();} );</script>
867
868	</div>
869</div>
870<div id="nav-login" class="modal" tabindex="-1" role="dialog">
871	<div class="modal-dialog" role="document">
872		<div class="modal-content">
873			<div class="modal-header">
874				<h4 class="modal-title">Login</h4>
875				<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
876			</div>
877			<div class="modal-body">
878				<div class="mb-3">
879					<form action="https://hub.farthinghalearms.com/" id="modal_login" method="post" >
880	<input type="hidden" name="auth-params" value="login" />
881	<div>
882			<div id="id_modal_login_username_wrapper" class="mb-3">
883		<label for="id_modal_login_username" id="label_modal_login_username">
884			Nickname		</label>
885		<input
886			class="form-control"
887			name="modal_login_username"
888			id="id_modal_login_username"
889			type="text"
890			value=""
891						>
892		<small id="help_modal_login_username" class="form-text text-muted">
893			
894		</small>
895	</div>
896			<div class="mb-3">
897		<label for="id_modal_login_password">Password</label>
898		<input class="form-control" type="password" name="modal_login_password" id="id_modal_login_password" value="">		<small id="help_modal_login_password" class="form-text text-muted"></small>
899	</div>
900			<div id="modal_login_remember_container" class="clearfix onoffswitch checkbox mb-3">
901		<label for="id_modal_login_remember">Remember me</label>
902		<div class="float-end"><input type="checkbox" name="modal_login_remember" id="id_modal_login_remember" value="1"   ><label class="switchlabel" for='id_modal_login_remember'> <span class="onoffswitch-inner" data-on='Yes' data-off='No'></span><span class="onoffswitch-switch"></span></label></div>
903		<small class="form-text text-muted"></small>
904	</div>
905		<button type="submit" name="submit" class="btn btn-primary">Login</button>
906				<hr>
907		<a href="rmagic" class="btn btn-outline-success">Remote Authentication</a>
908		<a href="https://hub.farthinghalearms.com/pubsites" title="Create an account to access services and applications" class="register-link float-end">Register</a>
909	</div>
910		<input type="hidden" name="0" value="" />
911	</form>
912
913				</div>
914			</div>
915		</div>
916	</div>
917</div>
918
919					<div id="page-footer"></div>
920					<div id="pause"></div>
921				</section>
922				<aside id="region_3" class="d-none d-xl-block"><div class="aside_spacer_top_right"></div><div class="aside_spacer_right"><div id="right_aside_wrapper" class="aside_wrapper"></div></div></aside>
923			</div>
924		</div>
925	</main>
926	<footer></footer>
927</body>
928</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.