| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -22,32 +22,18 @@ import {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Hidden communities for transparency.
 | 
					 | 
					 | 
					 | 
					// Hidden communities for transparency.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					const filteredCommunities = {
 | 
					 | 
					 | 
					 | 
					const filteredCommunities = {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						tests: [
 | 
					 | 
					 | 
					 | 
						tests: [
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"2e9345+c7fb",  // TestRoom
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"762ba9+c7fb",  // TesterRoom
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"b4d829+c7fb",  // Test
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"e5853a+c7fb",  // testtest
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"fishing+8e2e", // Example group from PySOGS documentation
 | 
					 | 
					 | 
					 | 
							"fishing+8e2e", // Example group from PySOGS documentation
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"test+118d",    // Testing 1, 2, 3
 | 
					 | 
					 | 
					 | 
							"test+118d",    // Testing 1, 2, 3
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"test+13f6",    // Testing room
 | 
					 | 
					 | 
					 | 
							"test+13f6",    // Testing room2
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"test+c01b",    // Testing room
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"test+fe93",    // 测试(Test)
 | 
					 | 
					 | 
					 | 
							"test+fe93",    // 测试(Test)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"xyz+7908",     // XYZ Room
 | 
					 | 
					 | 
					 | 
							"xyz+7908",     // XYZ Room
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"xyz+efca",     // XYZ Room
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						],
 | 
					 | 
					 | 
					 | 
						],
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						offensive: [
 | 
					 | 
					 | 
					 | 
						offensive: [
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"60fa60+c7fb",    // "N-word" Community
 | 
					 | 
					 | 
					 | 
							"AlexMed+e093",   // drug trading?
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"ab1a4d+c7fb",    // zUnsensored Group (CSAM)
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"AlexMed+e093",   //
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"gore+e5e0",      // gore
 | 
					 | 
					 | 
					 | 
							"gore+e5e0",      // gore
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"RU-STEROID+e093" //
 | 
					 | 
					 | 
					 | 
							"RU-STEROID+e093" // drug trading?
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						],
 | 
					 | 
					 | 
					 | 
						],
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// These communities should be checked regularly
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// in case they update their PySOGS version
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						legacy: [
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							"Ukraine+02bd"  // https://reccacon.com/view/room/Ukraine
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						]
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					};
 | 
					 | 
					 | 
					 | 
					};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// This can be achieved with `text-overflow: ellipsis` instead
 | 
					 | 
					 | 
					 | 
					// This can be achieved with `text-overflow: ellipsis` instead
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -60,13 +46,27 @@ const transformJoinURL = (join_link) => {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						});
 | 
					 | 
					 | 
					 | 
						});
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					function onLoad(timestamp) {
 | 
					 | 
					 | 
					 | 
					function getTimestamp() {
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						setLastChecked(timestamp);
 | 
					 | 
					 | 
					 | 
						const timestampRaw = dom.meta_timestamp()
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							?.getAttribute('content');
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (!timestampRaw) return null;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						const timestamp = parseInt(timestampRaw);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (Number.isNaN(timestamp)) return null;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						return timestamp;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					function onLoad() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						const timestamp = getTimestamp();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (timestamp !== null) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							setLastChecked(timestamp);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						hideBadCommunities();
 | 
					 | 
					 | 
					 | 
						hideBadCommunities();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						// Sort by server to show off new feature & align colors.
 | 
					 | 
					 | 
					 | 
						// Sort by server to show off new feature & align colors.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sortTable(COLUMN.SERVER_ICON);
 | 
					 | 
					 | 
					 | 
						sortTable(COLUMN.SERVER_ICON);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						createJoinLinkButtons();
 | 
					 | 
					 | 
					 | 
						createJoinLinkButtons();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						markSortableColumns();
 | 
					 | 
					 | 
					 | 
						markSortableColumns();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						addQRModalHandlers();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						addServerIconInteractions();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					function displayQRModal(communityID) {
 | 
					 | 
					 | 
					 | 
					function displayQRModal(communityID) {
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -77,6 +77,24 @@ function hideQRModal(communityID) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						dom.qr_modal(communityID).style.display = "none";
 | 
					 | 
					 | 
					 | 
						dom.qr_modal(communityID).style.display = "none";
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					function addQRModalHandlers() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						const rows = dom.tbl_communities_content_rows();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (!rows) throw new Error("Rows not found");
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						for (const row of rows) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							const communityID = row.getAttribute('data-identifier');
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							row.querySelector('.td_qr_code').addEventListener(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								'click',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								() => displayQRModal(communityID)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							const closeButton =
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								dom.qr_modal(communityID).querySelector('.qr-code-modal-close');
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							closeButton.addEventListener(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								'click',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								() => hideQRModal(communityID)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					function createJoinLinkButtons() {
 | 
					 | 
					 | 
					 | 
					function createJoinLinkButtons() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const join_URLs = dom.join_urls();
 | 
					 | 
					 | 
					 | 
						const join_URLs = dom.join_urls();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						Array.from(join_URLs).forEach((td_url) => {
 | 
					 | 
					 | 
					 | 
						Array.from(join_URLs).forEach((td_url) => {
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -89,7 +107,7 @@ function createJoinLinkButtons() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					function hideBadCommunities() {
 | 
					 | 
					 | 
					 | 
					function hideBadCommunities() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						let numberOfHiddenCommunities = 0;
 | 
					 | 
					 | 
					 | 
						let numberOfHiddenCommunities = 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						for (const category of ['tests', 'offensive', 'legacy']) {
 | 
					 | 
					 | 
					 | 
						for (const category of ['tests', 'offensive']) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							numberOfHiddenCommunities +=
 | 
					 | 
					 | 
					 | 
							numberOfHiddenCommunities +=
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							  filteredCommunities[category]
 | 
					 | 
					 | 
					 | 
							  filteredCommunities[category]
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							    .map(hideElementByID)
 | 
					 | 
					 | 
					 | 
							    .map(hideElementByID)
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -138,6 +156,19 @@ function setLastChecked(last_checked) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						timestamp_element.innerText =	`${time_passed_in_minutes} minutes ago`;
 | 
					 | 
					 | 
					 | 
						timestamp_element.innerText =	`${time_passed_in_minutes} minutes ago`;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					// TODO: Move info into dynamic modal.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					function addServerIconInteractions() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						const rows = dom.tbl_communities_content_rows();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						for (const row of rows) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							const hostname = row.getAttribute('data-hostname');
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							const publicKey = row.getAttribute('data-pubkey');
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							const serverIcon = row.querySelector('.td_server_icon');
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							serverIcon.addEventListener('click', () => {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								alert(`Host: ${hostname}?>\n\nPublic key:\n${publicKey}?>`);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							});
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/**
 | 
					 | 
					 | 
					 | 
					/**
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * Function comparing two elements.
 | 
					 | 
					 | 
					 | 
					 * Function comparing two elements.
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 *
 | 
					 | 
					 | 
					 | 
					 *
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -253,9 +284,13 @@ function markSortableColumns() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const table = dom.tbl_communities();
 | 
					 | 
					 | 
					 | 
						const table = dom.tbl_communities();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						const header_cells = table.querySelectorAll('th');
 | 
					 | 
					 | 
					 | 
						const header_cells = table.querySelectorAll('th');
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						for (let colno = 0; colno < header_cells.length; colno++) {
 | 
					 | 
					 | 
					 | 
						for (let colno = 0; colno < header_cells.length; colno++) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						  if (!columnIsSortable(colno)) continue;
 | 
					 | 
					 | 
					 | 
							if (!columnIsSortable(colno)) continue;
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							header_cells[colno].classList.add('sortable');
 | 
					 | 
					 | 
					 | 
							header_cells[colno].classList.add('sortable');
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						}
 | 
					 | 
					 | 
					 | 
							header_cells[colno].addEventListener(
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								'click',
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								() => sortTable(colno)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/**
 | 
					 | 
					 | 
					 | 
					/**
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -279,13 +314,7 @@ function sortTable(column) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						setSortState(table, { ascending, column });
 | 
					 | 
					 | 
					 | 
						setSortState(table, { ascending, column });
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// html.js for styling purposes
 | 
					 | 
					 | 
					 | 
					// `html.js` selector for styling purposes
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					window.document.documentElement.classList.add("js");
 | 
					 | 
					 | 
					 | 
					document.documentElement.classList.add("js");
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Crude way to export from module script due to inline event handlers.
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					// Ideally, all handlers would be attached from JS via addEventListener.
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					Object.assign(window, {
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						onLoad, sortTable, displayQRModal,
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						hideQRModal, copyToClipboard
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					});
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					document.addEventListener('DOMContentLoaded', () => onLoad());
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
					 | 
					 | 
					
 
 |