async function ready() {

	var params = getQueryParams (document.location.search);

	/** Hi Bugzilla - Fix bug where syncStatus endpoint returns URL parameters after anchor link (https://bugzilla.mozilla.org/show_bug.cgi?id=1947693) */
	var tURL = new URL(window.location.href); // temporary url that we can modify if need be
	var tParams = tURL.searchParams; // search parameters
	var tHash = tURL.hash; // url hash
	/** If the current hash includes & then we know that URL parameters were mistakenly appended to the end */
	if (tHash.indexOf('&') > -1) {
		var recoverParams = tHash.split("&"); // split the hash by &
		var originalHash = recoverParams[0]; // save this as a fallback for what the hash should be post clean up
		/** Loop through the split hash and look for URL parameters that we will then add back to the URL */
		recoverParams.forEach(function(p) {
			if (p.indexOf("#") == -1) { // If # is not present then it is likely a URL parameter
				var keyValue = p.split("="); // split by = just in case it is not 
				if (keyValue.length == 2) { tParams.set(keyValue[0], keyValue[1]); } // If the length is 2 then we know we got a key/value pair and we can add it back to the parameters
			} else { originalHash = p; } // # is present - this is what the hash should be post clean up
		});
		tURL.hash = originalHash;
		window.history.replaceState({}, '', tURL.href); // replace URL with cleaned up version
	}

	/** _zm_cms_guid cookie code */
	var otCookies = checkCookie("OptanonConsent");
	if (window.location.href.indexOf('zoomus') >-1) {console.log("Current URL is "+window.location.href);}
	if (otCookies == null) { otCookies = ""; }
	var cmsCookie = checkCookie("_zm_cms_guid");
	if (window.location.href.indexOf('zoomus') > -1) {
		console.log("cms cookie value = "+cmsCookie);
	}

	/** Check to see if third party cookies are disabled in Chrome */
	var tpcd = true;
	var iframe_url = "https://www.zoom.us/third_party_cookie_check.html";
	if (window.location.href.indexOf('zoomus') > -1) { iframe_url = "https://dev-integration.zoomdev.us/third_party_cookie_check.html"; }
	//if (window.location.href.indexOf('support.zoom.com') > -1 || window.location.href.indexOf('zoomus.service-now.com') > -1) { iframe_url = "https://www.zoom.us/third_party_cookie_check.html";}
	if (isChrome()) {
		// Have we already checked third party cookies today? 
		var tpcd_cookie = checkCookie("_zm_tpcd_checked");
		// If tpde_cookie is null then we have not checked and we need to create the iframe to check Chrome's third party cookies 
		if (tpcd_cookie == null) {
			if (window.location.href.indexOf('support.zoom.com') > -1) { tpcd = await isThirdPartyCookieDisabled(3000, iframe_url); } // only run on prod for now - change this if needing to test
			// Set cookie to show that we have already checked this, value will show (inverse) whether or not third party cookies are enabled
			if (window.location.href.indexOf('zoomusdev') > -1) { document.cookie = "_zm_tpcd_checked=" + tpcd.toString() + "; " + (24* 60 * 60 * 1000) + "; path=/";}
			else { document.cookie = "_zm_tpcd_checked=" + tpcd.toString() + "; " + (24* 60 * 60 * 1000) + "; domain=zoom.com; path=/"; }
		} 
		// We already checked - we can pull the value from tpcd_cookie value
		else {
			if (tpcd_cookie == "false") { tpcd = false; }
			else if (tpcd_cookie == "true") { tpcd = true; }
		}
		// tpcd = true means disabled, tpcd = false means enabled 
	}
	
	/** CHROME with third party cookies enabled - DON'T NEED TO DO ANYTHING HERE */
	if ((isChrome() || isCrawler()) && !tpcd ) {
		if (window.location.href.indexOf('zoomus') >-1) {
			console.log("Browser is Chrome based with third party cookies enabled or is a crawler, don't need to check for cookie");
		}
	}
	/** NON-CHROME + WE RECEIVE cms_guid URL PARAMETER - NEED TO SET COOKIE HERE */
	else if (params.cms_guid != undefined && cmsCookie == null) {
		// Determine cookie expiration date.
		// If cms_guid == "false" then we set the cookie for 1hr. Otherwise set for 24hr.
		var expireTime;
		if (params.cms_guid == "false" || params.cms_guid == false) { expireTime = 60 * 60 * 1000;}
		else { expireTime = 24* 60 * 60 * 1000; }
		
		// Set Cookie on zoom.com domain
		var date = new Date();
		date.setTime(date.getTime() + expireTime); // 1 hour in milliseconds
		var expires = "expires=" + date.toUTCString();
		
		// Set different cookies for prod/dev
		if (window.location.href.indexOf('zoomusdev') > -1) { document.cookie = "_zm_cms_guid=" + params.cms_guid + "; " + expires + "; path=/";}
		else { document.cookie = "_zm_cms_guid=" + params.cms_guid + "; " + expires + "; domain=zoom.com; path=/"; }
		
		// Clean up URL by removing cms_guid and lang parameters
		var url = new URL(window.location.href);
		var searchParams = new URLSearchParams(url.search);
		searchParams.delete("cms_guid");
		if (params.logged_in != undefined) { searchParams.delete("logged_in");}
		if (params.lang != undefined) { searchParams.delete("lang"); }
		url.search = searchParams.toString();
		if (window.location.href.indexOf('zoomus') >-1) { console.log("Cleaning current URL to "+url); }
		window.history.replaceState({}, '', url);
	}
	/** NON-CHROME + cms_guid URL PARAMETER IS NOT PRESENT. NEED TO DETERMINE WHETHER OR NOT TO GO GET IT. */
	else {
		if (window.location.href.indexOf('zoomus') >-1) { console.log("Browser is not Chrome based - cookie value is "+cmsCookie); }
		/** _zm_cms_guid cookie does not exist at all so we need to redirect to syncStatus */
		if (cmsCookie == null) {
			// Determine which URL to redirect to
			var newURL = "";
			if (window.location.href.indexOf('zoomusdev') > -1) { newURL = "http://dev-integration.zoomdev.us/syncStatus?continue=https://zoomusdev.service-now.com/hc?id=contact_us"; }
			else { newURL = "http://zoom.us/syncStatus?continue="+encodeURIComponent(window.location.href);}
			//window.location.replace(newURL); // Redirect
			if (window.location.href.indexOf('support.zoom.com') > -1) {
				window.location.replace(newURL); // Redirect
			} else { console.log("Would be redirecting to : "+newURL); }
		}
		/** Cookie already exists as "false" but we have a URL parameter indicating that the user logged in via the bot -- Need to get an updated cookie value. */
		else if (cmsCookie == "false" && params.logged_in=="true") {
			// Dev
			if (window.location.href.indexOf('zoomusdev') > -1) { 
				document.cookie = "_zm_cms_guid=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; // Clear cookie
				window.location.replace("http://dev-integration.zoomdev.us/syncStatus?continue=https://zoomusdev.service-now.com/hc"); // Redirect
			}
			// Prod
			else { 
				document.cookie = "_zm_cms_guid=; expires=Thu, 01 Jan 1970 00:00:00 UTC; domain=zoom.com; path=/;"; // Clear cookie
				window.location.replace("http://zoom.us/syncStatus?continue="+encodeURIComponent(window.location.href)); // Redirect
			}
		}
		/** Cookie already exists and is set properly. Don't need to do anything here. */
		else {
			if (window.location.href.indexOf('zoomus') >-1) { console.log("Cookie exists and is not 'false' - no redirect"); }
		}
		if (params.logged_in != undefined) {
			var url = new URL(window.location.href);
			var searchParams = new URLSearchParams(url.search);
			searchParams.delete("logged_in");
		}
	}
	/** end cookie code */

	if (params.onlycontent=='1') {
		$('html').addClass('contentonly');
	}
	else {
		params.onlycontent='0';
	}

	if (params.nohyperlink=='1') {
		$('html').addClass('nohyperlink');
		$('.kb-article-content a').each(function(e) {
			console.log(e);
			/***
				Cases where we just replace the parameters for the link :
				- support.zoom.us is found in the link
				- /articles/ is found in the link
				- /requests is not found in the link
			***/
			if ($(this).attr('href').indexOf('support.zoom.us') > -1  && $(this).attr('href').indexOf('/articles/') > -1 && $(this).attr('href').indexOf('/requests') == -1) {
				var tmp = $(this).attr('href');	
				if ($(this).attr('href').indexOf('#') > -1) {	
					var url_split = tmp.split("#");	
					var new_url = url_split[0] + '?onlycontent='+params.onlycontent+'&nohyperlink='+params.nohyperlink + '#' + url_split[1];	
					$(this).attr('href', new_url);	
				}	
				else {	
					$(this).attr('href', tmp + '?onlycontent='+params.onlycontent+'&nohyperlink='+params.nohyperlink);	
				}
			}
			/***
				Cases where we do nothing with the link (either): 
				- the data-toggle property = collapse (accordion link)
				- the first character of the link is a # and https is not found (anchor link)
			***/
			else if ($(this).data('toggle') == 'collapse' || ($(this).attr('href').charAt(0) == "#" && $(this).attr('href').indexOf('https:') == -1)) {
				//do nothing
			}
			// All other links we just remove
			else {
				$(this).addClass('dead-link');
				$(this).removeAttr("href");
			}
		});
  }
	
}

