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.