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_directory.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>
vendor: 2 bytes, line 107
107
108<script src="https://hub.farthinghalearms.com/view/js/mod_directory.js?v=11.4.1"></script>
108 109 110<link rel="manifest" href="/manifest.json" /> 111<link rel="shortcut icon" href="https://hub.farthinghalearms.com/images/hubzilla.svg" /> 112<link rel="apple-touch-icon" href="/images/app/hz-192.png" /> 113 114
115<script> 116 var lang = 'en'; 117 var updateInterval = 80000; 118 var sse_enabled = 0; 119 var localUser = false; 120 var zid = null; 121 var justifiedGalleryActive = false; 122 var channelId = false; var auto_save_draft = false; 123 var module = 'directory';</script>
123 124 125 126
127<script>$(document).ready(function() { $("#nav-search-text").search_autocomplete('https://hub.farthinghalearms.com/acl');});</script>
127<script type="text/javascript" src="https://hub.farthinghalearms.com/addon/openstreetmap/openstreetmap.js"></script>
vendor: 2 bytes, line 127
127
128<script src="https://hub.farthinghalearms.com/view/js/main.js?v=11.4.1"></script>
128 129</head> 130<body > 131 <header><div id="toast-container" class="vstack gap-3 m-3 position-fixed top-0 end-0"></div> 132</header> 133 <nav id="navbar-top" class="navbar navbar-expand-lg sticky-top bg-body-tertiary mb-4" > 134 <div class="container-fluid flex-nowrap"> 135 <div class="navbar-text d-lg-none navbar-banner">Farthinghale Arms</div> 136 <div class="navbar-toggler-right"> 137 <button id="expand-aside" type="button" class="d-lg-none navbar-toggler border-0"> 138 <i class="bi bi-arrow-right-circle generic-icons" id="expand-aside-icon"></i> 139 </button> 140 <button id="menu-btn" class="navbar-toggler border-0" type="button" data-bs-toggle="offcanvas" data-bs-target="#app-bin"> 141 <i class="bi bi-three-dots-vertical generic-icons"></i> 142 </button> 143 </div> 144 <div class="collapse navbar-collapse justify-content-between" id="navbar-collapse-1"> 145 <ul class="navbar-nav"> 146 <li class="nav-item d-lg-flex"> 147 <a class="nav-link" href="#" title="Sign in" data-bs-toggle="modal" data-bs-target="#nav-login"> 148 Login 149 </a> 150 </li> 151 </ul> 152 153 <div class="navbar-text navbar-banner">Farthinghale Arms</div> 154 155 <ul id="nav-right" class="navbar-nav"> 156 <li class="nav-item collapse clearfix" id="nav-search" data-bs-theme="light"> 157 <form class="form-inline" method="get" action="search" role="search"> 158 <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');"/> 159 </form> 160 <div id="nav-search-spinner" class="spinner-wrapper"> 161 <div class="spinner s"></div> 162 </div> 163 </li> 164 <li class="nav-item" id="nav-search-btn"> 165 <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> 166 </li> 167 <li class="nav-item dropdown" id="app-menu"> 168 <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> 169 </li> 170 </ul> 171 </div> 172 </div> 173</nav> 174<div class="offcanvas offcanvas-end" tabindex="-1" id="app-bin" aria-labelledby="app-bin-label"> 175 <div class="offcanvas-header"> 176 177 <div class="hstack gap-1 d-lg-none pt-1 pb-1"> 178 <a class="btn btn-primary btn-sm text-white" href="#" title="Sign in" data-bs-toggle="modal" data-bs-target="#nav-login"> 179 Login 180 </a> 181 182 </div> 183 <div class="nav d-lg-flex w-100"></div> 184 <div class="hstack gap-1"> 185 <button id="theme-switch" type="button" class="btn btn-outline-secondary border-0"><i id="theme-switch-icon" class="bi bi-moon"></i></button> 186 <button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button> 187 </div> 188 189 </div> 190 <div class="offcanvas-body"> 191 <div class="text-uppercase text-muted nav-link"> 192 System Apps 193 </div> 194 <div class="nav nav-pills flex-column"> 195 <a class="nav-link active" href="https://hub.farthinghalearms.com/directory" data-papp="eyJ2ZXJzaW9uIjoiNCIsInVybCI6IiRiYXNldXJsXC9kaXJlY3RvcnksICRiYXNldXJsXC9z 196ZXR0aW5nc1wvZGlyZWN0b3J5IiwibmFtZSI6IkRpcmVjdG9yeSIsInBob3RvIjoiaWNvbjpk 197aWFncmFtLTMiLCJjYXRlZ29yaWVzIjoibmF2X2ZlYXR1cmVkX2FwcCwgTmV0d29ya2luZyIs 198ImRlc2MiOiJNZW1iZXJzIGRpcmVjdG9yeSBvZiB0aGUgWm90IG5ldHdvcmsuIiwidHlwZSI6 199InN5c3RlbSIsInBsdWdpbiI6IiIsImFjdGl2ZSI6dHJ1ZX0= 200" 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> 201 202 <a class="nav-link" href="https://hub.farthinghalearms.com/help" data-papp="eyJ2ZXJzaW9uIjoiNCIsInVybCI6IiRiYXNldXJsXC9oZWxwIiwibmFtZSI6IkhlbHAiLCJw 203aG90byI6Imljb246cXVlc3Rpb24tbGciLCJjYXRlZ29yaWVzIjoibmF2X2ZlYXR1cmVkX2Fw 204cCwgU3lzdGVtIiwiZGVzYyI6IlRoZSBIdWJ6aWxsYSBoZWxwIHBhZ2VzLiIsInR5cGUiOiJz 205eXN0ZW0iLCJwbHVnaW4iOiIifQ== 206" 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> 207 208 <a class="nav-link" href="https://hub.farthinghalearms.com/lang" data-papp="eyJ2ZXJzaW9uIjoiNCIsInVybCI6IiRiYXNldXJsXC9sYW5nIiwibmFtZSI6Ikxhbmd1YWdl 209IiwicGhvdG8iOiJpY29uOnRyYW5zbGF0ZSIsImNhdGVnb3JpZXMiOiJTeXN0ZW0iLCJkZXNj 210IjoiQSBzaW1wbGUgbGFuZ3VhZ2Ugc2VsZWN0b3IuIiwidHlwZSI6InN5c3RlbSIsInBsdWdp 211biI6IiJ9 212" data-icon="translate" data-url="https://hub.farthinghalearms.com/lang" data-name="Language"><i class="generic-icons-nav bi bi-translate"></i>Language</a> 213 214 <a class="nav-link" href="https://hub.farthinghalearms.com/randprof" data-papp="eyJ2ZXJzaW9uIjoiNCIsInVybCI6IiRiYXNldXJsXC9yYW5kcHJvZiIsIm5hbWUiOiJSYW5k 215b20gQ2hhbm5lbCIsInRhcmdldCI6InJhbmRwcm9mIiwicGhvdG8iOiJpY29uOnNodWZmbGUi
216LCJjYXRlZ29yaWVzIjoiTmV0d29ya2luZyIsImRlc2MiOiJWaXNpdCBhIHJhbmRvbSBjaGFu 217bmVsIGluIHRoZSBuZXR3b3JrLiIsInR5cGUiOiJzeXN0ZW0iLCJwbHVnaW4iOiIifQ== 218" 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> 219 220 <a class="nav-link" href="https://framagit.org/hubzilla/core/issues" data-papp="eyJ2ZXJzaW9uIjoiMyIsInVybCI6Imh0dHBzOlwvXC9mcmFtYWdpdC5vcmdcL2h1YnppbGxh 221XC9jb3JlXC9pc3N1ZXMiLCJuYW1lIjoiUmVwb3J0IEJ1ZyIsInBob3RvIjoiaWNvbjpidWci 222LCJjYXRlZ29yaWVzIjoiU3lzdGVtIiwiZGVzYyI6IlByb3ZpZGVzIGEgbGluayB0byB0aGUg 223SHViemlsbGEgYnVnIHRyYWNrZXIuIiwidHlwZSI6InN5c3RlbSIsInBsdWdpbiI6IiJ9 224" 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> 225 226 <a class="nav-link" href="https://hub.farthinghalearms.com/search" data-papp="eyJ2ZXJzaW9uIjoiMyIsInVybCI6IiRiYXNldXJsXC9zZWFyY2giLCJuYW1lIjoiU2VhcmNo 227IiwicGhvdG8iOiJpY29uOnNlYXJjaCIsImRlc2MiOiJBIHNlcGFyYXRlIHNlYXJjaCBhcHAg 228dG8gbG9vayB1cCBjb250ZW50LCBjaGFubmVscywgdGFncywgZG9jdW1lbnRhdGlvbiBvciBy 229ZW1vdGUgY29udGVudCBkZXBlbmRpbmcgb24gdGhlIHNlYXJjaCBzdHJpbmcgcHJlZml4LiIs 230InR5cGUiOiJzeXN0ZW0iLCJwbHVnaW4iOiIifQ== 231" data-icon="search" data-url="https://hub.farthinghalearms.com/search" data-name="Search"><i class="generic-icons-nav bi bi-search"></i>Search</a> 232 233 </div> 234 </div> 235</div> 236 <main> 237 <div class="content"> 238 <div class="columns"> 239 <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"> 240<div id="peoplefind-sidebar" class="widget"> 241 <h3>Find Channels</h3> 242 <form action="directory" method="post" /> 243 <div class="input-group mb-3"> 244 <input class="form-control" type="text" name="search" title="Examples: Robert Morgenstein, Fishing" placeholder="Enter name or interest" /> 245 <button class="btn btn-outline-secondary" type="submit" name="submit"><i class="bi bi-search"></i></button> 246 </div> 247 </form> 248 <ul class="nav nav-pills flex-column"> 249 <li class="nav-item"><a class="nav-link" href="randprof" >Random Profile</a></li> 250 </ul> 251</div> 252 253<div class="widget" id="dir_sort_links"> 254<h3>Directory Options</h3> 255 256 <div id="safemode_container" class="clearfix onoffswitch checkbox mb-3"> 257 <label for="id_safemode">Safe Mode</label> 258 <div class="float-end"><input type="checkbox" name="safemode" id="id_safemode" value="1" checked="checked" onchange='window.location.href="directory?f=&safe="+(this.checked ? 1 : 0)' ><label class="switchlabel" for='id_safemode'> <span class="onoffswitch-inner" data-on='Yes' data-off='No'></span><span class="onoffswitch-switch"></span></label></div> 259 <small class="form-text text-muted"></small> 260 </div> 261 <div id="globaldir_container" class="clearfix onoffswitch checkbox mb-3"> 262 <label for="id_globaldir">This Website Only</label> 263 <div class="float-end"><input type="checkbox" name="globaldir" id="id_globaldir" value="1" checked="checked" onchange='window.location.href="directory?f=&global="+(this.checked ? 0 : 1)' ><label class="switchlabel" for='id_globaldir'> <span class="onoffswitch-inner" data-on='Yes' data-off='No'></span><span class="onoffswitch-switch"></span></label></div> 264 <small class="form-text text-muted"></small> 265 </div> 266 <div id="pubforums_container" class="clearfix onoffswitch checkbox mb-3"> 267 <label for="id_pubforums">Public Forums Only</label> 268 <div class="float-end"><input type="checkbox" name="pubforums" id="id_pubforums" value="1" onchange='window.location.href="directory?f=&pubforums="+(this.checked ? 1 : 0)' ><label class="switchlabel" for='id_pubforums'> <span class="onoffswitch-inner" data-on='Yes' data-off='No'></span><span class="onoffswitch-switch"></span></label></div> 269 <small class="form-text text-muted"></small> 270 </div> 271 272</div> 273 274<div class="dirtagblock widget"> 275 <h3>Keywords</h3> 276 <div class="tags text-center"> 277 <span class="tag tag5">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=3D-Printing" class="tag tag5" rel="nofollow">3D-Printing</a> 278 <span class="tag tag5">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=3dprinting" class="tag tag5" rel="nofollow">3dprinting</a> 279 <span class="tag tag8">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=Azure" class="tag tag8" rel="nofollow">Azure</a> 280 <span class="tag tag5">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=blender" class="tag tag5" rel="nofollow">blender</a> 281 <span class="tag tag1">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=Debian" class="tag tag1" rel="nofollow">Debian</a> 282 <span class="tag tag1">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=developer" class="tag tag1" rel="nofollow">developer</a> 283 <span class="tag tag1">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=diy" class="tag tag1" rel="nofollow">diy</a> 284 <span class="tag tag5">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=fantasy" class="tag tag5" rel="nofollow">fantasy</a> 285 <span class="tag tag1">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=free" class="tag tag1" rel="nofollow">free</a> 286 <span class="tag tag5">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=gaming" class="tag tag5" rel="nofollow">gaming</a> 287 <span class="tag tag5">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=godot" class="tag tag5" rel="nofollow">godot</a> 288 <span class="tag tag8">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=hubzilla" class="tag tag8" rel="nofollow">hubzilla</a> 289 <span class="tag tag8">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=linux" class="tag tag8" rel="nofollow">linux</a> 290 <span class="tag tag5">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=lovecraft" class="tag tag5" rel="nofollow">lovecraft</a> 291 <span class="tag tag5">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=NASA" class="tag tag5" rel="nofollow">NASA</a> 292 <span class="tag tag8">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=nextcloud" class="tag tag8" rel="nofollow">nextcloud</a> 293 <span class="tag tag9">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=rocketry" class="tag tag9" rel="nofollow">rocketry</a> 294 <span class="tag tag5">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=rust" class="tag tag5" rel="nofollow">rust</a> 295 <span class="tag tag8">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=skeeball" class="tag tag8" rel="nofollow">skeeball</a> 296 <span class="tag tag1">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=software" class="tag tag1" rel="nofollow">software</a> 297 <span class="tag tag5">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=space" class="tag tag5" rel="nofollow">space</a> 298 <span class="tag tag8">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=sql" class="tag tag8" rel="nofollow">sql</a> 299 <span class="tag tag5">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=STEM" class="tag tag5" rel="nofollow">STEM</a> 300 <span class="tag tag1">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=web" class="tag tag1" rel="nofollow">web</a> 301 <span class="tag tag8">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=windows" class="tag tag8" rel="nofollow">windows</a> 302 <span class="tag tag1">#</span><a href="https://hub.farthinghalearms.com/directory/?f=&keywords=writer" class="tag tag1" rel="nofollow">writer</a> 303 </div> 304</div> 305 306 307 308</div></div></aside> 309 <section id="region_2">
310<script> var page_query = 'directory'; var extra_args = '' ; divmore_height = 94; </script>
310<div class="generic-content-wrapper"> 311 <div class="section-title-wrapper clearfix"> 312 <div class="btn-group float-end"> 313 <button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="Sort options"> 314 <i class="bi bi-arrow-down-up"></i> 315 </button> 316 <div class="dropdown-menu dropdown-menu-end"> 317 <a class="dropdown-item" href="directory?f=&order=date">Newest to Oldest</a> 318 <a class="dropdown-item" href="directory?f=&order=normal">Alphabetic</a> 319 <a class="dropdown-item" href="directory?f=&order=reversedate">Oldest to Newest</a> 320 <a class="dropdown-item" href="directory?f=&order=reverse">Reverse Alphabetic</a> 321 </div> 322 </div> 323 <h2>Local Directory</h2> 324 </div> 325 <div class="directory-item safe" id="directory-item-5-EPE0GFQjdTpIMAiP2acx44f5Frdq7dPhUxMX2N9mugD1MdSf2rYxXK5w42rQx3xKcyEvv48nQCItTtcV4ftQ" > 326 <div class="section-subtitle-wrapper clearfix"> 327 <div class="directory-actions float-end"> 328 </div> 329 <h3><a href='https://hub.farthinghalearms.com/chanview?f=&url=https%3A%2F%2Fhub.farthinghalearms.com%2Fchannel%2Fdwatney' >Marshall Sutherland</a></h3> 330 </div> 331 <div class="section-content-tools-wrapper directory-collapse"> 332 <div class="contact-photo-wrapper" id="directory-photo-wrapper-5-EPE0GFQjdTpIMAiP2acx44f5Frdq7dPhUxMX2N9mugD1MdSf2rYxXK5w42rQx3xKcyEvv48nQCItTtcV4ftQ" > 333 <div class="contact-photo" id="directory-photo-5-EPE0GFQjdTpIMAiP2acx44f5Frdq7dPhUxMX2N9mugD1MdSf2rYxXK5w42rQx3xKcyEvv48nQCItTtcV4ftQ" > 334 <a href="https://hub.farthinghalearms.com/chanview?f=&url=https%3A%2F%2Fhub.farthinghalearms.com%2Fchannel%2Fdwatney" class="directory-profile-link" id="directory-profile-link-5-EPE0GFQjdTpIMAiP2acx44f5Frdq7dPhUxMX2N9mugD1MdSf2rYxXK5w42rQx3xKcyEvv48nQCItTtcV4ftQ" > 335 <img class="directory-photo-img" src="https://hub.netzgemeinde.eu/photo/fd2a81c7-d05d-4f25-b13a-acccf6208668-5" alt="Marshall Sutherland" title="Marshall Sutherland" loading="lazy"/> 336 </a> 337 </div> 338 </div> 339 <div class="contact-info"> 340 341 342 343 <div class="contact-info-element"> 344 <span class="contact-info-label">Location:</span> USA 345 </div> 346 347 348 349 <div class="contact-info-element"> 350 <span class="contact-info-label">Keywords: </span> <a href="https://hub.farthinghalearms.com/directory/f=&keywords=hubzilla">hubzilla</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=nextcloud">nextcloud</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=sql">sql</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=windows">windows</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=linux">linux</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=Azure">Azure</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=skeeball">skeeball</a> 351 </div> 352 353 </div> 354 </div> 355</div> 356 <div class="directory-item safe" id="directory-item-J5j9BpfSWLreT1xi6ew9vJYzrs-MkjV00OrnGi73aTkQVThmdC-cXJxVzLVPcOmVYa4RUUeiwSfIuixb6_h0hQ" > 357 <div class="section-subtitle-wrapper clearfix"> 358 <div class="directory-actions float-end"> 359 </div> 360 <h3><a href='https://hub.farthinghalearms.com/chanview?f=&url=https%3A%2F%2Fhub.farthinghalearms.com%2Fchannel%2Fjoco' >JoCo Cruise</a></h3> 361 </div> 362 <div class="section-content-tools-wrapper directory-collapse"> 363 <div class="contact-photo-wrapper" id="directory-photo-wrapper-J5j9BpfSWLreT1xi6ew9vJYzrs-MkjV00OrnGi73aTkQVThmdC-cXJxVzLVPcOmVYa4RUUeiwSfIuixb6_h0hQ" > 364 <div class="contact-photo" id="directory-photo-J5j9BpfSWLreT1xi6ew9vJYzrs-MkjV00OrnGi73aTkQVThmdC-cXJxVzLVPcOmVYa4RUUeiwSfIuixb6_h0hQ" > 365 <a href="https://hub.farthinghalearms.com/chanview?f=&url=https%3A%2F%2Fhub.farthinghalearms.com%2Fchannel%2Fjoco" class="directory-profile-link" id="directory-profile-link-J5j9BpfSWLreT1xi6ew9vJYzrs-MkjV00OrnGi73aTkQVThmdC-cXJxVzLVPcOmVYa4RUUeiwSfIuixb6_h0hQ" > 366 <img class="directory-photo-img" src="https://hub.netzgemeinde.eu/photo/7732d80d-8bc8-415c-a88f-ce3994f393f9-5" alt="JoCo Cruise" title="JoCo Cruise" loading="lazy"/> 367 </a> 368 </div> 369 </div> 370 <div class="contact-info"> 371 372 <div class="contact-info-element"> 373 <span class="contact-info-label">Description:</span> Stuff about being on JoCo Cruise<br /> 374 </div> 375 376 377 378 379 380 381 <div class="contact-info-element"> 382 <span class="contact-info-label">About:</span> A secondary channel for Marshall Sutherland 383 </div> 384 </div> 385 </div> 386</div> 387 <div class="directory-item safe" id="directory-item-t37G-c17mSFgbmiAveOdEVHXeGvI0kV0xs8KuEr0rdaVF0CNUza_Fd2QgERtU0VfcnaaH3-JZ0MQBqqSEwNQxQ" > 388 <div class="section-subtitle-wrapper clearfix"> 389 <div class="directory-actions float-end"> 390 </div> 391 <h3><a href='https://hub.farthinghalearms.com/chanview?f=&url=https%3A%2F%2Fhub.inktada.com%2Fchannel%2Finsanerocketry' >Insane Rocketry</a></h3> 392 </div> 393 <div class="section-content-tools-wrapper directory-collapse"> 394 <div class="contact-photo-wrapper" id="directory-photo-wrapper-t37G-c17mSFgbmiAveOdEVHXeGvI0kV0xs8KuEr0rdaVF0CNUza_Fd2QgERtU0VfcnaaH3-JZ0MQBqqSEwNQxQ" > 395 <div class="contact-photo" id="directory-photo-t37G-c17mSFgbmiAveOdEVHXeGvI0kV0xs8KuEr0rdaVF0CNUza_Fd2QgERtU0VfcnaaH3-JZ0MQBqqSEwNQxQ" > 396 <a href="https://hub.farthinghalearms.com/chanview?f=&url=https%3A%2F%2Fhub.inktada.com%2Fchannel%2Finsanerocketry" class="directory-profile-link" id="directory-profile-link-t37G-c17mSFgbmiAveOdEVHXeGvI0kV0xs8KuEr0rdaVF0CNUza_Fd2QgERtU0VfcnaaH3-JZ0MQBqqSEwNQxQ" > 397 <img class="directory-photo-img" src="https://hub.netzgemeinde.eu/photo/89905a7c-51f9-4a62-ae31-2a3a36f570e4-5" alt="Insane Rocketry" title="Insane Rocketry" loading="lazy"/> 398 </a> 399 </div> 400 </div> 401 <div class="contact-info"> 402 403 404 405 406 407 <div class="contact-info-element"> 408 <span class="contact-info-label">Homepage: </span> https://www.insanerocketry.com 409 </div> 410 411 <div class="contact-info-element"> 412 <span class="contact-info-label">Keywords: </span> <a href="https://hub.farthinghalearms.com/directory/f=&keywords=rocketry">rocketry</a> 413 </div> 414 415 <div class="contact-info-element"> 416 <span class="contact-info-label">About:</span> Insane Rocketry is one stop for: Rocket Flight Logging including Images, Video, & data files; Kit lookup; Optional Tracking and telemetry data phone app. 417 </div> 418 </div> 419 </div> 420</div> 421 <div class="directory-item safe" id="directory-item-G3Q2dTWAw3H8oxYZRq5WTWhG8EOSheN-aAzrbb28-r8YNQEHFYZ-uZBei5MwI_JXFvNrIlPvSVDZCKUX9cuuJw" > 422 <div class="section-subtitle-wrapper clearfix"> 423 <div class="directory-actions float-end"> 424 </div> 425 <h3><a href='https://hub.farthinghalearms.com/chanview?f=&url=https%3A%2F%2Fhub.inktada.com%2Fchannel%2Fjason' >Jason Cook</a></h3> 426 </div> 427 <div class="section-content-tools-wrapper directory-collapse"> 428 <div class="contact-photo-wrapper" id="directory-photo-wrapper-G3Q2dTWAw3H8oxYZRq5WTWhG8EOSheN-aAzrbb28-r8YNQEHFYZ-uZBei5MwI_JXFvNrIlPvSVDZCKUX9cuuJw" > 429 <div class="contact-photo" id="directory-photo-G3Q2dTWAw3H8oxYZRq5WTWhG8EOSheN-aAzrbb28-r8YNQEHFYZ-uZBei5MwI_JXFvNrIlPvSVDZCKUX9cuuJw" > 430 <a href="https://hub.farthinghalearms.com/chanview?f=&url=https%3A%2F%2Fhub.inktada.com%2Fchannel%2Fjason" class="directory-profile-link" id="directory-profile-link-G3Q2dTWAw3H8oxYZRq5WTWhG8EOSheN-aAzrbb28-r8YNQEHFYZ-uZBei5MwI_JXFvNrIlPvSVDZCKUX9cuuJw" > 431 <img class="directory-photo-img" src="https://hub.netzgemeinde.eu/photo/909d67f3-78fe-4423-9abb-a8850fea0292-5" alt="Jason Cook" title="Jason Cook" loading="lazy"/> 432 </a> 433 </div> 434 </div> 435 <div class="contact-info"> 436 437 438 439 <div class="contact-info-element"> 440 <span class="contact-info-label">Location:</span> FL, United States 441 </div> 442 443 444 <div class="contact-info-element"> 445 <span class="contact-info-label">Homepage: </span> https://www.insanerocketry.com 446 </div> 447 448 <div class="contact-info-element"> 449 <span class="contact-info-label">Keywords: </span> <a href="https://hub.farthinghalearms.com/directory/f=&keywords=rocketry">rocketry</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=space">space</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=STEM">STEM</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=NASA">NASA</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=3dprinting">3dprinting</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=3D-Printing">3D-Printing</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=blender">blender</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=fantasy">fantasy</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=lovecraft">lovecraft</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=rust">rust</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=godot">godot</a>, <a href="https://hub.farthinghalearms.com/directory/f=&keywords=gaming">gaming</a> 450 </div> 451 452 </div> 453 </div> 454</div> 455 <div class="directory-item safe" id="directory-item-5C4CiTOjT8ptNMlaF
455aVRFqgZV2VolM1OzY-JFJryhWBhe27fpYHt4cFAf1jI5C2GBzj5JI1TcxrmqG7pSgTR5w" > 456 <div class="section-subtitle-wrapper clearfix"> 457 <div class="directory-actions float-end"> 458 </div> 459 <h3><a href='https://hub.farthinghalearms.com/chanview?f=&url=https%3A%2F%2Fhub.farthinghalearms.com%2Fchannel%2Fkdedwards' >K. Dwayne Edwards</a></h3> 460 </div> 461 <div class="section-content-tools-wrapper directory-collapse"> 462 <div class="contact-photo-wrapper" id="directory-photo-wrapper-5C4CiTOjT8ptNMlaFaVRFqgZV2VolM1OzY-JFJryhWBhe27fpYHt4cFAf1jI5C2GBzj5JI1TcxrmqG7pSgTR5w" > 463 <div class="contact-photo" id="directory-photo-5C4CiTOjT8ptNMlaFaVRFqgZV2VolM1OzY-JFJryhWBhe27fpYHt4cFAf1jI5C2GBzj5JI1TcxrmqG7pSgTR5w" > 464 <a href="https://hub.farthinghalearms.com/chanview?f=&url=https%3A%2F%2Fhub.farthinghalearms.com%2Fchannel%2Fkdedwards" class="directory-profile-link" id="directory-profile-link-5C4CiTOjT8ptNMlaFaVRFqgZV2VolM1OzY-JFJryhWBhe27fpYHt4cFAf1jI5C2GBzj5JI1TcxrmqG7pSgTR5w" > 465 <img class="directory-photo-img" src="https://hub.netzgemeinde.eu/photo/ad3ce9f0-c489-42c9-9ead-f446dc5866a7-5" alt="K. Dwayne Edwards" title="K. Dwayne Edwards" loading="lazy"/> 466 </a> 467 </div> 468 </div> 469 <div class="contact-info"> 470 471 472 <div class="contact-info-element"> 473 <span class="contact-info-label">Age:</span> 48 474 </div> 475 476 477 478 479 480 </div> 481 </div> 482</div> 483 <div id="page-end" class="float-start w-100"></div> 484</div> 485<div id="page-spinner" class="spinner-wrapper"> 486 <div class="spinner m"></div> 487</div>
488<script> 489 $(document).ready(function() { 490 loadingPage = false; 491 }); 492</script>
492 493<div id="nav-login" class="modal" tabindex="-1" role="dialog"> 494 <div class="modal-dialog" role="document"> 495 <div class="modal-content"> 496 <div class="modal-header"> 497 <h4 class="modal-title">Login</h4> 498 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 499 </div> 500 <div class="modal-body"> 501 <div class="mb-3"> 502 <form action="https://hub.farthinghalearms.com/directory" id="modal_login" method="post" > 503 <input type="hidden" name="auth-params" value="login" /> 504 <div> 505 <div id="id_modal_login_username_wrapper" class="mb-3"> 506 <label for="id_modal_login_username" id="label_modal_login_username"> 507 Nickname </label> 508 <input 509 class="form-control" 510 name="modal_login_username" 511 id="id_modal_login_username" 512 type="text" 513 value="" 514 > 515 <small id="help_modal_login_username" class="form-text text-muted"> 516 517 </small> 518 </div> 519 <div class="mb-3"> 520 <label for="id_modal_login_password">Password</label> 521 <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> 522 </div> 523 <div id="modal_login_remember_container" class="clearfix onoffswitch checkbox mb-3"> 524 <label for="id_modal_login_remember">Remember me</label> 525 <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> 526 <small class="form-text text-muted"></small> 527 </div> 528 <button type="submit" name="submit" class="btn btn-primary">Login</button> 529 <hr> 530 <a href="rmagic" class="btn btn-outline-success">Remote Authentication</a> 531 <a href="https://hub.farthinghalearms.com/pubsites" title="Create an account to access services and applications" class="register-link float-end">Register</a> 532 </div> 533 <input type="hidden" name="0" value="" /> 534 </form> 535 536 </div> 537 </div> 538 </div> 539 </div> 540</div> 541 542 <div id="page-footer"></div> 543 <div id="pause"></div> 544 </section> 545 <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">
546<script> 547 var sse_bs_active = false; 548 var sse_offset = 0; 549 var sse_type; 550 var sse_partial_result = false; 551 var sse_rmids = []; 552 var sse_fallback_interval; 553 var sse_sys_only = 0; 554 555 document.addEventListener("DOMContentLoaded", function() { 556 let notificationsWrapper = document.getElementById('notifications_wrapper'); 557 let notificationsParent = notificationsWrapper ? notificationsWrapper.parentElement.id : null; 558 let notificationsBtn = document.querySelectorAll('.notifications-btn'); 559 560 // Event listener for notifications button 561 if (notificationsBtn) { 562 notificationsBtn.forEach(function (element) { 563 element.addEventListener('click', function(e) { 564 e.preventDefault(); 565 e.stopPropagation(); 566 567 // Remove the 'd-none' class to show the notifications wrapper 568 notificationsWrapper.classList.remove('d-none'); 569 570 // Check if the notifications wrapper has the 'fs' class 571 if (notificationsWrapper.classList.contains('fs')) { 572 // Prepend the notifications wrapper back to its original parent and hide it 573 document.getElementById(notificationsParent).appendChild(notificationsWrapper); 574 notificationsWrapper.classList.add('d-none'); 575 } else { 576 // Otherwise, prepend the notifications wrapper to 'main' 577 document.querySelector('main').prepend(notificationsWrapper); 578 } 579 580 // Toggle the 'fs' class 581 notificationsWrapper.classList.toggle('fs'); 582 }); 583 }); 584 } 585 586 // Event listener for clicking a notification 587 document.addEventListener('click', function(event) { 588 if (event.target.closest('a') && event.target.closest('a').classList.contains('notification')) { 589 if (notificationsWrapper.classList.contains('fs')) { 590 // Move notifications wrapper back to its original parent and hide it 591 notificationsWrapper.classList.remove('fs'); 592 notificationsWrapper.classList.add('d-none'); 593 document.getElementById(notificationsParent).appendChild(notificationsWrapper); 594 595 } 596 } 597 }); 598 599 if(sse_enabled) { 600 if(typeof(window.SharedWorker) === 'undefined') { 601 // notifications with multiple tabs open will not work very well in this scenario 602 let evtSource = new EventSource('/sse'); 603 604 evtSource.addEventListener('notifications', function(e) { 605 let obj = JSON.parse(e.data); 606 sse_handleNotifications(obj, false, false); 607 }, false); 608 609 document.addEventListener('visibilitychange', function() { 610 if (!document.hidden) { 611 sse_offset = 0; 612 sse_bs_init(); 613 } 614 }, false); 615 616 } 617 else { 618 let myWorker = new SharedWorker('/view/js/sse_worker.js', localUser); 619 620 myWorker.port.onmessage = function(e) { 621 obj = e.data; 622 console.log(obj); 623 sse_handleNotifications(obj, false, false); 624 } 625 626 myWorker.onerror = function(e) { 627 myWorker.port.close(); 628 } 629 630 myWorker.port.start(); 631 } 632 } 633 else { 634 if (!document.hidden) { 635 sse_fallback(); 636 sse_fallback_interval = setInterval(sse_fallback, updateInterval); 637 } 638 639 document.addEventListener('visibilitychange', function() { 640 if (document.hidden) { 641 clearInterval(sse_fallback_interval); 642 } 643 else { 644 sse_offset = 0; 645 sse_bs_init(); 646 sse_fallback_interval = setInterval(sse_fallback, updateInterval); 647 } 648 649 }, false); 650 } 651 652 document.querySelectorAll('.notification-link').forEach(function (element) { 653 element.addEventListener('click', function (element) { 654 sse_bs_notifications(element, true, false); 655 }); 656 }); 657 658 document.querySelectorAll('.notification-filter').forEach(function (element) { 659 element.addEventListener('keypress', function(e) { 660 if (e.which == 13) { // Enter key 661 this.blur(); 662 sse_offset = 0; 663 664 // Clear the content of the menu 665 document.getElementById("nav-" + sse_type + "-menu").innerHTML = ''; 666 667 // Show the loading element 668 document.getElementById("nav-" + sse_type + "-loading").style.display = 'block'; 669 670 // Get the value from the input element 671 var cn_val = document.getElementById('cn-' + sse_type + '-input') ? document.getElementById('cn-' + sse_type + '-input').value.toString().toLowerCase() : ''; 672 673 // Send a GET request using the Fetch API 674 fetch('/sse_bs/' + sse_type + '/' + sse_offset + '?nquery=' + encodeURIComponent(cn_val)) 675 .then(response => response.json()) 676 .then(obj => { 677 console.log('sse: bootstraping ' + sse_type); 678 console.log(obj); 679 680 sse_bs_active = false;
681 sse_partial_result = true; 682 sse_offset = obj[sse_type].offset; 683 684 if (sse_offset < 0) { 685 document.getElementById("nav-" + sse_type + "-loading").style.display = 'none'; 686 } 687 688 sse_handleNotifications(obj, true, false); 689 }) 690 .catch(error => { 691 console.error('Error fetching data:', error); 692 }); 693 } 694 }); 695 }); 696 697 document.querySelectorAll('.notifications-textinput-clear').forEach(function (element) { 698 element.addEventListener('click', function(e) { 699 if (!sse_partial_result) return; 700 701 // Clear the content of the menu 702 document.getElementById("nav-" + sse_type + "-menu").innerHTML = ''; 703 704 // Show the loading element 705 document.getElementById("nav-" + sse_type + "-loading").style.display = 'block'; 706 707 // Send a GET request using the Fetch API 708 fetch('/sse_bs/' + sse_type) 709 .then(response => response.json()) 710 .then(obj => { 711 console.log('sse: bootstraping ' + sse_type); 712 console.log(obj); 713 714 sse_bs_active = false; 715 sse_partial_result = false;
716 sse_offset = obj[sse_type].offset; 717 if (sse_offset < 0) { 718 document.getElementById("nav-" + sse_type + "-loading").style.display = 'none'; 719 } 720 721 sse_handleNotifications(obj, true, false); 722 }) 723 .catch(error => { 724 console.error('Error fetching data:', error); 725 }); 726 }); 727 }); 728 729 document.querySelectorAll('.notification-content').forEach(function(element) { 730 element.addEventListener('scroll', function() { 731 if (this.scrollTop > this.scrollHeight - this.clientHeight - (this.scrollHeight / 7)) { 732 sse_bs_notifications(sse_type, false, true); 733 } 734 }); 735 }); 736 737 738 }); 739 740 document.addEventListener('hz:sse_setNotificationsStatus', function(e) { 741 sse_setNotificationsStatus(e.detail); 742 }); 743 744 document.addEventListener('hz:sse_bs_init', function() { 745 sse_bs_init(); 746 }); 747 748 document.addEventListener('hz:sse_bs_counts', function() { 749 sse_bs_counts(); 750 }); 751 752 753 function sse_bs_init() { 754 // Check if 'notification_open' exists in sessionStorage or if sse_type is defined 755 if (sessionStorage.getItem('notification_open') !== null || typeof sse_type !== 'undefined') { 756 if (typeof sse_type === 'undefined') { 757 sse_type = sessionStorage.getItem('notification_open'); 758 } 759 760 // Add the 'show' class to the appropriate element 761 let subNav = document.getElementById("nav-" + sse_type + "-sub"); 762 if (subNav) { 763 subNav.classList.add('show'); 764 } 765 766 // Call the sse_bs_notifications function 767 sse_bs_notifications(sse_type, true, false); 768 } else { 769 // Call the sse_bs_counts function if conditions are not met 770 sse_bs_counts(); 771 } 772 } 773 774 function sse_bs_counts() { 775 if (sse_bs_active || sse_sys_only) { 776 return; 777 } 778 779 sse_bs_active = true; 780 781 // Use the fetch API to send the POST request with the data 782 fetch('/sse_bs', { 783 method: 'POST', 784 body: new URLSearchParams({sse_rmids: sse_rmids}) 785 }) 786 .then(response => response.json()) // Parse the JSON response 787 .then(obj => { 788 console.log(obj); 789 sse_bs_active = false; 790 sse_rmids = []; 791 sse_handleNotifications(obj, true, false); 792 }) 793 .catch(error => { 794 console.error('Error:', error); 795 sse_bs_active = false; 796 }); 797 } 798 799 function sse_bs_notifications(e, replace, followup) { 800 if (sse_bs_active || sse_sys_only) { 801 return; 802 } 803 804 let manual = false; 805 806 if (typeof replace === 'undefined') { 807 replace = e.data.replace; 808 } 809 810 if (typeof followup === 'undefined') { 811 followup = e.data.followup; 812 } 813 814 if (typeof e === 'string') { 815 sse_type = e; 816 } else { 817 manual = true; 818 sse_offset = 0; 819 sse_type = e.target.dataset.sse_type; 820 } 821 822 if (typeof sse_type === 'undefined') { 823 return; 824 } 825 826 if (followup || !manual || !document.getElementById('notification-link-' + sse_type).classList.contains('collapsed')) { 827 828 if (sse_offset >= 0) { 829 document.getElementById("nav-" + sse_type + "-loading").style.display = 'block'; 830 } 831 832 sessionStorage.setItem('notification_open', sse_type); 833 834 if (sse_offset !== -1 || replace) { 835 let cn_val = (document.getElementById('cn-' + sse_type + '-input') && sse_partial_result) 836 ? document.getElementById('cn-' + sse_type + '-input').value.toString().toLowerCase() 837 : ''; 838 839 document.getElementById("nav-" + sse_type + "-loading").style.display = 'block'; 840 841 sse_bs_active = true; 842 843 // Send POST request using fetch API 844 fetch('/sse_bs/' + sse_type + '/' + sse_offset, { 845 method: 'POST', 846 body: new URLSearchParams({ 847 sse_rmids: sse_rmids, 848 nquery: encodeURIComponent(cn_val) 849 }) 850 }) 851 .then(response => response.json()) // Parse the JSON response 852 .then(obj => { 853 console.log('sse: bootstraping ' + sse_type); 854 console.log(obj); 855 sse_bs_active = false; 856 sse_rmids = []; 857 document.getElementById("nav-" + sse_type + "-loading").style.display = 'none'; 858 859 if (typeof obj[sse_type] !== 'undefined') { 860 sse_offset = obj[sse_type].offset; 861 } 862 863 sse_handleNotifications(obj, replace, followup); 864 }) 865 .catch(error => { 866 console.error('Error:', error); 867 sse_bs_active = false; 868 }); 869 } else { 870 document.getElementById("nav-" + sse_type + "-loading").style.display = 'none'; 871 } 872 } else { 873 sessionStorage.removeItem('notification_open'); 874 } 875 } 876 877 function sse_handleNotifications(obj, replace, followup) { 878 879 // Notice and info notifications 880 if (obj.notice) {
881 obj.notice.notifications.forEach(notification => { 882 toast(notification, 'danger'); 883 }); 884 } 885 886 if (obj.info) { 887 obj.info.notifications.forEach(notification => { 888 toast(notification, 'info'); 889 }); 890 } 891 892 if (sse_sys_only) { 893 return; 894 } 895 896 let all_notifications = Object.keys(obj); 897 898 all_notifications.forEach(type => { 899 if (typeof obj[type] === 'undefined') { 900 return; 901 } 902 903 let count = Number(obj[type].count); 904 905 // Show notifications and update count 906 let updateElement = document.querySelector('.' + type + '-update'); 907 let buttonElement = document.querySelector('.' + type + '-button'); 908 let subElement = document.getElementById('nav-' + type + '-sub'); 909 910 if (count) { 911 if (buttonElement) buttonElement.style.display = 'block'; // Fade-in effect replaced by display block 912 if (replace || followup) { 913 updateElement.textContent = count >= 100 ? '99+' : count; 914 } else { 915 count = count + Number(updateElement.textContent.replace(/\++$/, '')); 916 updateElement.textContent = count >= 100 ? '99+' : count; 917 } 918 } else { 919 if (updateElement) updateElement.textContent = '0'; 920 if (subElement) subElement.classList.remove('show'); 921 if (buttonElement) { 922 buttonElement.style.display = 'none'; // Fade-out effect replaced by display none 923 sse_setNotificationsStatus(null); 924 } 925 } 926 927 if (obj[type].notifications.length) { 928 sse_handleNotificationsItems(type, obj[type].notifications, replace, followup); 929 } 930 }); 931 932 sse_setNotificationsStatus(null); 933 934 if (typeof obj[sse_type] !== 'undefined') { 935 // Load more notifications if visible notifications count becomes low 936 if (sse_type && sse_offset !== -1) { 937 let menu = document.getElementById('nav-' + sse_type + '-menu'); 938 if (menu && menu.querySelectorAll('.notification:not(.tt-filter-active):not(.cn-filter-active)').length < 15) { 939 sse_bs_notifications(sse_type, false, true); 940 } 941 } 942 } 943 } 944 945 function sse_handleNotificationsItems(notifyType, data, replace, followup) { 946 let notifications_tpl = decodeURIComponent(document.querySelector("#nav-notifications-template[rel=template]").innerHTML.replace('data-src', 'src')); 947 let notify_menu = document.getElementById("nav-" + notifyType + "-menu"); 948 let notify_loading = document.getElementById("nav-" + notifyType + "-loading"); 949 let notify_count = document.getElementsByClassName(notifyType + "-update"); 950 951 if (notify_menu === null) { 952 return; 953 } 954 955 956 if (replace && !followup) { 957 notify_menu.innerHTML = ''; // Clear menu 958 notify_loading.style.display = 'none'; // Hide loading 959 } 960 961 data.forEach(notification => { 962 // Special handling for network notifications 963 if (!replace && !followup && notification.thread_top && notifyType === 'network') { 964 document.dispatchEvent(new CustomEvent('hz:handleNetworkNotificationsItems', { detail: notification })); 965 } 966 967 // Prepare HTML using the template 968 let html = notifications_tpl.format( 969 notification.notify_link, 970 notification.photo, 971 notification.name, 972 notification.addr, 973 notification.message, 974 notification.when, 975 notification.hclass, 976 notification.b64mid, 977 notification.notify_id, 978 notification.thread_top, 979 notification.unseen, 980 notification.private_forum, 981 encodeURIComponent(notification.mids), 982 notification.body 983 ); 984 985 // Append the new notification HTML to the menu 986 notify_menu.insertAdjacentHTML('beforeend', html); 987 }); 988 989 // Sort notifications by date 990 if (!replace && !followup) { 991 let notifications = Array.from(notify_menu.getElementsByClassName('notification')); 992 993 notifications.sort((a, b) => { 994 let dateA = new Date(a.dataset.when).getTime(); 995 let dateB = new Date(b.dataset.when).getTime(); 996 997 return dateB - dateA; // Sort in descending order 998 }); 999 1000 notifications.forEach(notification => notify_menu.appendChild(notification)); 1001 } 1002 1003 1004 // Filter thread_top notifications if the filter is active 1005 let filterThreadTop = document.getElementById('tt-' + notifyType + '-only'); 1006 if (filterThreadTop && filterThreadTop.classList.contains('active')) { 1007 let notifications = notify_menu.querySelectorAll('[data-thread_top="false"]'); 1008 notifications.forEach(notification => notification.classList.add('tt-filter-active')); 1009 } 1010 1011 // Filter notifications based on the input field 1012 let filterInput = document.getElementById('cn-' + notifyType + '-input'); 1013 if (filterInput) {
1014 let filter = filterInput.value.toString().toLowerCase(); 1015 if (filter) { 1016 if (filter.indexOf('%') === 0) filter = filter.substring(1); // Remove the percent if it exists 1017 let notifications = notify_menu.querySelectorAll('.notification'); 1018 notifications.forEach(notification => { 1019 let cn = notification.dataset.contact_name.toString().toLowerCase(); 1020 let ca = notification.dataset.contact_addr.toString().toLowerCase(); 1021 if (cn.indexOf(filter) === -1 && ca.indexOf(filter) === -1) { 1022 notification.classList.add('cn-filter-active'); 1023 } else { 1024 notification.classList.remove('cn-filter-active'); 1025 } 1026 }); 1027 } 1028 } 1029 1030 // Update relative time for notifications 1031 updateRelativeTime('.autotime-narrow'); 1032 } 1033 1034 1035 function sse_updateNotifications(mid) { 1036 // Find the notification elements based on its 'data-b64mid' or href attribute. 1037 // The latter will match reactions where b64mid will contain the uuid of its thread parent (reacted on) instead of its own. 1038 let notifications = document.querySelectorAll(`.notification[data-b64mid='${mid}'], .notification[href*='display/${mid}']`); 1039 1040 notifications.forEach(notification => { 1041 let type = notification.parentElement.id.split('-')[1]; 1042 1043 // Skip processing if the type is 'notify' and the conditions don't match 1044 if (type === 'notify' && (mid !== bParam_mid || sse_type !== 'notify')) { 1045 return true; 1046 } 1047 1048 notification.remove(); 1049 }); 1050 } 1051 1052 1053 function sse_setNotificationsStatus(data) { 1054 let primary_notifications = ['dm', 'home', 'intros', 'register', 'notify', 'files']; 1055 let nlinks = document.getElementById('notifications').querySelectorAll('.notification-link'); 1056 let primary_available = false; 1057 let any_available = false; 1058 1059 // Loop through all notifications and check their visibility 1060 nlinks.forEach(nlink => { 1061 let type = nlink.dataset.sse_type; 1062 let button = document.querySelector(`.${type}-button`); 1063 if (button && getComputedStyle(button).display === 'block') { 1064 any_available = true; 1065 if (primary_notifications.indexOf(type) > -1) { 1066 primary_available = true; 1067 } 1068 } 1069 }); 1070 1071 // Update notification button icons based on the primary notification availability 1072 let notificationIcons = document.querySelectorAll('.notifications-btn-icon'); 1073 1074 if (notificationIcons) { 1075 let iconClass = primary_available ? 'bi-exclamation-triangle' : 'bi-exclamation-circle'; 1076 let iconToRemove = primary_available ? 'bi-exclamation-circle' : 'bi-exclamation-triangle'; 1077 1078 notificationIcons.forEach(notificationIcon => { 1079 notificationIcon.classList.replace(iconToRemove, iconClass); 1080 }); 1081 } 1082 1083 // Update visibility of notification button and sections 1084 let notificationsBtn = document.querySelectorAll('.notifications-btn'); 1085 let noNotifications = document.querySelector('#no_notifications'); 1086 let notifications = document.querySelector('#notifications'); 1087 let navbarCollapse = document.querySelector('#navbar-collapse-1'); 1088 1089 if (any_available) { 1090 notificationsBtn.forEach(btn => { 1091 btn.style.opacity = 1; 1092 }); 1093 noNotifications.style.display = 'none'; 1094 notifications.style.display = 'block'; 1095 } else { 1096 if (notificationsBtn) { 1097 notificationsBtn.forEach(btn => { 1098 btn.style.opacity = 0.5; 1099 }); 1100 } 1101 if (navbarCollapse) navbarCollapse.classList.remove('show'); 1102 noNotifications.style.display = 'block'; 1103 notifications.style.display = 'none'; 1104 } 1105 1106 // Handle specific notifications if 'data' is provided 1107 if (data) { 1108 data.forEach(function (nmid) { 1109 sse_rmids.push(nmid); 1110 sse_updateNotifications(nmid); 1111 }); 1112 } 1113 } 1114 1115 function sse_fallback() { 1116 fetch('/sse') 1117 .then(response => response.json()) 1118 .then(obj => { 1119 if (!obj) return; 1120 1121 console.log('sse fallback'); 1122 console.log(obj); 1123 1124 sse_handleNotifications(obj, false, false); 1125 }) 1126 .catch(error => { 1127 console.error('Error fetching SSE data:', error); 1128 }); 1129 } 1130 1131</script>
1131 1132 1133<div id="notifications_wrapper" class="mb-4"> 1134 <div id="no_notifications" class="d-xl-none"> 1135 Sorry, you have got no notifications at the moment<span class="jumping-dots"><span class="dot-1">.</span><span class="dot-2">.</span><span class="dot-3">.</span></span> 1136 </div> 1137 <div id="nav-notifications-template" rel="template" class="d-none"> 1138 <a class="list-group-item list-group-item-action notification {6}" href="{0}" title="{13}" data-b64mid="{7}" data-notify_id="{8}" data-thread_top="{9}" data-contact_name="{2}" data-contact_addr="{3}" data-when="{5}"> 1139 <img data-src="{1}" loading="lazy" class="rounded float-start me-2 menu-img-2"> 1140 <div class="text-nowrap"> 1141 <div class="d-flex justify-content-between align-items-center lh-sm"> 1142 <div class="text-truncate pe-1"> 1143 <strong title="{2} - {3}">{2}</strong> 1144 </div> 1145 <small class="autotime-narrow text-body-secondary" title="{5}"></small> 1146 </div> 1147 <div class="text-truncate">{4}</div> 1148 </div> 1149 </a> 1150 </div> 1151 <div id="notifications" class="border border-top-0 rounded navbar-nav collapse"> 1152 </div> 1153</div> 1154 1155 1156</div></div></aside> 1157 </div> 1158 </div> 1159 </main> 1160 <footer></footer> 1161</body> 1162</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.