// Loads a script and then runs the callback function
function loadScript( url, callback ) {
  var script = document.createElement( "script" )
  script.type = "text/javascript";
  if(script.readyState) {  // only required for IE <9
    script.onreadystatechange = function() {
      if ( script.readyState === "loaded" || script.readyState === "complete" ) {
        script.onreadystatechange = null;
        callback();
      }
    };
  } else {  //Others
    script.onload = function() {
      callback();
    };
  }

  script.src = url;
  document.getElementsByTagName( "head" )[0].appendChild( script );
}

function getQueryParams (queryString)
{
	queryString = queryString.split ('+').join (' ');

	var params = {};
	var tokens;
	var regex = /[?&]?([^=]+)=([^&]*)/g;

	while (tokens = regex.exec (queryString))
	{
	params[decodeURIComponent (tokens[1])] = decodeURIComponent (tokens[2]);
	}

	return params;
}

function isChrome() {
	return navigator.userAgent.toLowerCase().includes("chrome");
}

function isCrawler() {
	var botPattern = "(googlebot\/|bot|Googlebot-Mobile|Googlebot-Image|Google favicon|Mediapartners-Google|bingbot|slurp|java|wget|curl|Commons-HttpClient|Python-urllib|libwww|httpunit|nutch|phpcrawl|msnbot|jyxobot|FAST-WebCrawler|FAST Enterprise Crawler|biglotron|teoma|convera|seekbot|gigablast|exabot|ngbot|ia_archiver|GingerCrawler|webmon |httrack|webcrawler|grub.org|UsineNouvelleCrawler|antibot|netresearchserver|speedy|fluffy|bibnum.bnf|findlink|msrbot|panscient|yacybot|AISearchBot|IOI|ips-agent|tagoobot|MJ12bot|dotbot|woriobot|yanga|buzzbot|mlbot|yandexbot|purebot|Linguee Bot|Voyager|CyberPatrol|voilabot|baiduspider|citeseerxbot|spbot|twengabot|postrank|turnitinbot|scribdbot|page2rss|sitebot|linkdex|Adidxbot|blekkobot|ezooms|dotbot|Mail.RU_Bot|discobot|heritrix|findthatfile|europarchive.org|NerdByNature.Bot|sistrix crawler|ahrefsbot|Aboundex|domaincrawler|wbsearchbot|summify|ccbot|edisterbot|seznambot|ec2linkfinder|gslfbot|aihitbot|intelium_bot|facebookexternalhit|yeti|RetrevoPageAnalyzer|lb-spider|sogou|lssbot|careerbot|wotbox|wocbot|ichiro|DuckDuckBot|lssrocketcrawler|drupact|webcompanycrawler|acoonbot|openindexspider|gnam gnam spider|web-archive-net.com.bot|backlinkcrawler|coccoc|integromedb|content crawler spider|toplistbot|seokicks-robot|it2media-domain-crawler|ip-web-crawler.com|siteexplorer.info|elisabot|proximic|changedetection|blexbot|arabot|WeSEE:Search|niki-bot|CrystalSemanticsBot|rogerbot|360Spider|psbot|InterfaxScanBot|Lipperhey SEO Service|CC Metadata Scaper|g00g1e.net|GrapeshotCrawler|urlappendbot|brainobot|fr-crawler|binlar|SimpleCrawler|Livelapbot|Twitterbot|cXensebot|smtbot|bnf.fr_bot|A6-Indexer|ADmantX|Facebot|Twitterbot|OrangeBot|memorybot|AdvBot|MegaIndex|SemanticScholarBot|ltx71|nerdybot|xovibot|BUbiNG|Qwantify|archive.org_bot|Applebot|TweetmemeBot|crawler4j|findxbot|SemrushBot|yoozBot|lipperhey|y!j-asr|Domain Re-Animator Bot|AddThis)";
	var re = new RegExp(botPattern, 'i');
	var userAgent = navigator.userAgent; 
	return re.test(userAgent);
}

async function isThirdPartyCookieDisabled(timeoutMs, url) {
	return new Promise((resolve) => {
	  const iframe = document.createElement('iframe');
	  const targetOrigin = url;
	  let resolved = false;
  
	  iframe.style.display = 'none';
	  iframe.src = targetOrigin;
  
	  const timeout = setTimeout(() => {
		if (!resolved) {
		  resolved = true;
		  iframe.remove();
		  resolve(true); // Assume cookies are disabled on timeout
		}
	  }, timeoutMs);
  
	  iframe.onload = () => {
		try {
			iframe.contentWindow.postMessage({ type: 'checkCookies' }, targetOrigin);
		} catch (e) {
		  	clearTimeout(timeout);
		  	resolved = true;
		  	iframe.remove();
		  	resolve(true); // Assume disabled if postMessage fails
		}
	  };
  
	  function handleMessage(event) {
		//if ((event.origin === "https://dev-integration.zoomdev.us" || event.origin === "https://zoom.us") && event.source === iframe.contentWindow && event.data.type === 'cookieStatus') {
		if (event.data.type === 'cookieStatus') {
			if (window.location.href.indexOf('zoomusdev') > -1) {console.log("This message met the criteria.", event);}
			clearTimeout(timeout);
			resolved = true;
			window.removeEventListener('message', handleMessage);
			iframe.remove();
			resolve(!event.data.status); // Invert: true means disabled
		}
	  }
  
	  window.addEventListener('message', handleMessage);
	  document.body.appendChild(iframe);
	});
}

document.addEventListener("DOMContentLoaded", ready);