GIF89a; %PDF-1.5 %���� ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµù Õ5sLOšuY Donat Was Here
DonatShell
Server IP : 134.29.175.74  /  Your IP : 216.73.216.160
Web Server : nginx/1.10.2
System : Windows NT CST-WEBSERVER 10.0 build 19045 (Windows 10) i586
User : Administrator ( 0)
PHP Version : 7.1.0
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : OFF  |  Perl : OFF  |  Python : OFF  |  Sudo : OFF  |  Pkexec : OFF
Directory :  C:/nginx/html/Scheduler/Schedule/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ HOME SHELL ]     

Current File : C:/nginx/html/Scheduler/Schedule//schedule.js
"use strict";
// Schedule/schedule.js

// _Initialize() .................................................. Initialize js.
// _Resized() ..................................................... Resize js.
// _Scrolled() ..................................................a.. Scroll js.
// AddClassMeeting() .............................................. Add a new meeting to the Schedule Class dialog.
// AddClassMeeting_Done(divId) .................................... Wait until the Meeting loads and call ScheduleClassDialog_SetWidth().
// ChangeInstructorColor(e) ....................................... Change the color of the Instructor for Highlight/Instructor.
// ClassMeeting_SetHeight(by) ..................................... Align display (visible height) of Schecule Class dialog meetings.
// ClassmeetingArranged(e) ........................................ Show or hide class meeting time and days form elements based on Arranged checked.
// ClassmeetingOffCampus(e) ....................................... Show or hide class meeting rooms form elements based on Off campus checked.
// ClearTextSelection() ........................................... Clear any text selection on the page.
// CloseTextbox() ................................................. Close and empty the textboxDiv.
// ConvertMinutesToTime(dayminutes, flags) ........................ Convert day minutes to time. Default is 24 hr clock with two digit hour and ':00' seconds.
// ConvertTimeTo12hr(timeofday) ................................... Convert time to 12hr with meridiem. Seconds will be ignored if present.
// ConvertTimeToMinutes(timeofday) ................................ Convert time to minutes. Seconds will be ignored if present.
// CreateSortedClasses() .......................................... Create an array (EVENTS_ORDERED) of ScheduleClasses sorted by course number and section.
// DisplaySchedule(by) ............................................ Display the classes on the schedule.
// DisplaySchedule_SetSize() ........................................ Set scheduleTime, scheduleCell, and scheduleHead widths and heights.
// DisplaySchedule_Highlight_Conflicts() .......................... Check schedule for class Degree/year, room, or instructor conflicts and change meeting styles to show them.
// DisplaySchedule_Highlight_Instructors() ........................ Highlight the different Instructors.
// DisplayScheduleShowHide() ...................................... Show or hide the scheduleHead, scheduleTimes, and scheduleCells and calculate left and width of cells.
// EventListeners_Add() ........................................... Add event listeners to the schedule classes.
// EventListeners_Remove() ........................................ Remove event listeners to the calendar_class divs.
// Events_Add( day ) .............................................. Add events for this day to EVENTS_TO_DISPLAY for positioning schedule classes.
// Events_Overlapping(day) ........................................ Check all events for overlap and add to EVENTS_OVERLAPPING.
// Events_Prepare( day ) .......................................... Adds additional properties to EVENTS_TO_DISPLAY, so that they can be positioned properly on the schedule.
// Events_Prepare_GetLeft( overlapObject, eventKey, day, width ) .. Calculate left overlapping events.
// Events_Prepare_MaxOverlap(overlapObject, eventKey) ............. Calculate max overlap length for positioning schedule classes.
// Events_Sort( EVENT ) ........................................... Sorts array of event objects by their begin and position paremeters.
// HighlightLikeMe() .............................................. Highlight all sibling class meetings with something to make them noticeable.
// MoveCLass_Cancel() ............................................. Cancel the class move and put the calendar_class divs back to their original locations.
// OpenDialog(scheduleclassId, CallCount) ......................... Open the dialogDiv with the scheduleclass info loaded.
// OpenTextbox(evt, title, text, buttons, returnFunction) ......... Open the textboxDiv.
// Print() ........................................................ Print the contents of the 'eId' element.
// RemoveChildren(e) .............................................. Remove all child elements from e.
// ScheduleChange() ............................................... Display the schedule change form.
// ScheduleChange_ChangeScheduleButtonCheck(e) .................... Enable/disable Change schedule button.
// ScheduleChange_CreateScheduleButtonCheck(e) .................... Enable/disable Create schedule button.
// ScheduleClass_MoveSingleMeetingDiv() ........................... Move class meeting div to the drop day/time, update db and redraw.
// ScheduleClass_OpenAddDialog() .................................. Add a class to the schedule.
// ScheduleClass_OpenEditDialog(evt) .............................. Edit the class.
// ScheduleClass_RemoveClassMeetingVerify(scmId, thisTask) ........ Verify removal of class meeting.
// ScheduleClass_RemoveClassVerify(thisTask) ...................... Verify removal of schedule class.
// ScheduleClassDialog_SetWidth(by) ............................... Set the wicth of the Schedule Class dialogDiv.
// ScheduleClassDialogDrag(e) ..................................... Handles the drag event from the Schedule Class dialog.
// ScheduleClassDragBegin(evt) .................................... Begin the schedule class drag.
// ScheduleClassDragCheck(evt) .................................... Determine if this is a click or a drag of a schedule class.
// ScheduleClassDragCheckWait(evt) ................................ Wait 50 ms to ensure this is a drag vs a click.
// ScheduleClassDragMove(evt) ..................................... Follow the mouse with the schedule class being dragged.
// ScheduleClassDragMoveAbortCheck(evt) ........................... Check for ESC key to abort sheedule class drag.
// ScheduleClassDrop(evt) ......................................... handle schedule class drop.
// ScheduleImportClasses(thisTask) ................................ Handle class import from another schedule.
// ScheduleImportClasses_ParseButtonCheck(e) ...................... Enable/disable Change schedule button.
// ScheduleImportClasses_ScheduleButtonCheck(e) ................... Enable/disable Change schedule button.
// ScheduleTaskHide() ............................................. Hide the schedule and display the div_ScheduleFunctionsContainer.
// ScheduleTaskShow() ............................................. Show the schedule and hide the div_ScheduleFunctionsContainer.
// ScheduleViewSettings(makeChange) ............................... Set schedule settings: calendar_dayview, calendar_timebegin, calendar_timeend, calendar_timeincrement, and calendar_incrementheight.
// ScrollDialogDiv() .............................................. Reposition the Schedule Class dialog on page scroll
// Search_FindMeetings(search) .................................... Find and highlight class meetings that match search.
// Search_HighlightMeetings() ..................................... Hightlight meetings found by search.
// Search_UnhighlightMeetings() ................................... Unhighlight and clear meetings found by search.
// Search_UpdateDatalist(e) ....................................... Populate schedule search datalist from input.
// SetClassEndTime(e) ............................................. Set the class end time based on the # credits / meeting days.
// SetupBuildingSelectOptions(e) .................................. Set the options for the building select.
// SetupInstructorOptions() ....................................... Set the options for the next instructor select.
// SetupNextCampusSelectOptions(scmId, campusIndex) ............... Set the options for the next campus select.
// SetupRoomSelectOptions() ....................................... Set the options for the room select.
// ShowInstructorButton(e) ........................................ Show + add instructor button.
// ShowInstructorNext(e) .......................................... Show next select element for instructor.
// Room_RoomLine_Show(scmId, campusIndex_Next) ......................... Show next select element for campus.
// RoomLine_RemoveAddButtons_ShowHide(scmId, campusIndex) ............................. Show + add room button.
// SidenavToggle(sidenavClass) .................................... Show / hide side nav sub menu.
// SortObject(obj) ................................................ Sort an object by key.
// UnhighlightLikeMe() ............................................ Unhighlight all siblin class meetings.

//"use strict";

// Variables
let ClassMeetingIndex = 1; // Used to set the id for new class meetings (add meeting).
let EVENTS_ORDERED = []; // an array of ScheduleClasses sorted by course number and section.
let EVENTS_OVERLAPPING;	// Events as keys with an array of their overlapping events.
let EVENTS_READY;				// Events with position and width set.
let EVENTS_TO_DISPLAY;	// Events to be rendered on the schedule
let ScheduleClassOpenCount = 0;
let ScheduleDayTimePositions = {};
let ScheduleInstructions_class = '<span class="actionback nowrap">Click to edit.</span> <span class="action nowrap">--or--</span><br><span class="actionback nowrap">Mouse-down / drag / drop to move.</span>';
let ScheduleInstructions_arranged = '<span class="actionback nowrap">Click to edit.</span> <span class="nowrap"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span>';
let ScheduleTop;
let bcrt = 0; // Used by AutoscrollPage() by Garrett Wiley.
let buildingId = 0;
let campusId = 0;
let currentOpenScheduleClassId;
let dialogDivContents;
let dragElementTL;
let mXprevious;
let mYprevious;
let mousedownFlag = '';
let mousedownTimer = 0;
//let roomId = 0; // unused 2022/04/06 jfm
let schedulecontainerTL;
let scheduleHeads;
let scrollTL = {}; let viewportTL = {}; let dragElementOriginalTL;

var _Initialize = function() {
	console.log(PC+'_Initialize_Tooltip[] schedule.js:105',CH);
	PositionSidenav();
	EventListeners_Add();
	DisplaySchedule_SetSize();
	DisplaySchedule('_Initialize schedule.js:109');
};

var _Resized = function() {
	console.log(PC+'_Resized[] schedule.js:112',CH);
	PositionSidenav();
	console.log("document.getElementById('schedulecontainer').style.display="+document.getElementById('schedulecontainer').style.display);
	if ( document.getElementById('schedulecontainer').style.display !== 'none' ) {
		setTimeout(DisplaySchedule_SetSize,50);
		setTimeout(DisplaySchedule,100);
	}
};

var _Scrolled = function() {
	//console.warn('_Scrolled[] schedule.js');
	PositionSidenav();
};

// ChangeInstructorColor(e)
// Change the color of the Instructor for Highlight/Instructor.
// Change is stored in the database and session.
function ChangeInstructorColor(e) {
	//alert(evt.target.id);.
	// let userId = e.getAttribute("data-userId"); // data-userId is not currently output in the code.
	let idParts = e.id.split('_');
	let Id = idParts[1];
	for (let i = 0; i < ScheduleInstructor.length; i++ ) {
		if ( ScheduleInstructor[i].instructorId == Id ) {
			ScheduleInstructor[i].color = e.value.substr(1);
			console.log(`ScheduleInstructor[i].color = ${ScheduleInstructor[i].color}`);
			// Need Ajax call to save color.
			URI = ROOT_http + '/User/UserUpdate.php?task=ChangeColor';
			URI += '&userId='+ScheduleInstructor[i].instructorId;
			URI += '&color='+ScheduleInstructor[i].color;
			UpdateInclude(URI, false, false, false);
		}
	}
	DisplaySchedule_Highlight_Instructors();
} // END ChangeInstructorColor.

// DisplaySchedule_Highlight_Instructors()
// Highlight the different Instructors.
function DisplaySchedule_Highlight_Instructors() {
	var DEBUG = true;
	if ( DEBUG ) { console.groupCollapsed(PC+'DisplaySchedule_Highlight_Instructors[]',CG); }
	if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_None[]',CC); }
	DisplaySchedule_Highlight_None();
	let eHighlightInstructor = document.getElementById('ulHighlightInstructor');
	RemoveChildren(eHighlightInstructor);	
	let ScheduleInstructorCount = ScheduleInstructor.length;
	// Modify the DOM by creating and adding DOM elements.
	for ( let i = 0; i < ScheduleInstructorCount; i++ ) {
		let li = document.createElement('li');
		li.style.border = '2px solid #' + ScheduleInstructor[i].color;
		var att = document.createAttribute("data-userId");
		att.value = ScheduleInstructor[i].instructorId;
		li.setAttributeNode(att);
		li.id = `user_highlight_${ScheduleInstructor[i].instructorId}`;
		li.innerHTML = li.innerHTML + `<input type="text" id="inp_${ScheduleInstructor[i].instructorId}" style="display: none;" onchange="ChangeInstructorColor(this)">`;
		li.innerHTML = li.innerHTML + ' ' + ScheduleInstructor[i].Name;
		//li.addEventListener('click',fn.spectrum);
		//$(`#inp_${ScheduleInstructor[i].instructorId}`).spectrum({});
		eHighlightInstructor.appendChild(li);
		$(`#inp_${ScheduleInstructor[i].instructorId}`).spectrum({ color:`${ScheduleInstructor[i].color}`, preferredFormat:'hex' });
	}
	let li = document.createElement('li');
	li.style.border = "2px solid orange";
	//li.style.color = 'orange';
	li.innerHTML=li.innerHTML + 'none';
	eHighlightInstructor.appendChild(li);
	let CalendarClassDivs = document.querySelectorAll('div[id^="calendar_class_"]');
	////let CalendarClassDivsCount = CalendarClassDivs.length;
	CalendarClassDivs.forEach(function(e, index) {
		console.log(PC+CalendarClassDivs[index].innerHTML,CI);
		// Highlight border.
		let InstructorCount = 0;
		ScheduleInstructor.forEach(function(instructor, IDX) {
			console.log(PC+`${IDX}: ${ScheduleInstructor[IDX].Name}`,CL);
			if (CalendarClassDivs[index].innerHTML.indexOf(ScheduleInstructor[IDX].Name) !== -1) {
				CalendarClassDivs[index].style.border = `3px solid #${ScheduleInstructor[IDX].color}`;
				InstructorCount++;
			}
			// Need to deal with instructor none and multiple instructors.
			console.log(e.id, InstructorCount);
			
		});
	});
	if ( DEBUG ) { console.groupEnd(); }
} // END DisplaySchedule_Highlight_Instructors.

// EventListeners_Add()
// Add event listeners to the calendar_class divs.
function EventListeners_Add() {
	var DEBUG = false;
	if ( DEBUG ) { console.warn('EventListeners_Add[]'); }
	//window.addEventListener('resize',_Resized); // Add resize to re-display the schedule. Resized DisplaySchedule
	var this_calendar_meeting;
	var i;
	var calendar_classes = document.getElementsByClassName('calendar_class');
	for ( i=0; i<calendar_classes.length; i++) {
		this_calendar_meeting = calendar_classes[i];
		if ( DEBUG ) { console.log('Adding click EventListener for '+this_calendar_meeting.id); }
		this_calendar_meeting.addEventListener('click',ScheduleClass_OpenEditDialog); // Add click for class meeting edit.
		if ( DEBUG ) { console.log('Adding mousedown EventListener for '+this_calendar_meeting.id); }
		this_calendar_meeting.addEventListener('mousedown',ScheduleClassDragCheck); // Add mousedown for drag and drop.
		this_calendar_meeting.addEventListener('mouseenter',HighlightLikeMe,{ useCapture:true }); // Add mouseover for highlighting sibling classes.
		this_calendar_meeting.addEventListener('mouseleave',UnhighlightLikeMe,{ useCapture:true }); // Add mouseout to end highlighting sibling classes.
	}
	var calendar_arranged = document.getElementsByClassName('calendar_arranged');
	for ( i=0; i<calendar_arranged.length; i++) {
		this_calendar_meeting = calendar_arranged[i];
		if ( DEBUG ) { console.log('Adding click EventListener for '+this_calendar_meeting.id); }
		this_calendar_meeting.addEventListener('click',ScheduleClass_OpenEditDialog); // Add click for class meeting edit.
		if ( DEBUG ) { console.log('Adding mousedown EventListener for '+this_calendar_meeting.id); }
		//this_calendar_meeting.addEventListener('mousedown',ScheduleClassDragCheck); // Add mousedown for drag and drop.
		this_calendar_meeting.addEventListener('mouseenter',HighlightLikeMe,{ useCapture:true }); // Add mouseover for highlighting sibling classes.
		this_calendar_meeting.addEventListener('mouseleave',UnhighlightLikeMe,{ useCapture:true }); // Add mouseout to end highlighting sibling classes.
	}
} // END EventListeners_Add.

// EventListeners_Remove()
// Remove event listeners to the calendar_class divs.
function EventListeners_Remove() {
	var DEBUG_EventListeners_Remove = false;
	if ( DEBUG_EventListeners_Remove ) { console.warn('EventListeners_Remove[]'); }
	let this_calendar_class;
	// let this_calendar_meeting; // unused 2022/04/06 jfm
	let i;
	let calendar_classes = document.getElementsByClassName('calendar_class');
	for ( i=0; i<calendar_classes.length; i++) {
		this_calendar_class = calendar_classes[i];
		if ( DEBUG_EventListeners_Remove ) { console.log('Adding click EventListener for '+this_calendar_class.id); }
		this_calendar_class.removeEventListener('click',ScheduleClass_OpenEditDialog); // Add click for class meeting edit.
		if ( DEBUG_EventListeners_Remove ) { console.log('Adding mousedown EventListener for '+this_calendar_class.id); }
		this_calendar_class.removeEventListener('mousedown',ScheduleClassDragCheck); // Add mousedown for drag and drop.
	}
	var calendar_arranged = document.getElementsByClassName('calendar_arranged');
	for ( i=0; i<calendar_arranged.length; i++) {
		this_calendar_class = calendar_arranged[i];
		if ( DEBUG_EventListeners_Remove ) { console.log('Adding click EventListener for '+this_calendar_class.id); }
		this_calendar_class.removeEventListener('click',ScheduleClass_OpenEditDialog); // Add click for class meeting edit.
		if ( DEBUG_EventListeners_Remove ) { console.log('Adding mousedown EventListener for '+this_calendar_class.id); }
		this_calendar_class.removeEventListener('mousedown',ScheduleClassDragCheck); // Add mousedown for drag and drop.
	}
} // END EventListeners_Remove.


// ClassMeeting_SetHeight(by)
// Align display (visible height) of Schecule Class dialog meetings.
// This is done by changing the paddingBottom, not by setting the height.
function ClassMeeting_SetHeight(by) {
	var DEBUG_ClassMeeting_SetHeight = false;
	if ( DEBUG_ClassMeeting_SetHeight ) { console.warn('ClassMeeting_SetHeight[by='+by+']'); }
	var divClassMeetings = document.getElementsByClassName('divClassMeeting'); // Get the divClassMeetings.
	if ( DEBUG_ClassMeeting_SetHeight ) { console.log('divClassMeetings.length='+divClassMeetings.length); }
	var thisClassMeetingDiv;
	// BEGIN Get height and bottom margin for each divClassMeeting.
	var ClassMeetingHeight = []; // Height of each divClassMeeting.
	var Row_Max_Height = []; // Max height (less the paddingBottom) of divClassMeetings on each row.
	var Row_Min_Padding = []; // Max paddingBottom of divClassMeetings on each row.
	//var thisMarginBottom; // unused 2022/04/06 jfm
	var thisPaddingBottom;
	// Preload row max height and min paddingBottom.
	var rowIndex = 0;
	var meetingIndex;
	for ( meetingIndex=0; meetingIndex<divClassMeetings.length; meetingIndex++ ) { // Loop thru divClassMeetings.
		if ( meetingIndex % 2 === 0 ) {
			Row_Max_Height[rowIndex] = 0;
			Row_Min_Padding[rowIndex] = 99999;
			rowIndex++; // Increase row after even divClassMeeting.
		}
	} // Loop thru divClassMeetings.
	// Get divClassMeeting paddingBottom and height less paddingBottom.
	rowIndex = 0;
	for ( meetingIndex=0; meetingIndex<divClassMeetings.length; meetingIndex++ ) { // Loop thru divClassMeetings.
		thisClassMeetingDiv = divClassMeetings[meetingIndex];
		if ( DEBUG_ClassMeeting_SetHeight ) { console.log('thisClassMeetingDiv.id='+thisClassMeetingDiv.id); }
		// Get paddingBottom.
		thisPaddingBottom = window.getComputedStyle(thisClassMeetingDiv,null).paddingBottom.replace('px','');
		if ( thisPaddingBottom < Row_Min_Padding[rowIndex] ) { Row_Min_Padding[rowIndex] = parseFloat(thisPaddingBottom); }
		// Get height less paddingBottom.
		ClassMeetingHeight[meetingIndex] = window.getComputedStyle(thisClassMeetingDiv,null).height.replace('px','') - thisPaddingBottom;
		if ( ClassMeetingHeight[meetingIndex] > Row_Max_Height[rowIndex] ) { Row_Max_Height[rowIndex] = ClassMeetingHeight[meetingIndex]; }
		if ( meetingIndex % 2 !== 0 ) {
			rowIndex++; // Increase row after odd divClassMeeting.
		}
	} // Loop thru divClassMeetings.
	if ( DEBUG_ClassMeeting_SetHeight ) { 
		console.log('ClassMeetingHeight ='+JSON.stringify(ClassMeetingHeight));
		console.log('Row_Max_Height='+JSON.stringify(Row_Max_Height));
		//console.log('Row_Min_Margin ='+JSON.stringify(Row_Min_Margin));
		console.log('Row_Min_Padding='+JSON.stringify(Row_Min_Padding));
	}
	// END Get height and bottom margin for each divClassMeeting.
	// BEGIN Set the paddingBottom to even out the divClassMeetings height in each row.
	var newPaddingBottom;
	rowIndex = 0;
	for ( meetingIndex=0; meetingIndex<divClassMeetings.length; meetingIndex++ ) { // Loop thru divClassMeetings.
		thisClassMeetingDiv = divClassMeetings[meetingIndex];
		newPaddingBottom = Row_Max_Height[rowIndex] - ClassMeetingHeight[meetingIndex] + Row_Min_Padding[rowIndex];
		if ( meetingIndex % 2 !== 0 ) {
			newPaddingBottom += 0.01; // Add 0.01 to odd meetings because of browser rounding.
		}
		if ( DEBUG_ClassMeeting_SetHeight ) { console.log(meetingIndex+' newPaddingBottom='+newPaddingBottom); }
		thisClassMeetingDiv.style.paddingBottom = newPaddingBottom + 'px'; // Set divClassMeeting paddingBottom.
		if ( meetingIndex % 2 !== 0 ) {
			rowIndex++; // Increase row after odd divClassMeeting.
		}
	} // Loop thru divClassMeetings.
	// END Set the paddingBottom to even out the divClassMeetings height in each row.
} // END ClassMeeting_SetHeight. 

// ClassmeetingArranged(e)
// Show or hide class meeting time and days form elements based on Arranged checked.
function ClassmeetingArranged(e) { // id_scheduleclassmeetingArranged_240 id_scheduleclassmeetingArranged_add1
	var DEBUG_ClassmeetingArranged = true;
	if ( DEBUG_ClassmeetingArranged ) { console.warn('ClassmeetingArranged['+e.id+']'); }
	var eIdParts = e.id.split('_');
	var eId = eIdParts[2];
	if ( typeof eIdParts[3] !== 'undefined' ) { eId = 'add'+eIdParts[3]; }
	if ( DEBUG_ClassmeetingArranged ) { console.log('eId='+eId); }
	
	//console.log('e.checked='+e.checked);
	if ( e.checked ) {
		if ( document.getElementById('id_meetingTimes_'+eId) ) {
			document.getElementById('id_meetingTimes_'+eId).style.display = 'none';
			document.getElementById('id_meetingDays_'+eId).style.display = 'none';
		}
	} else {
		if ( document.getElementById('id_meetingTimes_'+eId) ) {
			document.getElementById('id_meetingTimes_'+eId).style.display = 'block';
			document.getElementById('id_meetingDays_'+eId).style.display = 'block';
		}
	}
	Validate_ScheduleClass();
} // END ClassmeetingArranged.

// ClassmeetingOffCampus(e)
// e = The chkClassIsOffCampus element.
// Show or hide class meeting rooms form elements based on Off campus checked.
function ClassmeetingOffCampus(e) {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.group(`${PC}ClassmeetingOffCampus[e.id=${e.id}]`,CG); }//Collapsed
	if ( DEBUG ) { console.log(`${PC}e.checked=${e.checked}`,CL); }
	// Get divRoomsId from checkbox id.
	let eIdParts = e.id.split('_');
	let scmId = eIdParts[1];
	let divRoomsId = 'divRooms_'+scmId;
	//if ( DEBUG ) { console.log('divRoomsId='+divRoomsId); }
	if ( e.checked ) {
		if ( document.getElementById(divRoomsId) ) {
			if ( DEBUG ) { console.log(`${PC}${divRoomsId} hidden`,CF); }
			document.getElementById(divRoomsId).style.display = 'none';
		}
	} else {
		if ( document.getElementById(divRoomsId) ) {
			if ( DEBUG ) { console.log(`${PC}${divRoomsId} shown`,CT); }
			document.getElementById(divRoomsId).style.display = 'block';
			Room_RoomLine_Show(scmId, 0); // Show campusIndex 0 RoomLine.
		}
	}
	Validate_ScheduleClass();
	if ( DEBUG ) { console.log(`${PC}END ${PC}ClassmeetingOffCampus`,SE,ST); console.groupEnd(); }
} // END ClassmeetingOffCampus.

// ClearTextSelection()
// Clear any text selection on the page.
function ClearTextSelection() {
	//console.log('Clear text selection.');
	if ( document.selection ) {
    //console.log('document.selection'); 
		document.selection.empty();
	} else if ( window.getSelection ) {
		//console.log('window.getSelection');
		window.getSelection().removeAllRanges();
	}
} // END ClearTextSelection.

// CloseTextbox()
// Close and empty the textboxDiv.
function CloseTextbox() {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.group(`${PC}CloseTextbox]`,CG); }//Collapsed
	let eTextboxDiv = document.getElementById('textboxDiv');
	eTextboxDiv.style.display = 'none';
	eTextboxDiv.innerHTML = '';
	if ( DEBUG ) { console.groupEnd(); console.log(PC+'END '+PC+'CloseTextbox',SE,ST); }
} // END CloseTextbox.

// ConvertMinutesToTime(dayminutes, flags)
// Convert day minutes to time. Default is 24 hr clock with two digit hour and ':00' seconds.
// dayminutes = day minutes.
//      flags = time format options.
//              a = 12 hour format with 'am' or 'pm' meridiem appended. Overrides P.
//              h = One digit hour possible.
//              P = 12 hour format with 'AM' or 'PM' meridiem appended.
//              s = Append ':00' seconds.
//              _ = Put a space before the meridiem. Has no effect without a or P.
//              . = Put dot after meridiem letters (a.m.). Has no effect without a or P.
// Examples using 810 dayminutes:
// flags = return value
//  none = 13:30:00
//     a = 01:30:00pm
//    ah = 1:30:00pm
//   ah_ = 1:30:00 pm
//   ah. = 1:30:00p.m.
//  ah_. = 1:30:00 p.m.
//   ahs = 1:30pm
//  ahs_ = 1:30 pm
//  ahs. = 1:30p.m.
// ahs_. = 1:30 p.m.
//    a_ = 01:30:00 pm
//    a. = 01:30:00p.m.
//   a_. = 01:30:00 p.m.
//    as = 01:30pm
//   as_ = 01:30 pm
//   as. = 01:30p.m.
//  as_. = 01:30 p.m.
//     P = Same as 'a' except the meridiem is in uppercase.
//     s = 13:30
function ConvertMinutesToTime(dayminutes, flags) {
	var DEBUG_ConvertMinutesToTime = false;
	if ( typeof flags === 'undefined' ) { flags = ''; }
	if ( DEBUG_ConvertMinutesToTime ) { console.warn('ConvertMinutesToTime[dayminutes='+dayminutes+', flags='+flags+']'); }
	var hr = parseInt(parseInt(dayminutes)/60);
	var mn = parseInt(dayminutes) - (hr*60);
	if ( DEBUG_ConvertMinutesToTime ) { console.log('hr='+hr+' mn='+mn); }
	var AMPM = '';
	var meridiemDot = '';
	var meridiem = '';
	var meridiemA = '';
	var meridiemM = '';
	var meridiemP = '';
	var meridiemSpace = '';
	if ( flags.indexOf('a') !== -1 ) { meridiemA = 'a'; meridiemM = 'm'; meridiemP = 'p'; } else { if ( flags.indexOf('P') !== -1 ) { meridiemA = 'A'; meridiemM = 'M'; meridiemP = 'P'; } }
	if ( meridiemA !== '' ) {
		if ( flags.indexOf('_') !== -1 ) { meridiemSpace = ' '; }
		if ( flags.indexOf('.') !== -1 ) { meridiemDot = '.'; }
	}
	if ( meridiemA !== '' ) {
		if ( hr >= 12 ) {
			meridiem = meridiemP;
			if ( hr !== 12 ) {
				hr -= 12;
			}
		} else {
			meridiem = meridiemA;
			if ( hr === 0 ) {
				hr = 12;
			}
		}
		AMPM = meridiemSpace + meridiem + meridiemDot + meridiemM + meridiemDot;
	}
	hr = hr.toString(); if ( hr.length < 2 && flags.indexOf('h') === -1 ) { hr = '0'+hr; }
	mn = mn.toString(); if ( mn.length < 2 ) { mn = '0'+mn; }
	if ( DEBUG_ConvertMinutesToTime ) { console.log('hr='+hr+' mn='+mn+' AMPM='+AMPM); }
	var timeofday = hr + ':' + mn;
	if ( flags.indexOf('s') !== -1 ) { timeofday += ':00'; }
	if ( DEBUG_ConvertMinutesToTime ) { console.log('timeofday='+timeofday); }
	return timeofday + AMPM;
} // ENE ConvertMinutesToTime.

// ConvertTimeTo12hr(timeofday)
// Convert time to 12hr with meridiem. Seconds will be ignored if present.
function ConvertTimeTo12hr(timeofday) {
	var timeofdayParts = timeofday.split(':');
	var hr = parseInt(timeofdayParts[0]);
	var hr12 = hr;
	//var min = parseInt(timeofdayParts[1]); // unused 2022/04/06 jfm
	if ( hr12 > 12 ) { hr12 -= 12; }
	var timeofdayNoSeconds = hr12+':'+timeofdayParts[1];
	var Time12hr;
	if ( hr < 12 ) {
		Time12hr = timeofdayNoSeconds+'am';
	} else {
		Time12hr = timeofdayNoSeconds+'pm';
	}
	return Time12hr;
} // END ConvertTimeTo12hr.

// ConvertTimeToMinutes(timeofday)
// Convert time to minutes. Seconds will be ignored if present.
// i.e. 11:30:00 returns 690.
// timeofday = the time to convert.
function ConvertTimeToMinutes(timeofday) {
	var DEBUG = false;
	if ( DEBUG ) { console.group(`${PC}ConvertTimeToMinutes[timeofday=${timeofday}]`,CG); }//Collapsed
	var AM = ( timeofday.toUpperCase().indexOf('A') !== -1 );
	var PM = ( timeofday.toUpperCase().indexOf('P') !== -1 );
	var timeParts = timeofday.toUpperCase().replace('A','').replace('M','').replace('P','').split(':');
	if ( DEBUG ) { console.log('AM='+AM+' PM='+PM+' timeParts='+timeParts); }
	if ( AM && parseInt(timeParts[0]) === 12 ) { timeParts[0] = 0; }
	if ( PM && parseInt(timeParts[0]) !== 12 ) { timeParts[0] = parseInt(timeParts[0]) + 12; }
	var DayMinutes = parseInt(timeParts[0]) * 60 + parseInt(timeParts[1]);
	//if ( isNaN(DayMinutes) ) { DayMinutes = 0; }
	if ( DEBUG ) { console.log('DayMinutes='+DayMinutes); }
	if ( DEBUG ) { console.log(`${PC}END ${PC}ConvertTimeToMinutes`,SE,ST); console.groupEnd(); }
	return DayMinutes;
} // END ConvertTimeToMinutes.

// CreateSortedClasses()
// Create an array (EVENTS_ORDERED) of ScheduleClasses sorted by course number and section.
function CreateSortedClasses() {
	var DEBUG = false;
	if ( DEBUG ) { console.group(`${PC}CreateSortedClasses[]`,CG); }//Collapsed.
	EVENTS_ORDERED = [];
	let unsortedScheduleClasses = {};
	for ( var scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){
		let section = ScheduleClass[scId].Section.substr(0,2);
		if ( section.length < 2 ) { section = '0' + section; }
		let sort = ScheduleClass[scId].Course + '_' + section;
		unsortedScheduleClasses[sort] = { scId:scId };
	}}
	if ( DEBUG ) { console.log(`${PC}unsortedScheduleClasses=${JSON.stringify(unsortedScheduleClasses)}`,CL); }
	let sortedScheduleClasses = SortObject(unsortedScheduleClasses);
	if ( DEBUG ) { console.log(`${PC}sortedScheduleClasses=${JSON.stringify(sortedScheduleClasses)}`,CI); }
	for ( var sort in sortedScheduleClasses ){if(sortedScheduleClasses.hasOwnProperty(sort)){
	EVENTS_ORDERED.push(parseInt(sortedScheduleClasses[sort].scId));
	}}
	if ( DEBUG ) { console.log(`${PC}EVENTS_ORDERED=${JSON.stringify(EVENTS_ORDERED)}`,CS); }
	if ( DEBUG ) { console.groupEnd(); }
} // END CreateSortedClasses.

// DisplaySchedule(by)
// Display the class meetings on the schedule.
// Class meetings are converted to EVENTS for each day and then displayed.
let DAY_TO_DEBUG = '';
function DisplaySchedule(by) {
	//return;
	CreateSortedClasses(); // Create an array (EVENTS_ORDERED) of ScheduleClasses sorted by course number and section.
	var DEBUG = false;
	if ( DisplaySchedule.counter == 1 ) {DEBUG = DEBUG_ON; }
	let DEBUG_ORIGINAL = DEBUG;
	if ( DEBUG || DAY_TO_DEBUG ) { console.groupCollapsed(PC+`DisplaySchedule[] by=${by}`,CG); } else { console.log(PC+`DisplaySchedule[] by=${by} counter=${DisplaySchedule.counter}`,CH); }
	//return; // Uncomment to stop schedule display.
	var MeetingDivs =  document.getElementsByClassName("calendar_class");
	if ( DEBUG ) { console.log('MeetingDivs.length='+MeetingDivs.length); }
	//DisplaySchedule_SetSize();
	DisplayScheduleShowHide();
	for ( var d=0; d<ScheduleViewDays.length; d++ ) { // Loop thru schedule days. work: M=0, T=1, W=2, H=3, F=4 full: U=0, M=1, T=2, W=3, H=4, F=5, S=6
		var day = ScheduleViewDays[d];
		if ( day === DAY_TO_DEBUG ) { DEBUG = DEBUG_ON; } else { DEBUG = DEBUG_ORIGINAL; }
		EVENTS_TO_DISPLAY = [];
		EVENTS_OVERLAPPING = {};
		EVENTS_READY = {};
		if ( Events_Add(day) ) {
			if ( DEBUG ) { console.log(day+' EVENTS_TO_DISPLAY='+JSON.stringify(EVENTS_TO_DISPLAY)); }
			Events_Overlapping(day);
			if ( DEBUG ) { console.log(day+' EVENTS_OVERLAPPING='+JSON.stringify(EVENTS_OVERLAPPING)); }
			Events_Prepare(day);
			if ( DEBUG ) { console.log(day+' EVENTS_TO_DISPLAY='+JSON.stringify(EVENTS_TO_DISPLAY)); }
			if ( DEBUG ) { console.log(day+' EVENTS_TO_DISPLAY='+JSON.stringify(EVENTS_TO_DISPLAY)); }
			if ( DEBUG ) { console.log(day+' EVENTS_READY='+JSON.stringify(EVENTS_READY)); }
		}
		// Position the classmeetings.
		for ( var ci=0; ci<EVENTS_TO_DISPLAY.length; ci++ ) { // Loop thru EVENTS_TO_DISPLAY.
			var thisMeeting = EVENTS_TO_DISPLAY[ci];
			//if ( DEBUG ) { console.log('thisMeeting.divId='+thisMeeting.divId); }
			if ( document.getElementById(thisMeeting.divId) ) {
				let classMeetingElement = document.getElementById(thisMeeting.divId);
				var innerDiv = classMeetingElement.children[0];
				//var backgroundDiv = innerDiv.lastChild;
				//console.log('backgroundDiv.id='+backgroundDiv.id);
				if ( DEBUG ) { console.log('281 thisMeeting.divId='+thisMeeting.divId+ 'thisMeeting.top='+thisMeeting.top+' ScheduleDayTimePositions['+thisMeeting.day+'].left='+ScheduleDayTimePositions[thisMeeting.day].left); }
				var styleLeft = thisMeeting.left + ScheduleDayTimePositions[thisMeeting.day].left;
				classMeetingElement.style.position = 'absolute';
				classMeetingElement.style.left    = styleLeft + 'px';
				classMeetingElement.style.width   = thisMeeting.width - 2 + 'px'; // -2 to show some space between meetings.
				classMeetingElement.style.display = 'block';
				//if ( classMeetingElement.id === 'calendar_class_8_M600' ) {
				var styleTop = thisMeeting.top * ScheduleHeightMultiplier + ScheduleTop;
				if ( DEBUG ) { console.log('281 thisMeeting.divId='+thisMeeting.divId+ 'thisMeeting.top='+thisMeeting.top+' ScheduleHeightMultiplier='+ScheduleHeightMultiplier+' ScheduleTop='+ScheduleTop+' styleTop='+styleTop); }
				//}
				classMeetingElement.style.top     = styleTop + 'px';//thisMeeting.top * ScheduleHeightMultiplier + ScheduleTop + 'px'; // + 1
				classMeetingElement.style.height  = thisMeeting.height * ScheduleHeightMultiplier + 'px';
				innerDiv.style.height = thisMeeting.height * ScheduleHeightMultiplier + 'px';
				//var backgroundDivTop = classMeetingElement.style.top + classMeetingElement.style.height - 21 + 'px';
				if ( DEBUG ) {
					var ceb = ElementBounds(classMeetingElement,'schedule.js 445');
					console.log(PC+ScheduleClass[EVENTS_TO_DISPLAY[ci].scId].Course+' bounds = '+ JSON.stringify(ceb),CI);
				}
			} else {
				console.info("\t"+thisMeeting.divId+' not found.');
			}
		} // Loop thru EVENTS_TO_DISPLAY.
	} // Loop thru schedule days.
	if ( DEBUG ) { console.groupEnd(); }
	DisplaySchedule_Highlight();
	DisplaySchedule.counter++;
} // END DisplaySchedule.
DisplaySchedule.counter = 0;

// DisplaySchedule_SetSize()
// Set scheduleTime, scheduleCell, and scheduleHead widths and heights.
function DisplaySchedule_SetSize() {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.group(`${PC}DisplaySchedule_SetSize[] ${DisplaySchedule.counter}`,CG); }//Collapsed
	let dayIndex; // Loop varable.
	// BEGIN Calculate scheduleCell width.
	// Hide the schedule so it does not effect width of page.
	// Need to get scrollbar width before hiding schedulecontainer.
	let scrollbarWidth = GetScrollbarWidth();
	document.getElementById('schedulecontainer').style.display = 'none'; // When this is done, the table width changes. WHY???
	// Show calendarCells so the scheduleCell widths can be calculated.
	// Show the schedule table.
	let eTable = document.getElementById('tbl_scheduleTable');
	eTable.style.display = 'table';
	console.dir(eTable);
	//eTable.width = "auto";
	eTable.style.width = ""; // Remove style width so the table will redraw to 100%;
	let tableBounds = ElementBounds('tbl_scheduleTable');
	if ( DEBUG ) { console.log(`${PC}scrollbarWidth=${scrollbarWidth} table.width=${tableBounds.width}`,CI); }
	// Do not subtract the scrollbarWidth when the page forst loads. Why???
	if ( DisplaySchedule.counter > 0 ) {
		eTable.style.width = tableBounds.width - scrollbarWidth + 'px';
	}
	//eTable.style.width = tableBounds.width - scrollbarWidth + 'px';
	tableBounds = ElementBounds('tbl_scheduleTable');
	if ( DEBUG ) { console.log(`${PC}scrollbarWidth=${scrollbarWidth} table.width=${tableBounds.width}`,CS); }
	//if ( DisplaySchedule.counter == 1 ) { return; }
	let calendarCells = document.getElementsByClassName('calendarCell');
	if ( DEBUG ) { console.log('calendarCells.length='+calendarCells.length); }
	for ( dayIndex=0; dayIndex<calendarCells.length; dayIndex++ ) {
		//if ( DEBUG ) { console.log('calendarCells['+dayIndex+'].title='+calendarCells[dayIndex].title+' .className='+calendarCells[dayIndex].className+' .offsetWidth='+calendarCells[dayIndex].offsetWidth); }
		if ( ScheduleViewDays.indexOf(calendarCells[dayIndex].title.substr(0,1)) !== -1 ) { // Is this day in ScheduleViewDays ('UMTWHFS' or 'MTWHF').
			if ( DEBUG ) { console.log('Show '+calendarCells[dayIndex].title); }
			calendarCells[dayIndex].className = 'calendarCell';
		} else {
			if ( DEBUG ) { console.log('Hide '+calendarCells[dayIndex].title); }
			calendarCells[dayIndex].className = 'calendarCell hidden';
		}
	} // Is this day in ScheduleViewDays ('UMTWHFS' or 'MTWHF').
	// Calculate scheduleCell width.
	if ( DEBUG ) { console.log('calendarCells[3].className='+calendarCells[3].className+' calendarCells[3].offsetWidth='+calendarCells[3].offsetWidth); }
	// var setWidth = parseInt(calendarCells[3].offsetWidth);
	var setWidth = calendarCells[3].offsetWidth;
	var setWidthdivWidthDivisor = 2;
	var calculatedWidth = setWidth;//parseInt(setWidth/setWidthdivWidthDivisor) * setWidthdivWidthDivisor - 0;//4; // Changed to subtract 0 px 1/28/20 jfm
	if ( DEBUG ) { console.log('calculatedWidth='+calculatedWidth); }
	// Hide the schedule table.
	//eTable.style.display = 'none';
	// Show the schedule.
	//if ( DisplaySchedule.counter == 1 ) { return; }
	document.getElementById('schedulecontainer').style.display = 'block';
	//if ( DisplaySchedule.counter == 1 ) { return; }
	// END Calculate scheduleCell width.
	// Set scheduleTime heights.
	var scheduleTimes = document.getElementsByClassName('scheduleTime');
	if ( DEBUG ) { console.log('scheduleTimes.length='+scheduleTimes.length); }
	for ( var scheduleCellindex=0; scheduleCellindex<scheduleTimes.length; scheduleCellindex++ ) {
		if ( scheduleTimes[scheduleCellindex].className.indexOf('scheduleHead') === -1 ) { // Is this a schedule time (not the head 'Time')?
			scheduleTimes[scheduleCellindex].style.height = ScheduleIncrementHeight + 'px';
		} // Is this a schedule time (not the head 'Time')?
	} // Is this a schedule time (not the head 'Time')?
	// Set scheduleCell heights and widths.
	var scheduleCells = document.getElementsByClassName('scheduleCell');
	if ( DEBUG ) { console.log('scheduleCells.length='+scheduleCells.length); }
	for ( scheduleCellindex=0; scheduleCellindex<scheduleCells.length; scheduleCellindex++ ) {
		scheduleCells[scheduleCellindex].style.width = calculatedWidth + 'px';
		scheduleCells[scheduleCellindex].style.height = ScheduleIncrementHeight + 'px';
		//scheduleCells[scheduleCellindex].style.lineHeight = ScheduleIncrementHeight - 5 + 'px';
	}
	// Set scheduleHead widths.
	scheduleHeads = document.getElementsByClassName('scheduleHead');
	if ( DEBUG ) { console.log('scheduleHeads.length='+scheduleHeads.length); }
	for ( scheduleCellindex=0; scheduleCellindex<scheduleHeads.length; scheduleCellindex++ ) {
		if ( scheduleHeads[scheduleCellindex].className.indexOf('scheduleTime') === -1 ) { // Is this a weekday (not the time).
			scheduleHeads[scheduleCellindex].style.width = calculatedWidth + 'px';
		} // Is this a weekday (not the time).
	}
	if ( DEBUG ) { console.log(`${PC}END ${PC}DisplaySchedule_SetSize`,SE,ST); console.groupEnd(); }
} // END DisplaySchedule_SetSize.

// DisplaySchedule_Highlight_Change(highlightType)
// Change the highlight type and redisplay the schedule.
function DisplaySchedule_Highlight_Change(highlightType) {
	let highlightTypes = ['none',
												'Conflict',
												'Credential',
												'Instructor',
												'Room',
												];
	if (highlightTypes.indexOf(highlightType) !== -1) {
		ScheduleHighlightView = highlightType;
		DisplaySchedule('DisplaySchedule_Highlight_Change');
	} else {
		console.log(`${PC}=ERROR! DisplaySchedule_Highlight: Invalid highlight type sent:${xxxhighlightType}`,CE);
	}
} // END DisplaySchedule_Highlight_Change

// DisplaySchedule_Highlight_Conflicts();
// Check schedule for class 1) Degree/year, 2) room, or 3) Instructor conflicts and change meeting styles to show them.
function DisplaySchedule_Highlight_Conflicts() {
	//return;
	var DEBUG_All = false;
	var DEBUG_MultipleNone = false;
	var DEBUG_Conflicts = false;
	if ( DEBUG_All ) { DEBUG_MultipleNone = true; DEBUG_Conflicts = true; }
	if ( DEBUG_MultipleNone || DEBUG_Conflicts ) { console.groupCollapsed(`${PC}DisplaySchedule_Highlight_Conflicts[]`,CG); }
	if ( DEBUG_MultipleNone || DEBUG_Conflicts ) { console.log(PC+'DisplaySchedule_Highlight_None[]',CC); }
	DisplaySchedule_Highlight_None();
	let	AnyConflicts,
			eCalendarClassDiv,
			calendar_class_div_base,
			calendar_class_div_id,
			campus1,
			campus2,
			ccmTime,
			ClassConflicts,
			courseId1,
			courseId2,
			courseNumber1,
			// courseNumber2, // unused 2022/04/06 jfm
			credential1,
			credential2,
			// credentialConflict, // unused 2022/04/06 jfm
			credentials1,
			credentials2,
			day,
			DayConflicts,
			days,
			d1,
			// d2, // unused 2022/04/06 jfm
			elementExists,
			eoId,
			instructor1,
			instructor2,
			// instructorConflict, // unused 2022/04/06 jfm
			instructors1,
			instructors2,
			m1,
			m2,
			meetingCount1,
			o1,
			// o2, // unused 2022/04/06 jfm
			overlap,
			r1,
			r2,
			room1,
			room2,
			rooms1,
			rooms2,
			scId,
			scmId,
			scId1;
	// BEGIN Highlight multiple and none.
	if ( DEBUG_MultipleNone ) { console.groupCollapsed(`${PB}Highlight multiple and none.`,SB,CD); }
	for ( scId1 in ScheduleClass ) {if(ScheduleClass.hasOwnProperty(scId1)) { // Loop thru 1st classes.
		calendar_class_div_base = 'calendar_class_'+scId1+'_';
		for ( m1=0; m1<SCMnow[scId1].length; m1++ ) { // Loop thru class meetings.
			scmId = SCMnow[scId1][m1].scmId;
			if ( DEBUG_MultipleNone ) { console.log(PC+`${ScheduleClass[scId1].Course}`,CI); }
			if ( DEBUG_MultipleNone ) { console.log(PC+`SCMnow[{$scId1}][{$m1}] = ${JSON.stringify(SCMnow[scId1][m1])}`,CL); }
			days = ['',...SCMnow[scId1][m1].days];
			if ( DEBUG_MultipleNone ) { console.log(PC+`days = ${days}`,CL); }
			for ( d1=0; d1<days.length; d1++ ) { // Loop thru days including a null one.
				courseId1 = ScheduleClass[scId1].courseId;
				courseNumber1 = Course[courseId1].Dept + Course[courseId1].Number;
				credentials1 = Course[courseId1].credentials;
				instructors1 = SCMnow[scId1][m1].instructors;
				rooms1 = SCMnow[scId1][m1].rooms;
				ccmTime = ConvertTimeToMinutes(SCMnow[scId1][m1].bTime);
				if ( isNaN(ccmTime) ) { ccmTime = 0; }
				calendar_class_div_id = calendar_class_div_base + days[d1] + ccmTime;
				eCalendarClassDiv = document.getElementById(calendar_class_div_id);
				elementExists = eCalendarClassDiv instanceof HTMLElement;
				if ( elementExists ) {
					if ( DEBUG_MultipleNone ) { console.log(PC+'calendar_class_div_id='+calendar_class_div_id,CI); }
					if ( DEBUG_MultipleNone ) { console.log(PC+'Checking '+courseNumber1+' '+calendar_class_div_id,CL); }
					eCalendarClassDiv = document.getElementById(calendar_class_div_id);
					// If the ccmTime is 0 change this div to a relative position.
					if ( ccmTime === 0 ) {
						eCalendarClassDiv.style.position = 'relative';
					}
					// Remove all highlights.
					var Highlights = [ 'class_Credential_Conflict', 'class_Credential_None', 'class_Instructor_Conflict', 'class_Instructor_Multiple', 'class_Instructor_None', 'class_Room_Conflict', 'class_Room_Multiple', 'class_Room_None' ];
					for ( var h=0; h<Highlights.length; h++ ) { // Loop thru Highlights.
						if ( eCalendarClassDiv.className.indexOf(Highlights[h]) !== -1 ) { // Is a highlight in the className?
							eCalendarClassDiv.className = eCalendarClassDiv.className.replace(' '+Highlights[h],'');
						} // Is a highlight in the className?
					} // Loop thru Highlights.
					// Check credentials.
					if ( !credentials1.length ) {
						if ( DEBUG_MultipleNone ) { console.info("\t\t"+'No credential'); }
						if ( eCalendarClassDiv.className.indexOf('class_Credential_None') === -1 ) {
							eCalendarClassDiv.className += ' class_Credential_None';
						}
					}
					// Check instructors.
					if ( instructors1.length ) {
						if ( instructors1.length > 1 ) {
							if ( DEBUG_MultipleNone ) { console.info("\t\t"+'Multiple instructors'); }
							if ( eCalendarClassDiv.className.indexOf('class_Instructor_Multiple') === -1 ) {
								eCalendarClassDiv.className += ' class_Instructor_Multiple';
							}
						}
					} else {
						if ( DEBUG_MultipleNone ) { console.info("\t\t"+'No instructor'); }
						if ( eCalendarClassDiv.className.indexOf('class_Instructor_None') === -1 ) {
							eCalendarClassDiv.className += ' class_Instructor_None';
						}
					}
					// Check rooms.
					if ( rooms1.length ) {
						if ( rooms1.length > 1 ) {
							if ( DEBUG_MultipleNone ) { console.info("\t\t"+'Multiple rooms'); }
							if ( eCalendarClassDiv.className.indexOf('class_Room_Multiple') === -1 ) {
								eCalendarClassDiv.className += ' class_Room_Multiple';
							}
						}
					} else {
						if ( SCMnow[scId1][m1].onCampus === '1' ) {
							if ( DEBUG_MultipleNone ) { console.info("\t\t"+calendar_class_div_id+' not found.'); }
							if ( eCalendarClassDiv.className.indexOf('class_Room_None') === -1 ) {
								eCalendarClassDiv.className += ' class_Room_None';
							}
						}
					}
				} else {
					if ( DEBUG_MultipleNone ) { console.log(PC+`Element ${calendar_class_div_id} does not exist.`,CF); }
				}
			} // Loop thru days including a null one.
		} // Loop thru class meetings.
	}}
	if ( DEBUG_MultipleNone ) { console.log(`${PC}END ${PC}Highlight multiple and none.`,SE,CD); console.groupEnd(); }
	// END Highlight multiple and none.
	// BEGIN Highlight conflicts.
	AnyConflicts = 0;
	if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PC}Highlight conflicts.`,CD); }
	for ( var ScheduleViewDayIndex=0; ScheduleViewDayIndex<ScheduleViewDays.length; ScheduleViewDayIndex++ ) { // Loop thru ScheduleViewDays days.
		day = ScheduleViewDays[ScheduleViewDayIndex];
		if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PB}Check ${day} for conflicts.`,SB,ST); }
		DayConflicts = 0;
		EVENTS_TO_DISPLAY = [];
		EVENTS_OVERLAPPING = {};
		EVENTS_READY = {};
		if ( Events_Add(day) ) {
			Events_Overlapping(day);
			Events_Prepare(day);
		}
		for ( eoId in EVENTS_OVERLAPPING ) {if(EVENTS_OVERLAPPING.hasOwnProperty(eoId)) { // Loop EVENTS_OVERLAPPING.
			scId = EVENTS_OVERLAPPING[eoId].scId;
			calendar_class_div_base = `calendar_class_${scId}_`;
			if ( EVENTS_OVERLAPPING[eoId].length ) {
				ClassConflicts = 0;
				if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PC}${ScheduleClass[scId].Course}, scmId = ${EVENTS_OVERLAPPING[eoId].scmId}, has ${EVENTS_OVERLAPPING[eoId].length} overlap(s) = ${JSON.stringify(EVENTS_OVERLAPPING[eoId].overlaps)}`,CD); }
				meetingCount1 = SCMnow[scId].length;
				if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[scId].Course} class has ${meetingCount1} meeting(s)`,CL); }
				for ( m1 = 0; m1 < meetingCount1; m1++ ) { // Loop thru first class meetings.
					if ( SCMnow[scId][m1].days.indexOf(day) !== -1 ) { // Does the first class meeting meet today?
						if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[scId].Course} SCMnow[${m1}] meets on ${day}.`,CT); }
						courseId1 = ScheduleClass[scId].courseId;
						credentials1 = Course[courseId1].credentials;
						instructors1 = [...SCMnow[scId][m1].instructors];
						rooms1 = SCMnow[scId][m1].rooms;
						ccmTime = ConvertTimeToMinutes(SCMnow[scId][m1].bTime);
						calendar_class_div_id = `${calendar_class_div_base}${day}${ccmTime}`;
						eCalendarClassDiv = document.getElementById(calendar_class_div_id);
						campus1 = [];
						SCMnow[scId][m1].rooms.forEach(function(room) {
							if ( !campus1.includes(RoomLookup[room].campusId) ) { campus1.push(RoomLookup[room].campusId); }
						});DisplaySchedule_Highlight
						for (o1 = 0; o1 < EVENTS_OVERLAPPING[eoId].overlaps.length; o1++ ) { // Loop thru overlaps.
							overlap = EVENTS_OVERLAPPING[eoId].overlaps[o1];
							if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PC}Checking against ${ScheduleClass[overlap.scId].Course}`,CI); }
							let CourseConflicts = 0;
							if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[overlap.scId].Course} overlap scmId = ${overlap.scmId}`,CL); }
							let meetingCount2 = SCMnow[overlap.scId].length;
							if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[overlap.scId].Course} class has ${meetingCount2} meeting(s)`,CL); }
								for ( m2 = 0; m2<meetingCount2; m2++ ) { // Loop thru overlap class meetings.
									if ( SCMnow[overlap.scId][m2].scmId === overlap.scmId ) { // Is this the overlaping meeting?
										if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[overlap.scId].Course} class meeting[${m2}] scmId ${SCMnow[overlap.scId][m2].scmId} matches overlap.scmId ${overlap.scmId}.`,CT); }
										courseId2 = ScheduleClass[overlap.scId].courseId;
										credentials2 = Course[courseId2].credentials;
										instructors2 = SCMnow[overlap.scId][m2].instructors;
										rooms2 = SCMnow[overlap.scId][m2].rooms;
										/**/
										// BEGIN Check for credintial conflicts.
										let credentialConflict = false;
										if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PC}Check for credintial conflicts.`,CS); }
										if ( credentials1.length && credentials2.length ) {
											if ( DEBUG_Conflicts ) { console.log(`${PC}credentials1 = ${JSON.stringify(credentials1)}`,CD); }
											if ( DEBUG_Conflicts ) { console.log(`${PC}credentials2 = ${JSON.stringify(credentials2)}`,CI); }
											credentialConflict = false;
											//credential_dance:
											for ( r1=0; r1<credentials1.length; r1++ ) { // Loop thru 1st credintials.
												credential1 = credentials1[r1];
												if ( DEBUG_Conflicts ) { console.log(`${PC}credential1.Id = ${credential1.Id}, Yr = ${credential1.Yr}`,CD); }
												for ( r2=0; r2<credentials2.length; r2++ ) { // Loop thru 2nd credintials.
													credential2 = credentials2[r2];
													if ( DEBUG_Conflicts ) { console.log(`${PC}credential2.Id = ${credential2.Id}, Yr = ${credential2.Yr}`,CI); }
													if ( credential1.Id === credential2.Id && credential1.Yr === credential2.Yr ) { // Is there a credential conflict?
														// There is a potential conflict. Need to test meeting dates.
														if ( ( SCMnow[scId][m1].sDate >= SCMnow[overlap.scId][m2].sDate && SCMnow[scId][m1].sDate <= SCMnow[overlap.scId][m2].eDate ) || ( SCMnow[scId][m1].eDate >= SCMnow[overlap.scId][m2].sDate && SCMnow[scId][m1].eDate <= SCMnow[overlap.scId][m2].eDate ) ) {
															// There is a potential conflict. Need to test campus.
															campus2 = [];
															SCMnow[overlap.scId][m2].rooms.forEach(function(room) {
																if ( !campus2.includes(RoomLookup[room].campusId) ) { campus2.push(RoomLookup[room].campusId); }
															});
															if ( DEBUG_Conflicts ) { console.log(`${PC}campus1 = ${campus1}`,CL); }
															if ( DEBUG_Conflicts ) { console.log(`${PC}campus2 = ${campus2}`,CL); }
															/** / // Old code using Array.diff
															if ( DEBUG_Conflicts ) { console.log(`Campus match: ${campus1.diff(campus2)}`); }
															let difference = campus1.filter(x => !campus2.includes(x));
															if ( campus1.diff(campus2).length ) {
																credentialConflict = true;
															}
															/**/
															/**/
															let difference = campus1.filter(x => !campus2.includes(x));
															if ( DEBUG_Conflicts ) { console.log(`Campus match: ${difference}`); }
															if ( difference.length ) {
																credentialConflict = true;
															}
															/**/
														} else {
															if ( DEBUG_Conflicts ) { console.log(`${PC}Dates do not overlap ${ScheduleClass[scId].Course} = ${SCMnow[scId][m1].sDate}-${SCMnow[scId][m1].eDate}, ${ScheduleClass[overlap.scId].Course} = ${SCMnow[overlap.scId][m2].sDate}-${SCMnow[overlap.scId][m2].eDate}.`,CL); }
														}
														if ( credentialConflict ) {
															DayConflicts++;
															ClassConflicts++;
															CourseConflicts++;
															AnyConflicts++;
															if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[scId].Course} has a credential conflict with ${ScheduleClass[overlap.scId].Course} for ${Credintial[credential1.Id].Title} yr ${credential1.Yr}.`,CW); }
															try {
																if ( eCalendarClassDiv.className.indexOf('class_Credential_Conflict') === -1 ) {
																	eCalendarClassDiv.className += ' class_Credential_Conflict';
																}
															}
															catch(err) {
																console.log(`${PC}Element ${calendar_class_div_id} does not exist.`,CE);
															}
															//break credential_dance;
														}
													} // Is there a credential conflict?
												} // Loop thru 2nd credintials.
											} // Loop thru 1st credintials.
										} else {
											if ( DEBUG_Conflicts ) { console.log(`${PC}credentials1.length = ${credentials1.length}, credentials2.length = ${credentials2.length}`,CL); }
										}
										if ( DEBUG_Conflicts ) { console.log(`${PC}END ${PC}Check for credintial conflicts.`,SE,CS); console.groupEnd(); if (credentialConflict) { console.log(`${PC}There are credential conflict(s).`,CW); } }
										// END Check for credintial conflicts.
										/**/
										/**/
										// Check for instructor conflicts.
										let instructorConflict = false;
										if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PC}Check for instructor conflicts.`,CS); }
										if ( instructors1.length && instructors2.length ) {
											if ( DEBUG_Conflicts ) { console.log(`${PC}instructors1 = ${JSON.stringify(instructors1)}`,CD); }
											if ( DEBUG_Conflicts ) { console.log(`${PC}instructors2 = ${JSON.stringify(instructors2)}`,CI); }
											instructorConflict = false;
											instructor_dance:
											for ( r1=0; r1<instructors1.length; r1++ ) { // Loop thru 1st instructors.
												instructor1 = instructors1[r1];
												for ( r2=0; r2<instructors2.length; r2++ ) { // Loop thru 2nd instructors.
													instructor2 = instructors2[r2];
													if ( DEBUG_Conflicts ) { console.log(`${PC}instructor1 = ${instructor1}, instructors2 = ${instructor2}`,CL); }
													if ( instructor1 === instructor2 ) { // Is there an instructor conflict?
														// There is a potential conflict. Need to test meeting dates.
														if ( ( SCMnow[scId][m1].sDate >= SCMnow[overlap.scId][m2].sDate && SCMnow[scId][m1].sDate <= SCMnow[overlap.scId][m2].eDate ) ||
																( SCMnow[scId][m1].eDate >= SCMnow[overlap.scId][m2].sDate && SCMnow[scId][m1].eDate <= SCMnow[overlap.scId][m2].eDate )
														) {
															instructorConflict = true;
														} else {
															if ( DEBUG_Conflicts ) { console.log(`${PC}Dates do not overlap ${ScheduleClass[scId].Course} = ${SCMnow[scId][m1].sDate}-${SCMnow[scId][m1].eDate}, ${ScheduleClass[overlap.scId].Course} = ${SCMnow[overlap.scId][m2].sDate}-${SCMnow[overlap.scId][m2].eDate}.`,CL); }
														}
														if ( instructorConflict ) {
															DayConflicts++;
															ClassConflicts++;
															CourseConflicts++;
															AnyConflicts++;
															if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[scId].Course} has a instructor conflict with ${ScheduleClass[overlap.scId].Course} for ${InstructorLookup[instructor1].Name}.`,CW); }
															try {
																if ( eCalendarClassDiv.className.indexOf('class_Instructor_Conflict') === -1 ) {
																	eCalendarClassDiv.className += ' class_Instructor_Conflict';
																}
															}
															catch(err) {
																console.log(`${PC}Element ${calendar_class_div_id} does not exist.`,CE);
															}
															break instructor_dance;
														}
													} // Is there an instructor conflict?
												} // Loop thru 2nd instructors.
											} // Loop thru 1st instructors.
										} else {
											if ( DEBUG_Conflicts ) { console.log(`${PC}instructors1.length = ${instructors1.length}, instructors2.length = ${instructors2.length}`,CL); }
										}
										if ( DEBUG_Conflicts ) { console.log(`${PC}END ${PC}Check for instructor conflicts.`,SE,CS); console.groupEnd(); if (instructorConflict) { console.log(`${PC}There are instructor conflict(s).`,CW); } }
										/**/
										
										/**/
										// Check for room conflicts.
										let roomConflict = false;
										if ( DEBUG_Conflicts ) { console.groupCollapsed(`${PC}Check for room conflicts.`,CS); }
										if ( rooms1.length && rooms2.length ) {
											if ( DEBUG_Conflicts ) { console.log(`${PC}rooms1 = ${JSON.stringify(rooms1)}`,CD); }
											if ( DEBUG_Conflicts ) { console.log(`${PC}rooms2 = ${JSON.stringify(rooms2)}`,CI); }
											roomConflict = false;
											//room_dance:
											for ( r1=0; r1<rooms1.length; r1++ ) { // Loop thru 1st rooms.
												room1 = rooms1[r1];
												for ( r2=0; r2<rooms2.length; r2++ ) { // Loop thru 2nd rooms.
													room2 = rooms2[r2];
													if ( DEBUG_Conflicts ) { console.log(`${PC}room1 = ${room1}, rooms2 = ${room2}`,CL); }
													if ( room1 === room2 ) { // Is there an room conflict?
														// There is a potential conflict. Need to test meeting dates.
														if ( ( SCMnow[scId][m1].sDate >= SCMnow[overlap.scId][m2].sDate && SCMnow[scId][m1].sDate <= SCMnow[overlap.scId][m2].eDate ) || 
																( SCMnow[scId][m1].eDate >= SCMnow[overlap.scId][m2].sDate && SCMnow[scId][m1].eDate <= SCMnow[overlap.scId][m2].eDate )
														) {
															roomConflict = true;
														} else {
															if ( DEBUG_Conflicts ) { console.log(`${PC}Dates do not overlap ${ScheduleClass[scId].Course} = ${SCMnow[scId][m1].sDate}-${SCMnow[scId][m1].eDate}, ${ScheduleClass[overlap.scId].Course} = ${SCMnow[overlap.scId][m2].sDate}-${SCMnow[overlap.scId][m2].eDate}.`,CL); }
														}
														if ( roomConflict ) {
															DayConflicts++;
															ClassConflicts++;
															CourseConflicts++;
															AnyConflicts++;
															if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[scId].Course} has a room conflict with ${ScheduleClass[overlap.scId].Course} for ${room1}.`,CW); }
															try {
																if ( eCalendarClassDiv.className.indexOf('class_Room_Conflict') === -1 ) {
																	eCalendarClassDiv.className += ' class_Room_Conflict';
																}
															}
															catch(err) {
																console.log(`${PC}Element ${calendar_class_div_id} does not exist.`,CE);
															}
															//break room_dance;
														}
													} // Is there an room conflict?
												} // Loop thru 2nd rooms.
											} // Loop thru 1st rooms.
										} else {
											if ( DEBUG_Conflicts ) { console.log(`${PC}rooms1.length = ${rooms1.length}, rooms2.length = ${rooms2.length}`,CL); }
										}
										if ( DEBUG_Conflicts ) { console.log(`${PC}END ${PC}Check for room conflicts.`,SE,CS); console.groupEnd(); if (roomConflict) { console.log(`${PC}There are room conflict(s).`,CW); } }
										/**/
									} else { // Is this the overlaping meeting?
										//if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[overlap.scId].Course} class meeting[${m2}] scmId ${SCMnow[overlap.scId][m2].scmId} does not match overlap.scmId ${overlap.scmId}.`,CF); }
									} // Is this the overlaping meeting?
								} // Loop thru overlap meetings.
							if ( DEBUG_Conflicts ) { console.log(`${PC}END ${PC}${ScheduleClass[overlap.scId].Course}`,SE,CL); console.groupEnd(); if (CourseConflicts) { console.log(`${PC}There are ${CourseConflicts} conflict(s) with ${ScheduleClass[overlap.scId].Course}.`,CW); } }
						} // Loop thru overlaps.
					} else { // Does the first class meeting meet today?
						//if ( DEBUG_Conflicts ) { console.log(`${PC}${ScheduleClass[scId].Course} class meeting ${m1} does not meet on ${day}.`,CF); }
					} // Does the first class meeting meet today?
				} // Loop thru first class meetings.
				if ( DEBUG_Conflicts ) { console.log(`${PC}END ${PC}${ScheduleClass[scId].Course}`,SE,CD); console.groupEnd(); if (ClassConflicts) { console.log(`${PC}There are ${ClassConflicts} class conflict(s).`,CW); } }

			} else {
				if ( DEBUG_Conflicts ) { console.log(PC+`${ScheduleClass[EVENTS_OVERLAPPING[eoId].scId].Course}, scmId = ${EVENTS_OVERLAPPING[eoId].scmId}, has no overlaps.`,CT); }
			}
		}} // Loop thru 1st EVENTS_OVERLAPPING.
		if ( DEBUG_Conflicts ) { console.groupEnd(); console.log(`${PE}Check ${day} for conflicts.`,SE,ST); if (DayConflicts) { console.log(`${PC}${day} has ${DayConflicts} conflicts.`,CW); } }
	} // Loop thru ScheduleViewDays days.
	// END Highlight conflicts.
	if ( DEBUG_Conflicts ) { console.log(`${PC}END ${PC}Highlight conflicts.`,SE,CD); console.groupEnd(); }
	/**/
	if ( DEBUG_MultipleNone || DEBUG_Conflicts ) { console.log(`${PC}END ${PC}DisplaySchedule_Highlight_Conflicts`,SE,ST); console.groupEnd(); if (AnyConflicts) { console.log(`${PC}There are ${AnyConflicts} conflicts.`,CW); } }
} // END DisplaySchedule_Highlight_Conflicts.

// DisplaySchedule_Highlight_Credentials()
// Highlight the different credential courses and credential/year courses.
var cColors = ['FF2800', 'FF003F', 'FF6347', 'FB4F14', 'FFA500', 'E48400', 'E4D00A', 'FBEC5D', 'FFFF00', '7FFF00', '00FF00', '4CBB17', 'B2FFFF', '7DF9FF', '00FFFF', 'DF73FF', 'D19FE8', 'F4BBFF', 'FE4EDA', 'FF00FF', 'FF1493'];
function DisplaySchedule_Highlight_Credentials() {
	var DEBUG = DEBUG_ON;
	let DEBUG_Conflicts = false;
	if ( DEBUG ) { console.group(`${PC}DisplaySchedule_Highlight_Credentials[]`,CG); }//Collapsed
	let credentialYearsDone = [];
	for ( var scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClasses.
		let courseId = ScheduleClass[scId].courseId;
		let credentials = Course[courseId].credentials; // eg: [ {Id:1, Yr:1}, {Id:2, Yr:1} ]
		for (let ci = 0; ci < credentials.length; ci++) { // Loop thru Course credentials.
			let courseCredentialYear = credentials[ci].Id.toString() + ':' + credentials[ci].Yr.toString();
			if (credentialYearsDone.indexOf(courseCredentialYear) == -1 ) { // Have we not checked this courseCredentialYear?
				credentialYearsDone.push(courseCredentialYear); // Remember we did this one.
				for ( var scId2 in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId2)){ // Loop thru ScheduleClasses again looking for conflict.
					if (scId != scId2) { // Is this not the same class?
						let courseId2 = ScheduleClass[scId].courseId;
						let credentials2 = Course[courseId].credentials;
						let credentialConflict = false;
						for (let ci = 0; ci < credentials2.length; ci++) { // Loop thru credentials2.
							let courseCredentialYear2 = credentials[ci].Id.toString() + ':' + credentials[ci].Yr.toString();
							if (courseCredentialYear == courseCredentialYear2) { // Are the two credentials the same?
								// Check for day/time conflict.
								
							} // Are the two credentials the same?
						} // Loop thru credentials2.
					} // Is this not the same class?
				}} // Loop thru ScheduleClasses again looking for conflict.
				
			} // Have we not checked this courseCredentialYear?
		} // Loop thru Course credentials.
	}} // Loop thru ScheduleClass.
	
	if ( DEBUG ) { console.groupEnd(); }
} // END DisplaySchedule_Highlight_Credentials.

// DisplayScheduleShowHide()
// Show or hide the scheduleHead, scheduleTimes, and scheduleCells and calculate left and width of cells.
// U & S day cells are hidden for 'Work week' view. All cells are shown for 'Full week' view.
// All cells in a row are hidden if before begin or after end times.
// All cells in a row are hidden if the time is not evenly divisible by the ScheduleTimeIncrement.
function DisplayScheduleShowHide() {
	var DEBUG_DisplayScheduleShowHide_Cell = false;
	var DEBUG_DisplayScheduleShowHide_Time = false;
	var DEBUG_DisplayScheduleShowHide_Wide = false;
	if ( DEBUG_DisplayScheduleShowHide_Cell || DEBUG_DisplayScheduleShowHide_Time || DEBUG_DisplayScheduleShowHide_Wide ) { console.warn('DisplayScheduleShowHide[]'); }
	var scheduleCells;
	var scheduleTimes;
	var scheduleCellindex;
	//var csClassName; // unused 2022/04/06 jfm
	//var calendarCells; // unused 2022/04/06 jfm
	//var dayIndex; // unused 2022/04/06 jfm
	//var calendarCell; // unused 2022/04/06 jfm
	//var setWidth; // unused 2022/04/06 jfm
	//var setWidthdivWidthDivisor; // unused 2022/04/06 jfm
	var ScheduleCellDay;
	var ScheduleCellId;
	var scheduleHeadindex;
	var ScheduleTimeBegin_mTime = parseInt(ScheduleTimeBegin) * 60;
	var ScheduleTimeEnd_mTime = parseInt(ScheduleTimeEnd) * 60;
	var scheduleTimeindex;
	if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('ScheduleTimeBegin_mTime='+ScheduleTimeBegin_mTime); }
	if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('ScheduleTimeEnd_mTime='+ScheduleTimeEnd_mTime); }
	// BEGIN Show all scheduleHeads on the right day.
	scheduleHeads = document.getElementsByClassName('scheduleHead'); // Get scheduleHeads.
	if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('scheduleHeads.length='+scheduleHeads.length); }
	for ( scheduleHeadindex=0; scheduleHeadindex<scheduleHeads.length; scheduleHeadindex++ ) { // Loop thru scheduleHeads.
		if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('scheduleHeads['+scheduleHeadindex+'].id='+scheduleHeads[scheduleHeadindex].id); }
		ScheduleCellId = scheduleHeads[scheduleHeadindex].id;
		ScheduleCellDay = ScheduleCellId.substring(0,1);
		if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('ScheduleCellDay='+ScheduleCellDay); }
		if ( ScheduleCellDay ) { // Is this a scheduleHead day (not the time).
			if ( ScheduleViewDays.indexOf(ScheduleCellDay) !== -1 ) { // Should this day be viewed?
				// Yes, check for scheduleHead only.
				scheduleHeads[scheduleHeadindex].className = 'scheduleHead';
				if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('Show this scheduleHead '+ScheduleCellId); }
			} else { // Should this day be viewed?
				// No, Hide this scheduleHead.
				scheduleHeads[scheduleHeadindex].className = 'scheduleHead hiddenz';
				if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('Hide this scheduleHead '+ScheduleCellId); }
			} // Should this day be viewed?
			//scheduleHeads[scheduleHeadindex].style.width = '50px';
		}
	} // Loop thru scheduleHeads.
	// END Show all scheduleHeads on the right day.
	// BEGIN Show all scheduleTimes between schedule times.
	scheduleTimes = document.getElementsByClassName('scheduleTime'); // Get scheduleTimes.
	if ( DEBUG_DisplayScheduleShowHide_Time ) { console.log('scheduleTimes.length='+scheduleTimes.length); }
	for ( scheduleTimeindex=0; scheduleTimeindex<scheduleTimes.length; scheduleTimeindex++ ) { // Loop thru scheduleTimes.
		if ( DEBUG_DisplayScheduleShowHide_Time ) { console.log('scheduleTimes['+scheduleTimeindex+'].id='+scheduleTimes[scheduleTimeindex].id); }
		var ScheduleTimeId = scheduleTimes[scheduleTimeindex].id;
		var ScheduleTime_mTime = parseInt(ScheduleTimeId.substring(1));
		if ( DEBUG_DisplayScheduleShowHide_Time ) { console.log('ScheduleTime_mTime='+ScheduleTime_mTime); } //ScheduleViewDays
		var ScheduleTime_mTimeIncrement =  parseInt( ScheduleTime_mTime / parseInt(ScheduleTimeIncrement) ) * parseInt(ScheduleTimeIncrement);
		if ( DEBUG_DisplayScheduleShowHide_Time ) { console.log('ScheduleTime_mTimeIncrement='+ScheduleTime_mTimeIncrement); } //ScheduleViewDays
		// Yes, Show this scheduleTime.
		if ( ScheduleTime_mTime === ScheduleTime_mTimeIncrement && ScheduleTime_mTime >= ScheduleTimeBegin_mTime && ScheduleTime_mTime <= ScheduleTimeEnd_mTime ) { // Should this time be viewed?
			// Yes, Show this scheduleTime.
			scheduleTimes[scheduleTimeindex].className = 'scheduleTime';
			if ( DEBUG_DisplayScheduleShowHide_Time ) { console.log('Show this scheduleTime '+ScheduleTimeId); }
		} else {
			// No, Hide this scheduleTime.
			if ( !isNaN(ScheduleTime_mTime) ) {
				scheduleTimes[scheduleTimeindex].className = 'scheduleTime hiddeny';
				if ( DEBUG_DisplayScheduleShowHide_Time ) { console.log('Hide this scheduleTime '+ScheduleTimeId); }
			}
		}
	} // Loop thru scheduleTimes.
	// END Show all scheduleTimes between schedule times.
	// BEGIN Show all scheduleCells on the right day and between schedule times.
	scheduleCells = document.getElementsByClassName('scheduleCell'); // Get scheduleCells.
	if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('scheduleCells.length='+scheduleCells.length); }
	for ( scheduleCellindex=0; scheduleCellindex<scheduleCells.length; scheduleCellindex++ ) { // Loop thru scheduleCells.
		if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('scheduleCells['+scheduleCellindex+'].id='+scheduleCells[scheduleCellindex].id); }
		ScheduleCellId = scheduleCells[scheduleCellindex].id;
		ScheduleCellDay = ScheduleCellId.substring(0,1);
		if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('ScheduleCellDay='+ScheduleCellDay); }
		if ( ScheduleCellDay ) {
			var ScheduleCell_mTime = parseInt(ScheduleCellId.substring(1));
			if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('ScheduleCell_mTime='+ScheduleCell_mTime); }//ScheduleViewDays
			var ScheduleCell_mTimeIncrement =  parseInt( ScheduleCell_mTime / parseInt(ScheduleTimeIncrement) ) * parseInt(ScheduleTimeIncrement);
			if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('ScheduleCell_mTimeIncrement='+ScheduleCell_mTimeIncrement); } //ScheduleViewDays
			if ( ScheduleViewDays.indexOf(ScheduleCellDay) !== -1 ) { // Should this day be viewed?
				// Yes, check for scheduleCell only.
				if ( ScheduleCell_mTime === ScheduleCell_mTimeIncrement && ScheduleCell_mTime >= ScheduleTimeBegin_mTime && ScheduleCell_mTime <= ScheduleTimeEnd_mTime ) { // Should this time be viewed?
					// Yes, Show this scheduleCell.
					scheduleCells[scheduleCellindex].className = 'scheduleCell';
					if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('Show this scheduleCell '+ScheduleCellId); }
				} else {
					// No, Hide this scheduleCell.
					scheduleCells[scheduleCellindex].className = 'scheduleCell hiddeny';
					if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('Hide this scheduleCell '+ScheduleCellId); }
				}
			} else { // Should this day be viewed?
				// No, Hide this scheduleCell.
				scheduleCells[scheduleCellindex].className = 'scheduleCell hiddenx';
				if ( DEBUG_DisplayScheduleShowHide_Cell ) { console.log('Hide this scheduleCell '+ScheduleCellId); }
			} // Should this day be viewed?
			//scheduleCells[scheduleCellindex].style.width = '50px';
		}
	} // Loop thru scheduleCells.
	// END Show all scheduleCells on the right day and between schedule times.
	// Calculate left and width for day.
	let schedulecontainerBounds = ElementBounds('schedulecontainer','schedule.js 846');
	if ( DEBUG_DisplayScheduleShowHide_Wide ) { console.log('schedulecontainerBounds left='+schedulecontainerBounds.left+' top='+schedulecontainerBounds.top+' right='+schedulecontainerBounds.right+' bottom='+schedulecontainerBounds.bottom+' width='+schedulecontainerBounds.width+' height='+schedulecontainerBounds.height); }
	var ScheduleMinuteStart = ScheduleTimeBegin * 60;
	if ( DEBUG_DisplayScheduleShowHide_Wide ) { console.log('ScheduleViewDays='+ScheduleViewDays+' ScheduleMinuteStart='+ScheduleMinuteStart); }
	let cBounds;
	let tdBounds;
	for ( var d1=0; d1<ScheduleViewDays.length; d1++ ) { // Loop thru ScheduleViewDays.
		var day = ScheduleViewDays[d1];
		cBounds = ElementBounds('schedulecontainer'); // Get location of the schedule.
		tdBounds = ElementBounds(day+ScheduleMinuteStart,'schedule.js 1151'); // Get location of top schedule cell for this day.
		//console.log('tdBounds='+JSON.stringify(tdBounds));
		if ( DEBUG_DisplayScheduleShowHide_Wide ) { console.log(day+' cBounds left='+cBounds.left+' top='+cBounds.top+' right='+cBounds.right+' bottom='+cBounds.bottom+' width='+cBounds.width+' height='+cBounds.height); }
		if ( DEBUG_DisplayScheduleShowHide_Wide ) { console.log(day+' tdBounds left='+tdBounds.left+' top='+tdBounds.top+' right='+tdBounds.right+' bottom='+tdBounds.bottom+' width='+tdBounds.width+' height='+tdBounds.height); }
		ScheduleTop = tdBounds.top - cBounds.top;
		ScheduleDayTimePositions[day] = { left:tdBounds.left - cBounds.left, width:tdBounds.width };
	} // Loop thru ScheduleViewDays.
	if ( DEBUG_DisplayScheduleShowHide_Wide ) { console.log('ScheduleTop='+ScheduleTop+' ScheduleDayTimePositions='+JSON.stringify(ScheduleDayTimePositions)); }
	var calendar_arranged = document.getElementsByClassName('calendar_arranged');
	for ( let i=0; i<calendar_arranged.length; i++) {
		let this_calendar_meeting = calendar_arranged[i];
		this_calendar_meeting.style.width = tdBounds.width + 'px';
	}
} // END DisplayScheduleShowHide.

// Events_Add( day )
// Add events for this day to EVENTS_TO_DISPLAY.
function Events_Add( day ) {
	var DEBUG = false;
	//if ( day === 'T' ||  day === 'H' ) { DEBUG = true; }
	if ( DEBUG ) { console.groupCollapsed(`${PC}Events_Add[day=${day}]`,CG); }//
	let begin,
			ccmTime,
			d1,
			divId,
			end,
			m1,
			minutesOffset = ScheduleTimeBegin * 60,
			modifiedEvents = 0;//,
			//sameClass // unused 2022/04/06 jfm
	// Load ClassMeetings into EVENTS_TO_DISPLAY for positioning schedule classes.
	let scId1;
	let length = EVENTS_ORDERED.length;
	if ( DEBUG ) { console.log(`${PC}length=${length} EVENTS_ORDERED=${JSON.stringify(EVENTS_ORDERED)}`,CL); }
	for ( var i=0; i<length; i++ ) { // Loop thru ordered ScheduleClasses.
		scId1 = EVENTS_ORDERED[i];
		if ( DEBUG ) { console.log(`${PC}scId1=${scId1}`,CI); }
		if ( DEBUG ) { console.log('ScheduleClass['+scId1+'].courseId='+ScheduleClass[scId1].courseId+' Section='+ScheduleClass[scId1].Section+' SCMnow['+scId1+']='+SCMnow[scId1]); }
		let cmLength = SCMnow[scId1].length;
		//console.log(`${PC}cmLength=${cmLength}`,CI);
		for ( m1=0; m1<cmLength; m1++ ) { // Loop thru class meetings.
			if ( DEBUG ) { console.log("\t"+' SCMnow['+scId1+']['+m1+']='+JSON.stringify(SCMnow[scId1][m1])); }
			begin = ConvertTimeToMinutes(SCMnow[scId1][m1].bTime);
			if ( !isNaN(begin) ) {
				ccmTime = begin;
			} else {
				ccmTime = 0;
			}
			SCMnow[scId1][m1].tdMinute = parseInt( begin / ScheduleTimeIncrement ) * ScheduleTimeIncrement;
			begin -= minutesOffset;
			end = ConvertTimeToMinutes(SCMnow[scId1][m1].eTime) - minutesOffset;
			if ( DEBUG ) { console.log('begin='+begin+' end='+end+' ccmTime='+ccmTime); }
			for ( d1=0; d1<SCMnow[scId1][m1].days.length; d1++) { // Loop thru meeting days.
				modifiedEvents = 1;
				//ccmTime = ConvertTimeToMinutes(SCMnow[scId1][m1].bTime);
				divId = 'calendar_class_'+scId1+'_'+SCMnow[scId1][m1].days[d1]+ccmTime;
				let classMeetingDay = SCMnow[scId1][m1].days[d1];
				if ( day === classMeetingDay ) { // Does the day = the classMeetingDay?
					EVENTS_TO_DISPLAY.push({
						scId  : scId1,
						scmId : SCMnow[scId1][m1].scmId,
						divId : divId,
						day   : day,
						sDate : SCMnow[scId1][m1].sDate,
						eDate : SCMnow[scId1][m1].eDate,
						begin : begin,
						end   : end,
						position : EVENTS_TO_DISPLAY.length
					});
				} // Does the day = the classMeetingDay?
			} // Loop thru meeting days.
		} // Loop thru class meetings.
	} // Loop thru ordered ScheduleClasses.
	//} // Loop thru classes.
	//} // Loop thru classes.
	if ( DEBUG ) { console.log('EVENTS_TO_DISPLAY='+JSON.stringify(EVENTS_TO_DISPLAY)); }
			//we don't want to refresh the DOM if nothing changed
	if ( modifiedEvents ) {
		if ( DEBUG ) { console.groupEnd(); }
		return true;
	}
	// Return value tells us if the view was refreshed
	if ( DEBUG ) { console.groupEnd(); }
	return false;
} // END Events_Add.

// Events_Overlapping(day)
// Check all events for overlap and add to EVENTS_OVERLAPPING.
function Events_Overlapping(day) {
	var DEBUG = DEBUG_OFF;
	//if ( day ==='M') { DEBUG = DEBUG_ON; }
	if ( DEBUG ) { console.group(`${PC}Events_Overlapping[day=${day}]`,CG); }//Collapsed
	var currentBdate,
			currentBegin,
			currentDay,
			currentDivId,
			currentEdate,
			currentEnd,
			objectKey,
			overlappingEvent,
			overlappingKey;
	var l=EVENTS_TO_DISPLAY.length;
	for ( var i=0; i<l; i++ ) { // Loop thru EVENTS_TO_DISPLAY.
		currentDivId = EVENTS_TO_DISPLAY[i].divId;
		currentDay   = EVENTS_TO_DISPLAY[i].day;
		currentBdate = EVENTS_TO_DISPLAY[i].bDate;
		currentEdate = EVENTS_TO_DISPLAY[i].eDate;
		currentBegin = EVENTS_TO_DISPLAY[i].begin;
		currentEnd   = EVENTS_TO_DISPLAY[i].end;
		objectKey    = EVENTS_TO_DISPLAY[i].scmId;//currentBegin+'*'+currentEnd+'*'+EVENTS_TO_DISPLAY[i].position;
		//console.log(EVENTS_TO_DISPLAY[i]);
		EVENTS_OVERLAPPING[objectKey] = { divId: currentDivId, items: {}, length: 0, overlaps: [], scId: EVENTS_TO_DISPLAY[i].scId, scmId: EVENTS_TO_DISPLAY[i].scmId };
		if ( DEBUG ) { console.info(PC+TB+'Checking scmId:'+EVENTS_TO_DISPLAY[i].scmId+' day:'+currentDay+', begin:'+currentBegin+', end:'+currentEnd+' Course:'+ScheduleClass[EVENTS_TO_DISPLAY[i].scId].Course,CI); }
		if ( DEBUG ) { console.log("\t"+"\t"+'EVENTS_TO_DISPLAY['+i+']='+JSON.stringify(EVENTS_TO_DISPLAY[i])); }
		for ( var j=0; j<l; j+=1 ) { // Loop thru EVENTS_TO_DISPLAY.
			if ( j !== i ) { // Is this a different event?
				overlappingEvent = EVENTS_TO_DISPLAY[j];
				if ( DEBUG ) { console.log("\t"+"\t"+'Against scId:'+overlappingEvent.scId+' day:'+overlappingEvent.day+', begin:'+overlappingEvent.begin+', end:'+overlappingEvent.end); }
				/** /
				if ( DEBUG ) {
					console.log("\t\t"+'overlappingEvent.day === currentDay == '+(overlappingEvent.day === currentDay));
					console.log("\t\t"+'( overlappingEvent.begin >= currentBegin && overlappingEvent.begin <= currentEnd ) == '+(( overlappingEvent.begin >= currentBegin && overlappingEvent.begin <= currentEnd )));
					console.log("\t\t"+'( overlappingEvent.end   >= currentBegin && overlappingEvent.end   <= currentEnd ) == '+(( overlappingEvent.end   >= currentBegin && overlappingEvent.end   <= currentEnd )));
					console.log("\t\t"+'( currentBegin >= overlappingEvent.begin && currentBegin <= overlappingEvent.end ) == '+(( currentBegin >= overlappingEvent.begin && currentBegin <= overlappingEvent.end )));
					console.log("\t\t"+'( currentEnd   >= overlappingEvent.begin && currentEnd   <= overlappingEvent.end ) == '+(( currentEnd   >= overlappingEvent.begin && currentEnd   <= overlappingEvent.end )));
				}
				/**/
				if ( ( overlappingEvent.day === currentDay ) && // day is same.
						(
							( ( overlappingEvent.begin >= currentBegin && overlappingEvent.begin <= currentEnd ) ||	// other's begin is between current begin and end.
								( overlappingEvent.end   >= currentBegin && overlappingEvent.end   <= currentEnd )			// other's end is between current begin and end. 
							) ||
							( ( currentBegin >= overlappingEvent.begin && currentBegin <= overlappingEvent.end ) ||	// current begin is between other's begin and end.
								( currentEnd   >= overlappingEvent.begin && currentEnd   <= overlappingEvent.end )			// current end is between other's begin and end.
							)
						)
					) { // wraps other's begin and end.
					overlappingKey = overlappingEvent.scmId;//overlappingEvent.begin+'*'+overlappingEvent.end+'*'+overlappingEvent.position;
					EVENTS_OVERLAPPING[objectKey].items[overlappingKey] = 1;
					EVENTS_OVERLAPPING[objectKey].length += 1;
					EVENTS_OVERLAPPING[objectKey].overlaps.push({ day: overlappingEvent.day, scId: overlappingEvent.scId, scmId: overlappingEvent.scmId });
					if ( DEBUG ) { 
						console.warn("\t"+"\t"+'Overlap scId:'+overlappingEvent.scId+', scmId:'+overlappingEvent.scmId+' Course:'+ScheduleClass[overlappingEvent.scId].Course);
						console.log("\t"+"\t"+"\t"+'EVENTS_OVERLAPPING['+objectKey+']='+JSON.stringify(EVENTS_OVERLAPPING[objectKey]));
					}
				} 
			} // Is this a different event?               
		} // Loop thru EVENTS_TO_DISPLAY.
/** /
						 ( ( overlappingEvent.begin >= currentBegin && overlappingEvent.begin <= currentEnd ) || // begin is between other's begin and end.
							 ( overlappingEvent.end   >= currentBegin && overlappingEvent.end   <= currentEnd ) || // end is between other's begin and end.
							 ( overlappingEvent.begin <= currentBegin && overlappingEvent.end >= currentBegin ) || // wraps other's begin and end.
							 ( overlappingEvent.begin === currentBegin || overlappingEvent.end === currentEnd ) ) ) { // begin or end is the same
/**/
		//if (!overlappingEvent){
		//EVENTS_OVERLAPPING[objectKey] = null;
		//}
	} // Loop thru EVENTS_TO_DISPLAY.   
	if ( DEBUG ) { console.log("\t"+"\t"+day+' EVENTS_OVERLAPPING='+JSON.stringify(EVENTS_OVERLAPPING)); }
	if ( DEBUG ) { console.groupEnd(); }
} // END Events_Overlapping.

// Events_Prepare( day )
// Adds additional properties to EVENTS_TO_DISPLAY, so that they can be positioned properly on the schedule.
// Events with calculated position are added to EVENTS_READY for Events_Prepare_GetLeft().
function Events_Prepare( day ) {
	var DEBUG = false;
	let DEBUG_ORIGINAL = DEBUG;
	//if ( day === DAY_TO_DEBUG ) { DEBUG = DEBUG_ON; }
	let DEBUG_GROUPS = false; if (DEBUG_GROUPS) { DEBUG = DEBUG_ON; }
	if ( DEBUG || DAY_TO_DEBUG ) { console.groupCollapsed(`${PC}Events_Prepare[day=${day}]`,CG); }//.
	var //currentDay, // unused 2022/04/06 jfm
			currentEvent,
			eventKey,
			i,
			j,
			k,
			l,
			//heightMultiplier = ScheduleIncrementHeight / ScheduleTimeIncrement,
			//left, // unused 2022/04/06 jfm
			//overlappingEvents, // unused 2022/04/06 jfm
			scmId,
			scmId2,
			scmId3,
			width;
	EVENTS_READY = {};
	Events_Sort(EVENTS_TO_DISPLAY);
	let divWidthDivisor = {};
	// BEGIN Calculate and set calendar_class div width.
	// BEGIN Get event groups.
	let overlapGroups = [];
	let overlapGroupsIndex = -1;
	for ( scmId in EVENTS_OVERLAPPING ){if(EVENTS_OVERLAPPING.hasOwnProperty(scmId)){ // Loop thru EVENTS_OVERLAPPING.
		let currentEVENTS_OVERLAPPING = EVENTS_OVERLAPPING[scmId];
		// Check if class scmId is in overlapGroups.
		let overlapGroupsLength = overlapGroups.length;
		if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS overlapGroupsLength=${overlapGroupsLength}`,CS); }
		let inGroup = false;
		for ( j=0; j<overlapGroupsLength; j++) { // Loop thru overlapGroups.
			let thisGroup = overlapGroups[j];
			if ( DEBUG_GROUPS && day === DAY_TO_DEBUG) { console.log(`${PC}DEBUG_GROUPS thisGroup=${JSON.stringify(thisGroup)}`,CL); }
			for ( k=0; k<thisGroup.length; k++ ) {
				if ( thisGroup[k].indexOf(scmId) !== -1 ) {
					inGroup = true;
				}
			}
		} // Loop thru overlapGroups.
		if ( DEBUG_GROUPS && day === DAY_TO_DEBUG) { if (inGroup) { console.log(`${PC}DEBUG_GROUPS scmId=${scmId} inGroup=${inGroup}`,CT); } else { console.log(`${PC}DEBUG_GROUPS scmId=${scmId} inGroup=${inGroup}`,CF); } }
		if ( !inGroup ) { // Is this class scmId NOT in a group?
			// Create new group.
			overlapGroupsIndex++;
			overlapGroups[overlapGroupsIndex] = [];
			overlapGroups[overlapGroupsIndex].push(scmId);
			if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS Create new group overlapGroups[${overlapGroupsIndex}]=${overlapGroups[overlapGroupsIndex]}`,CD); }
			// Loop thru class items and see if they are in a group.
			let theseItems = currentEVENTS_OVERLAPPING.items;
			if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS theseItems=[${JSON.stringify(theseItems)}`,CA); }
			for ( scmId2 in  theseItems){if(theseItems.hasOwnProperty(scmId2)){ // Loop thru theseItems
				if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS Testing ${scmId2} for ${scmId}`,CI); }
				if ( scmId !== scmId2 ) {
					let isInGroup = false;
					overlapGroupsLength = overlapGroups.length;
					if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS overlapGroupsLength= ${overlapGroupsLength}`,CI); }
					for ( j=0; j<overlapGroupsLength; j++) { // Loop thru overlapGroups.
						let thisOverlapGroup = overlapGroups[j];
						if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS Is ${scmId2} in thisOverlapGroup=${thisOverlapGroup} ${( thisOverlapGroup.indexOf(scmId2)!== -1 )}`,CI); }
						if ( thisOverlapGroup.indexOf(scmId2)!== -1 ) {
							isInGroup = true;
							//if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS isInGroup=${isInGroup}`,CT); }
						}
					} // Loop thru overlapGroups.
					if ( DEBUG_GROUPS && day === DAY_TO_DEBUG) { if (isInGroup) { console.log(`${PC}DEBUG_GROUPS scmId2=${scmId2} isInGroup=${isInGroup}`,CT); } else { console.log(`${PC}DEBUG_GROUPS scmId2=${scmId2} isInGroup=${isInGroup}`,CF); } }
					if ( isInGroup ) {
						// scmId2 was in a group so scmId group should be removed and scmId added to scmId2 group.
						if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS Remove group [${overlapGroupsIndex}]}`,CD); }
						overlapGroups.pop();
						overlapGroupsIndex--;
						overlapGroups[overlapGroupsIndex].push(scmId); // Changed 2023-03-28 jfm overlapGroups[overlapGroupsIndex].push(scmId2);
						if ( day === DAY_TO_DEBUG ) { console.log(`${PC}Add ${scmId} overlapGroups[${overlapGroupsIndex}]=${overlapGroups[overlapGroupsIndex]}`,CD); }
					} else {
						overlapGroups[overlapGroupsIndex].push(scmId2);
						if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS Add ${scmId2} overlapGroups[${overlapGroupsIndex}]=${overlapGroups[overlapGroupsIndex]}`,CD); }
					}
				} else {
					if ( DEBUG_GROUPS && day === DAY_TO_DEBUG ) { console.log(`${PC}DEBUG_GROUPS Skip ${scmId2} == ${scmId}`,CW); }
				}
			}} // Loop thru theseItems
		} // Is this class scmId NOT in a group?
	}} // Loop thru EVENTS_OVERLAPPING.
	if ( day === DAY_TO_DEBUG) { console.log(`${PC}${day} overlapGroups=${JSON.stringify(overlapGroups)}`,CI); }
	//   END Get event groups.
	
	// BEGIN Count non overlaps.
	for ( i=0; i<overlapGroups.length; i++) { // Loop thru groups.
		let thisGroup = overlapGroups[i];
		if ( day === DAY_TO_DEBUG ) { console.log(`${PC}thisGroup=${thisGroup}`,CI); }
		let nonOverlapping = [];
		for ( j=0; j<thisGroup.length; j++) { // Loop thru group classes.
			scmId = thisGroup[j];
			if ( day === DAY_TO_DEBUG ) { console.groupCollapsed(`${PC}Checking scmId=${scmId}`,CG); }//
			for ( k=0; k<thisGroup.length; k++) { // Loop thru group classes again.
				scmId2 = thisGroup[k];
				if ( scmId !== scmId2 ) { // Is this a different scmId?
					// Check for overlap.
					if ( day === DAY_TO_DEBUG ) { console.log(`${PC}Test scmId=${scmId} vs scmId2=${scmId2}`,CD); }
					let inItems = false;
					let scmId2Items = EVENTS_OVERLAPPING[scmId2].items;
					if ( day === DAY_TO_DEBUG ) { console.log(`${PC}scmId2=${scmId2}.items= ${JSON.stringify(scmId2Items)}`,CI); }
					for ( scmId3 in scmId2Items ){if(scmId2Items.hasOwnProperty(scmId3)){ // Loop thru items.
						if ( day === DAY_TO_DEBUG ) { console.log(`${PC}Check scmId=${scmId} vs scmId3=${scmId3}`,CD); }
						if ( scmId === scmId3 ) {
							if ( day === DAY_TO_DEBUG ) { console.log(`${PC}${scmId} === ${scmId3}`,CD); }
							inItems = true;
						}
					}} // Loop thru items.
					if ( day === DAY_TO_DEBUG ) { console.log(`${PC}inItems=${inItems}`,CI); }
					if ( !inItems ) {
						if ( nonOverlapping.indexOf(scmId2) === -1){
							nonOverlapping.push(scmId2);
						}
					}
				} else {
					if ( day === DAY_TO_DEBUG ) { console.log(`${PC}Skip ${scmId} vs ${scmId2}`,CW); }
				} // Is this a different scmId?
			} // Loop thru group classes again.
			if ( day === DAY_TO_DEBUG ) { console.groupEnd(); }
		} // Loop thru group classes.
		if ( day === DAY_TO_DEBUG ) { console.log(`${PC}divWidthDivisor=${JSON.stringify(divWidthDivisor)}`,CC); }
		// Save div width divisors for each scmId.
		let widthDivisor = thisGroup.length - parseInt(nonOverlapping.length / 2);
		if ( day === DAY_TO_DEBUG ) { console.log(`${PC}${day} thisGroup=${thisGroup} nonOverlapping=${JSON.stringify(nonOverlapping)} widthDivisor=${widthDivisor}`,CI); }
		for ( k=0; k<thisGroup.length; k++) { // Loop thru group classes again.
			divWidthDivisor[thisGroup[k]] = widthDivisor;
		} // Loop thru group classes again.
	} // Loop thru groups.
	//   END Count non overlaps.
	//   END Calculate and set calendar_class div width.
	
	if ( DEBUG ) { console.log(`${PC}${day} divWidthDivisor=${JSON.stringify(divWidthDivisor)}`,CI); }
	// Store EVENTS_TO_DISPLAY values.
	if ( DEBUG ) { console.log('EVENTS_TO_DISPLAY='+JSON.stringify(EVENTS_TO_DISPLAY)); }
	for ( i=0, l=EVENTS_TO_DISPLAY.length; i<l; i+=1 ) { // Loop thru EVENTS_TO_DISPLAY.
		if ( DEBUG ) { console.log('EVENTS_TO_DISPLAY['+i+']='+JSON.stringify(EVENTS_TO_DISPLAY[i])); }
		currentEvent      = EVENTS_TO_DISPLAY[i];
		if ( DEBUG ) { console.log(`${PC}${day} currentEvent=${JSON.stringify(currentEvent)}`,CG); }
		eventKey          = currentEvent.scmId;
		width = ScheduleDayTimePositions[day].width / (divWidthDivisor[eventKey]);
		if ( day === DAY_TO_DEBUG  ) { console.log(`${PC}${day} eventKey=${eventKey} divisor=${divWidthDivisor[eventKey]} width=${width}`,CC); }
		let left = Events_Prepare_GetLeft(EVENTS_OVERLAPPING[eventKey], eventKey, day, width);
		// Store values in EVENTS_TO_DISPLAY[i].
		currentEvent.top          = currentEvent.begin;// * heightMultiplier;
		currentEvent.width        = width;
		currentEvent.left         = left;
		currentEvent.height       = ( currentEvent.end - currentEvent.begin );// * heightMultiplier;
		//currentEvent.contentWidth = currentEvent.width - 4;
		if ( DEBUG ) { console.log('currentEvent='+JSON.stringify(currentEvent)); }
		EVENTS_READY[eventKey]    = {
			left: left,
			width : width
		};
		if ( DEBUG ) { console.log('EVENTS_READY['+eventKey+']='+JSON.stringify(EVENTS_READY[eventKey])); }
	} // Loop thru EVENTS_TO_DISPLAY.
	if ( DEBUG ) { console.log('EVENTS_TO_DISPLAY='+JSON.stringify(EVENTS_TO_DISPLAY)); }
	if ( DEBUG ) { console.log('EVENTS_READY='+JSON.stringify(EVENTS_READY)); }
	if ( DEBUG ) { console.groupEnd(); }
} // END Events_Prepare.

// Events_Prepare_GetLeft( overlapObject, eventKey, day )
// Calculate left overlapping events.
// This function performs a few operations.
// It accepts an event object with overlapping events of event object to be rendered (let's call it E).
// First of all it checks if E has any overlapping events.
// If not - then we know that it will be positioned at x=0.
// If there are overlapping events we check if they overlap with each other as it's x position can be influenced (e2):
//
// ********
// *  e1  *  *******
// *      *  *     *  ********
// *      *  *  E  *  *  e3  *
// ********  *     *  ********
// ********  *******
// *  e2  *
// ********
// E overlaps 3 others: e1, e2, and e3.
// But e3 does not overlap e2.
// Finally we find the left position of E using the positions of events that were already positioned.
function Events_Prepare_GetLeft( overlapObject, eventKey, day, width ) {
	var DEBUG = DEBUG_OFF;
	if ( DEBUG ) { console.group(`${PC}Events_Prepare_GetLeft[overlapObject.divId=${overlapObject.divId} eventKey=${eventKey} day=${day}]`,CG); }//Collapsed
	if ( DEBUG ) { console.log(`${PC}overlapObject=${JSON.stringify(overlapObject)}`,CL); }
	var noncollidingEvents         = {},
	noncollidingEventsPairs    = 0,
	noncollidingEventIds    = [],
	left                    = 0,
	overlappingEventsCount = Events_Prepare_MaxOverlap(overlapObject, eventKey),//overlapObject.length,
	overlappingEventsAmount = overlapObject.length,
	overlappingIEvents,
	overlapReadyIEvent,
	startingLefts           = {},
	overlappingEventsAmountIds = [];
	if ( overlapObject ) { // Is there an overlap?
		if ( DEBUG ) { console.log('overlappingEventsAmount='+overlappingEventsAmount); }
		if ( DEBUG ) { console.log('overlapObject.items='+JSON.stringify(overlapObject.items)); }
		let MaxOverlaps = 0;
		var i, m;
		noncollidingEvents         = {};
		//MaxOverlaps = overlappingEventsCount;
		for( i in overlapObject.items ) {if (overlapObject.items.hasOwnProperty(i)){ // Loop thru overlap items.
			overlapReadyIEvent = EVENTS_READY[i];
			if ( DEBUG ) { console.log(`${PC}${i} EVENTS_READY[${i}]=${JSON.stringify(EVENTS_READY[i])}`,CC); }
			overlappingIEvents = EVENTS_OVERLAPPING[i].items;
			for ( m in overlapObject.items ) {if (overlapObject.items.hasOwnProperty(m)){ // Loop thru overlap items.
				if ( DEBUG ) { console.log('i='+i+' m='+m+' noncollidingEvents[i]='+noncollidingEvents[i]+' noncollidingEvents[m]='+noncollidingEvents[m]+' overlappingIEvents[m]='+overlappingIEvents[m]+' eventKey='+eventKey); }
				if ( overlapObject.items.hasOwnProperty(m) && m !== i ) {
					if ( DEBUG ) { console.log(`${PC}Check for collision`,CL); }
					if (  noncollidingEvents[m] !== i &&
								noncollidingEvents[i] !== m &&
								!overlappingIEvents[m] &&
								m !== eventKey &&
								i !== eventKey ) { // Do these events NOT collide?
						if ( DEBUG ) { console.info(`${PC}${i} and ${m} do not collide.`,CC); }
						noncollidingEvents[i]   = m;
						noncollidingEvents[m]   = i;
						// if in array to not add to pair
						if ( noncollidingEventIds.indexOf(i) === -1 && noncollidingEventIds.indexOf(m) === -1 ) {
							noncollidingEventsPairs += 1;
						}
						if ( noncollidingEventIds.indexOf(m) === -1 ) { noncollidingEventIds.push(m); }
						// store i m in array
					} else { // Do these events NOT collide?
						// No, they collide.
						if ( DEBUG ) { console.log(`${PC}Collide.`,CF); }
						if ( overlappingEventsAmountIds.indexOf(i) === -1 ) {
							overlappingEventsAmount++;
							if ( DEBUG ) { console.log(`${PC}overlappingEventsAmount=${overlappingEventsAmount}`,CD); }
							overlappingEventsAmountIds.push(i);
						}
					} // Do these events NOT collide?
				} else {
					if ( DEBUG ) { console.log(`${PC}Same.`,CT); }
					if ( overlappingEventsAmountIds.indexOf(i) === -1 ) {
						overlappingEventsAmount++;
						if ( DEBUG ) { console.log(`${PC}overlappingEventsAmount=${overlappingEventsAmount}`,CD); }
						overlappingEventsAmountIds.push(i);
					}
				}
			}} // Loop thru overlap items.
			if ( MaxOverlaps < overlappingEventsAmount ) { MaxOverlaps = overlappingEventsAmount; }
			if ( overlapReadyIEvent ) {
				if ( DEBUG ) { console.log('overlapReadyIEvent '+i+' left='+overlapReadyIEvent.left+' width='+overlapReadyIEvent.width); }
				startingLefts[overlapReadyIEvent.left] = 1;
			}
		}} // Loop thru overlap items.
		if ( DEBUG ) { console.log(`${PC}noncollidingEventsPairs=${noncollidingEventsPairs} noncollidingEventIds=${noncollidingEventIds} overlappingEventsAmount=${overlappingEventsAmount}`,CL); }
		overlappingEventsAmount -= noncollidingEventsPairs;
		if ( DEBUG ) { console.log(`${PC}ScheduleDayTimePositions[day].width=${ScheduleDayTimePositions[day].width} overlappingEventsAmount=${overlappingEventsAmount} overlappingEventsCount=${overlappingEventsCount}`,CL); }
		if ( DEBUG ) { console.log('startingLefts='+JSON.stringify(startingLefts)+' width='+width); }
		if ( DEBUG ) { console.log(`${PC}ScheduleDayTimePositions[day].width=${ScheduleDayTimePositions[day].width} MaxOverlaps=${MaxOverlaps}`,CL); }
		for (var k in startingLefts){if (startingLefts.hasOwnProperty(k)){
			if (startingLefts[left]) {
				left += width;
			}
		}}
	} // Is there an overlap?
	if ( DEBUG ) { console.log(`${PC}left=${left}`,CI); }
	if ( DEBUG ) { console.groupEnd(); }
	return left;
} // END Events_Prepare_GetLeft.

// Events_Prepare_MaxOverlap(overlapObject, eventKey)
// Calculate max overlap length for positioning schedule classes.
function Events_Prepare_MaxOverlap(overlapObject, eventKey) {
	var DEBUG = DEBUG_OFF;
	//if ( DEBUG_scmIds.indexOf(overlapObject.scmId) !== -1 ) { DEBUG = DEBUG_ON; }
	//console.log(`${PC}( DEBUG_scmIds.indexOf(${overlapObject.scmId}) !== -1 )=${( DEBUG_scmIds.indexOf(overlapObject.scmId) !== -1 )}`,CI);
	if ( DEBUG ) { console.group(`${PC}Events_Prepare_MaxOverlap[overlapObject=${JSON.stringify(overlapObject)} eventKey=${eventKey}]`,CG); }//Collapsed
	var MaxLength = overlapObject.length;
	if ( DEBUG ) { console.log("\t"+ScheduleClass[ClassMeeting_ScheduleClass[eventKey]].Course+'.length='+MaxLength); }
	//console.log(eventKey+' MaxLength='+MaxLength);
	for ( var index in overlapObject.items ) {if(overlapObject.items.hasOwnProperty(index)) {
		var thisLength = EVENTS_OVERLAPPING[index].length;
		if ( DEBUG ) { console.log("\t"+ScheduleClass[ClassMeeting_ScheduleClass[index]].Course+' '+EVENTS_OVERLAPPING[index].scmId+'.length='+thisLength); }
		MaxLength = Math.max(MaxLength,thisLength);
	}}
	//MaxLength = Math.min(MaxLength,overlapObject.length);
	//if ( MaxLength > overlapObject.length ) { MaxLength -= 1; }
	if ( DEBUG ) { console.log("\t"+'MaxLength='+MaxLength); }
	if ( DEBUG ) { console.groupEnd(); }
	return MaxLength;
} // END Events_Prepare_MaxOverlap.

// Events_Sort( EVENT )
// Sorts array of event objects by their begin and position parameters.
function Events_Sort( EVENT ) {
	EVENT.sort(function(a, b) {
		if ( a.begin > b.begin ) {
			return 1;
		} else if ( a.begin < b.begin ) {
			return -1;
		} else {
			if ( a.position > b.position ) {
				return 1;
			} else if ( a.position < b.position ) {
				return -1;
			}
		return 0;
		}
	});
} // END Events_Sort.

// AddClassMeeting()
// Add a new meeting to the Schedule Class dialog.
function AddClassMeeting(scheduleclassId) {
	var DEBUG = true;
	if ( DEBUG ) { console.warn('AddClassMeeting[scheduleclassId='+scheduleclassId+']'); }
	if ( DEBUG ) { console.log('scheduleclassId='+scheduleclassId); }
	var eMeetingFieldset = document.getElementById('fldMeetings');
	// Create the new class meeting id.
	var ClassMeetingAddId = 'add'+	ClassMeetingIndex;
	ClassMeetingIndex++;
	// Save the new class meeting id.
	var scheduleclassmeetingIds = document.getElementById('hid_scheduleclassmeetingIds').value;
	if ( scheduleclassmeetingIds !== '' ) {
		document.getElementById('hid_scheduleclassmeetingIds').value = scheduleclassmeetingIds + ',' + ClassMeetingAddId;
	} else {
		document.getElementById('hid_scheduleclassmeetingIds').value = ClassMeetingAddId;
	}
	var _ClassMeetingAddId = '_'+ClassMeetingAddId; // Prepend the _ for use below.
	// Create the class meeting div.
	var div = document.createElement('div');
	div.id = 'id_classmeeting'+_ClassMeetingAddId;
	div.className = 'divClassMeeting';
	div.innerHTML = '';
	div.style.display = 'none';
	// Append new meeting in Schedule Class dialog.
	eMeetingFieldset.appendChild(div);
	// Get the meeting form via AJAX.
	URI = ROOT_http + '/Schedule/ScheduleClass/ScheduleClassForm.php?task=AddMeeting';
	URI += '&scheduleclassId='+scheduleclassId;
	URI += '&scmId='+ClassMeetingAddId;
	let preloadText = 'Getting class meeting';
	UpdateLoadingText = preloadText;
	let jsReturnCode = "AddClassMeeting_Done("+div.id+")";
	ScheduleClassOpenCount = 0;
	UpdateInclude(URI, div.id, preloadText, jsReturnCode);
} // END AddClassMeeting.

// AddClassMeeting_Done(divId)
// Wait until the Meeting loads and call ScheduleClassDialog_SetWidth().
function AddClassMeeting_Done(divId) {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.group(`${PC}AddClassMeeting_Done[divId=${divId}]`,CG); }//Collapsed
	if ( typeof divId === 'object' ) { // Is divId an object?
		divId = divId.id; // Change it to the object's id.
	} // Is divId an object?
	if ( DEBUG ) { console.warn('AddClassMeeting_Done[divId='+divId+']'); }
	if ( DEBUG ) { console.log("UpdateDOMelement.innerHTML.indexOf('Load Meeting OK')="+UpdateDOMelement.innerHTML.indexOf('Load Meeting OK')); }
	if ( UpdateDOMelement.innerHTML.indexOf('Load Meeting OK') !== -1 ) { // Did the dialog contents load OK?
		// Yes.
		console.log(`${divId}.style.display = 'block'`);
		document.getElementById(divId).style.display = 'block';
		ScheduleClassDialog_SetWidth('AddClassMeeting_Done 1196');
		var divIdParts = divId.split('_');
		var class1meetingStartDateId = 'inp_class1meetingStartDate_'+divIdParts[2];
		if ( document.getElementById(class1meetingStartDateId) ) {
			document.getElementById(class1meetingStartDateId).focus();
		}
		Validate_ScheduleClass();
	} else { // Did the dialog contents load OK?
		// No, try again.
		if ( ScheduleClassOpenCount < 5 ) {
			ScheduleClassOpenCount++;
			if ( DEBUG ) { console.log('ScheduleClassOpenCount='+ScheduleClassOpenCount); }
			//UpdateInclude(URI, divId); // The preloadText is stored in the global UpdateLoadingText, and jsReturnCode is in the global UpdateReturnCode.
			setTimeout(function(){AddClassMeeting_Done(divId);},ScheduleClassOpenCount*100);
		} else {
			//alert('AddClassMeeting_Done: Never got return from URI='+URI+' divId='+divId);
			document.getElementById(divId).remove();
			ClassMeetingIndex--;
			let e_errorDiv = document.getElementById('errorDiv');
			e_errorDiv.innerHTML = `ERROR: There was a problem communicating with the server.

Unable to get new class meeting information within 1 second.
Please try again. If this error continues, please notify the site Administrator.`;
			ttLoad(e_errorDiv, '', '', 'error', true);
		}
	} // Did the dialog contents load OK?
	if ( DEBUG ) { console.log(`${PC}END ${PC}function AddClassMeeting_Done`,SE,ST); console.groupEnd(); }
} // END AddClassMeeting_Done.

// HighlightLikeMe()
// Highlight all sibling class meetings with something to make them noticeable.
function HighlightLikeMe(evt) {
	let DEBUG = false;
	if ( evt.target !== this ) { return; }
	let e = evt.target;
	//let e1 = evt.toElement || evt.relatedTarget;
	if ( DEBUG ) { console.group(`${PC}HighlightLikeMe[e.id=${e.id}]`,CG); }//Collapsed
	//console.clear(); 			 background: linear-gradient(to bottom, var(--default-background) 25%, #ff0 100%)
	let idParts = e.id.split('_');
	let scId = idParts[2];
	if ( DEBUG ) { console.log(`${PC}scId=${scId}`,CI); }
	let i;
	let j;
	if ( typeof HighlightLikeMe.idsToHighlight == 'undefined' ) {
		HighlightLikeMe.idsToHighlight = [];
	}
	HighlightLikeMe.idsToHighlight = [e.id];
	for ( i=0; i<SCMnow[scId].length; i++ ) { // Loop thru ClassMeetings.
		let classMeeting = SCMnow[scId][i];
		let mTime = ConvertTimeToMinutes(classMeeting.bTime);
		if ( DEBUG ) { console.log(`${PC}mTime=${mTime} classMeeting.days.length=${classMeeting.days.length}`,CL); }// classMeeting=${JSON.stringify(classMeeting)}
		if ( !isNaN(mTime) ) { // Is the mTime valid?
			if ( classMeeting.days.length > 0  ) { // Does this classMeeting have days?
				// Yes, use the days to build the ids.
				for ( j =-0; j<classMeeting.days.length; j++ ) { // Loop thru the days.
					let day = classMeeting.days[j];
					let newId = `calendar_class_${scId}_${day}${mTime}`;
					if ( DEBUG ) { console.log(`${PC}newId=${newId} day=${day}`,CL); }
					HighlightLikeMe.idsToHighlight.push(newId);
				} // Loop thru the days.
			} // Does this classMeeting have days?
		} // Is the mTime valid?
	} // Loop thru ClassMeetings.
	if ( DEBUG ) { console.log(`${PC}idsToHighlight=${HighlightLikeMe.idsToHighlight}`,CI); }
	// Highlight the class meetings.
	for ( i=0; i<HighlightLikeMe.idsToHighlight.length; i++ ) {
		let eToHighlight = document.getElementById(HighlightLikeMe.idsToHighlight[i]);
		eToHighlight.style.boxShadow = '0 0 10px 8px blue';
		eToHighlight.style.zIndex = 20;
		eToHighlight.style.marginRight = '15px';
		eToHighlight.style.outline = 'blue solid 4px';
	}
	if ( DEBUG ) { console.groupEnd(); }
} // END HighlightLikeMe.

// RemoveChildren(e)
// Remove all child elements from e.
function RemoveChildren(e) {
	let c = e.childNodes;
	let l = c.length - 1;
	for( let i = l; i >= 0; i-- ) {
		e.removeChild(c[i]);
	}
} // END RemoveChildren

// ScheduleChange()
// Display the schedule change form.
function ScheduleChange(importClasses='') {
	var DEBUG_ScheduleChange = true;
	if ( DEBUG_ScheduleChange ) { console.warn('ScheduleViewSettings[importClasses='+importClasses+']'); }
	var eId = 'div_ScheduleFunctionsContainer';
	var e = document.getElementById(eId);
	var eDisplay = e.style.display; // Get schedulecontainer display.
	if ( DEBUG_ScheduleChange ) { console.log('eDisplay='+eDisplay); }
	if ( DEBUG_ScheduleChange && eDisplay === 'block' ) { console.log("e.innerHTML.indexOf('Change or create schedule')="+e.innerHTML.indexOf('Change or create schedule')); }
	if ( importClasses === '' && eDisplay === 'block' && e.innerHTML.indexOf('Change or create schedule') !== -1 ) {
		ScheduleTaskShow('ScheduleChange 882');
		return false;
	} else {
		ScheduleTaskHide();
	}
	switch ( importClasses ) { // switch importClasses.
		case '':
			URI = ROOT_http +'/Schedule/ScheduleChange/ScheduleChange.php';
			let preloadText = '<br><br><span class="bold info">Getting schedule form. Please wait ...</span><br><br><br>';			
			UpdateInclude(URI, eId, preloadText);
			//setTimeout(DisplaySchedule,50);
			window.scrollTo(0, 0);
		break;
		case 'Import classes':
			
			break;
		case 'Cancel':
			document.getElementById(eId).style.display = 'none';
			ScheduleTaskShow('ScheduleChange 903');
		break;
	} // switch importClasses.
	return false;
} // END ScheduleChange

// ScheduleChange_ChangeScheduleButtonCheck(e)
// Enable/disable Change schedule button.
function ScheduleChange_ChangeScheduleButtonCheck(e) {
	var scheduleIdSelected = e.value;
	console.log('scheduleIdSelected='+scheduleIdSelected);
	if ( scheduleIdSelected ) {
		document.getElementById('btn_Change_schedule').disabled = false;
	} else {
		document.getElementById('btn_Change_schedule').disabled = true;
	}
} // END ScheduleChange_ChangeScheduleButtonCheck.

// ScheduleClass_MoveSingleMeetingDiv(by)
// Move class meeting div to the drop day/time, update db and redraw.
function ScheduleClass_MoveSingleMeetingDiv(by) {
	var DEBUG = true;
	if ( DEBUG ) { console.groupCollapsed(PC+`ScheduleClass_MoveSingleMeetingDiv[] by=${by}`,CG); }
	if ( DEBUG ) { console.log(PC+`dragElement = ${NL}"id":"${dragElement.id}" ${D_formatJSONstring(dragElement)}`,CL); }
	let scId = dragElement.scId;
	let scmId = dragElement.scmId;
	let divId = dragElement.id;
	let diDay = dragElement.droppedIn_day;
	let diMtime = parseInt(dragElement.droppedIn_mTime);
	let scmIndex = parseInt(dragElement.scmIndex);
	let scmNewIndex = parseInt(dragElement.scmNewIndex);
	if ( DEBUG ) { console.log('SCMnow['+scId+']='+D_formatJSONstring(SCMnow[scId])); }
	// Check for Error:
	let moveError = document.getElementById('dialogDiv').innerHTML.indexOf('Error:');
	if ( DEBUG ) { console.log('moveError='+moveError); }
	if ( moveError === -1 ) { // Is there no error?
		// Save original SCMnow.  Now done in site_js.php.
		//SCMold[scId] = CopyObject(SCMnow[scId]);		
		// Copy the SCMnow to a new meeting.
		SCMnow[scId][scmNewIndex] = CopyObject(SCMnow[scId][scmIndex]);
		// Modify the scmId.
		SCMnow[scId][scmNewIndex].scmId = `_${scmId}_${NewMeeting_scmId_Count}`;
		NewMeeting_scmId_Count++;
		// Remove the days from the current meeting.
		SCMnow[scId][scmIndex].days = [];
		// BEGIN Move meeting to new time for all days.
		// Get day and beginning mTime from id.
		let DivIdParts = divId.split('_');
		let From_day = DivIdParts[3].substr(0,1);
		let From_mTime = DivIdParts[3].substr(1);
		let Difference_day = GetWeekdayNumber(diDay) - GetWeekdayNumber(From_day); // Get the day difference.
		let Difference_mTime = diMtime - From_mTime; // Get the mTime difference.
		let diTimeBegin = ConvertMinutesToTime(diMtime);
		let lengthMin = CalcMinuteDiff(SCMnow[scId][scmNewIndex].bTime,SCMnow[scId][scmNewIndex].eTime);
		let mTimeEnd = parseInt(diMtime) + parseInt(lengthMin);
		let diTimeEnd = ConvertMinutesToTime(mTimeEnd);
		if ( DEBUG ) { console.log('diTimeBegin='+diTimeBegin+' lengthMin='+lengthMin+' mTimeEnd='+mTimeEnd+' diTimeEnd='+diTimeEnd); }
		// Change the schedule class meeting bTime, eTime, days, and div id.
		var NewDays = '';
		// Save the day and time differences.
		//let Difference_day = GetWeekdayNumber(dragElement.droppedIn_day) - GetWeekdayNumber(dragElement.original_day); // Get the day difference.
		//let Difference_mTime = dragElement.droppedIn_mTime - dragElement.original_mTime; // Get the mTime difference.
		if ( DEBUG ) { console.log('diDay='+diDay+' From_day='+From_day+' Difference_day='+Difference_day); }
		if ( DEBUG ) { console.log('diMtime='+diMtime+' From_mTime='+From_mTime+' Difference_mTime='+Difference_mTime); }
		SCMnow[scId][scmNewIndex].dayDiff = Difference_day;
		SCMnow[scId][scmNewIndex].mbTimeDiff = Difference_mTime;
		// Change the bTime and eTime.
		SCMnow[scId][scmNewIndex].bTime = diTimeBegin+':00';
		SCMnow[scId][scmNewIndex].eTime = diTimeEnd+':00';
		// Change the days, bTime and eTime innerHTML, divId, and days innerHTML.
		var DayNumber = 0;
		var DayscmNewIndex;
		for ( DayscmNewIndex in SCMnow[scId][scmNewIndex].days ){if(SCMnow[scId][scmNewIndex].days.hasOwnProperty(DayscmNewIndex)){ // Loop thru the days.
			DayNumber++;
			if ( DEBUG ) { console.log('SCMnow['+scId+']['+scmNewIndex+'].days['+DayscmNewIndex+']='+SCMnow[scId][scmNewIndex].days[DayscmNewIndex]); }
			var divId_Old = 'calendar_class_'+scId+'_'+SCMnow[scId][scmNewIndex].days[DayscmNewIndex]+From_mTime; // Same the old divId.
			var NewDayNumber = parseInt(GetWeekdayNumber(SCMnow[scId][scmNewIndex].days[DayscmNewIndex]))+Difference_day; // Calc the new day number.
			if ( DEBUG ) { console.log('NewDayNumber='+NewDayNumber); }
			var NewDayD = GetWeekdayD(NewDayNumber); // Calc the weekdayD.
			if ( DEBUG ) { console.log('NewDayD='+NewDayD); }
			NewDays += NewDayD; // Add new day to content for days innerHTML.
			SCMnow[scId][scmNewIndex].days[DayscmNewIndex] = NewDayD;
			var divId_New = 'calendar_class_'+scId+'_'+NewDayD+diMtime; // Calc the new divId.
			//SCMnow[scId][scmNewIndex].moveNewId = divId_New;
			if ( DEBUG ) { console.log('divId_Old='+divId_Old+' divId_New='+divId_New); }
			document.getElementById('bTime_'+scmId+'_'+DayNumber).innerHTML = ConvertTimeTo12hr(diTimeBegin); // Change the bTime innerHTML.
			document.getElementById('eTime_'+scmId+'_'+DayNumber).innerHTML = ConvertTimeTo12hr(diTimeEnd); // Change the eTime innerHTML.
			document.getElementById(divId_Old).id = divId_New; // Change the divId.
		}} // Loop thru the days.
		DayNumber = 0;
		for ( DayscmNewIndex in SCMnow[scId][scmNewIndex].days ){if(SCMnow[scId][scmNewIndex].days.hasOwnProperty(DayscmNewIndex)){ // Loop thru the days.
			DayNumber++;
			document.getElementById('days_'+scmId+'_'+DayNumber).innerHTML = NewDays; // Change the days innerHTML.
		}} // Loop thru the days.
		if ( DEBUG ) { console.log('SCMnow['+scId+']='+D_formatJSONstring(SCMnow[scId])); }
		DisplaySchedule('ScheduleClass_MoveSingleMeetingDiv~1916'); // Re-display the schedule.		
	} // Is there no eror?
	if ( DEBUG ) { console.log('SCMnow['+scId+']='+D_formatJSONstring(SCMnow[scId])); }
	if ( DEBUG ) { console.log(`${PC}END ${PC}ScheduleClass_MoveSingleMeetingDiv`,SE,ST);  console.groupEnd(); }
} // END ScheduleClass_MoveSingleMeetingDiv.

// ScheduleChange_CreateScheduleButtonCheck(e)
// Enable/disable Create schedule button.
function ScheduleChange_CreateScheduleButtonCheck() {
	var sessionIdSelected = document.getElementById('sel_sessionId').value;
	var departmentIdSelected = document.getElementById('sel_departmentId').value;
	var scheduleNameEntered = document.getElementById('inp_scheduleName').value;
	console.log('sessionIdSelected='+sessionIdSelected+' departmentIdSelected='+departmentIdSelected+' scheduleNameEntered='+scheduleNameEntered);
	if ( sessionIdSelected && departmentIdSelected && scheduleNameEntered ) {
		document.getElementById('btn_Create_new_schedule').disabled = false;
	} else {
		document.getElementById('btn_Create_new_schedule').disabled = true;
	}
} // END ScheduleChange_CreateScheduleButtonCheck.


// ScheduleClass_RemoveClassMeetingVerify(scmId, thisTask)
// Verify removal of class meeting.
function ScheduleClass_RemoveClassMeetingVerify(scmId, thisTask) {
	var DEBUG_ScheduleClass_RemoveClassMeetingVerify = true;
	if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('BEGIN ScheduleClass_RemoveClassMeetingVerify[scmId='+scmId+' thisTask='+thisTask+']'); }
	if ( typeof thisTask === 'undefined' ) {
		if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('Display div_RemoveClassMeetingVerify_'+scmId); }
		document.getElementById('div_RemoveClassMeetingVerify_'+scmId).style.display = 'block';
	} else if ( thisTask === 'yes' ) {
		// Yes clicked, remove class meeting.
		// Hide the div.
		document.getElementById('div_RemoveClassMeetingVerify_'+scmId).style.display = 'none';
		// Remove this class meeting from the DOM.
		var divId = 'id_classmeeting_'+scmId;
		if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('divId='+divId); }
		var div = document.getElementById(divId);
		div.parentNode.removeChild(div);
		ScheduleClassDialog_SetWidth('ScheduleClass_RemoveClassMeetingVerify 1309');
		// Remove it from scheduleclassmeetingIds.
		var scheduleclassmeetingIds = document.getElementById('hid_scheduleclassmeetingIds').value;
		if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('scheduleclassmeetingIds='+scheduleclassmeetingIds); }
		scheduleclassmeetingIds = scheduleclassmeetingIds.split(',');
		var scheduleclassmeetingIndex = scheduleclassmeetingIds.indexOf(scmId);
		if( scheduleclassmeetingIndex !== -1 ) {
			scheduleclassmeetingIds.splice(scheduleclassmeetingIndex, 1); // Remove the scmId.
		}
		scheduleclassmeetingIds = scheduleclassmeetingIds.toString();
		if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('scheduleclassmeetingIds='+scheduleclassmeetingIds); }
		document.getElementById('hid_scheduleclassmeetingIds').value = scheduleclassmeetingIds;
		if ( typeof ClassMeeting_ScheduleClass[scmId] !== 'undefined' ) {
			let scId = ClassMeeting_ScheduleClass[scmId];
			// Remove the calendar_class div from the DOM.
			let tdDay;
			let calendar_classId;
			let meetingIndex;
			//let i; // unused 2022/04/06 jfm
			for ( meetingIndex=0; meetingIndex<SCMnow[scId].length; meetingIndex++ ) { // Loop thru class meetings.
				var tdMin = ConvertTimeToMinutes(SCMnow[scId][meetingIndex].bTime);
				if ( SCMnow[scId][meetingIndex].scmId === scmId ) { // Is this the meeting we want to remove?
					for ( var d=0; d<SCMnow[scId][meetingIndex].days.length; d++ ) { // Loop thru days.
						tdDay = SCMnow[scId][meetingIndex].days[d];
						calendar_classId = 'calendar_class_'+scId+'_'+tdDay+tdMin;
						if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('calendar_classId='+calendar_classId); }
						var e_calendar_class = document.getElementById(calendar_classId);
						e_calendar_class.parentNode.removeChild(e_calendar_class); // Remove this calendar_class div from the DOM.
					} // Loop thru days.
				} // Is this the meeting we want to remove?
			} // Loop thru class meetings.
			// Remove the SCMnow javascript object.
			if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) {
				console.log('ClassMeeting_ScheduleClass['+scmId+']='+ClassMeeting_ScheduleClass[scmId]+' scId='+scId);
				console.log('SCMnow[scId]='+JSON.stringify(SCMnow[scId]));
			}
			for ( meetingIndex=0; meetingIndex<SCMnow[scId].length; meetingIndex++ ) {
				if ( SCMnow[scId][meetingIndex].scmId === scmId ) {
					SCMnow[scId].splice(meetingIndex,1);
				}
			}
			if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('SCMnow[scId]='+JSON.stringify(SCMnow[scId])); }
			// Remove this class meeting from the database.
			// BEGIN Make AJAX call.
			// Build the URL for the AJAX call
			if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('BEGIN Make AJAX call.'); }		
			URI = ROOT_http + '/Schedule/ScheduleClass/ScheduleClassUpdate.php?';
			URI += 'task=RemoveClassMeeting';
			URI += '&scId='+scId;
			URI += '&scmId='+scmId;
			let preloadText = 'Removing class meeting';
			let jsReturnCode = false;
			UpdateInclude(URI, null, preloadText, jsReturnCode);
			// END Make AJAX call.
			if ( DEBUG_ScheduleClass_RemoveClassMeetingVerify ) { console.log('END Make AJAX call.'); }
		} else {
			console.log('ClassMeeting_ScheduleClass['+scmId+'] is undefined so there is no javascript object or data to remove.');
		}
	} else if ( thisTask === 'no' ) {
		// No clicked, just hide the div.
		document.getElementById('div_RemoveClassMeetingVerify_'+scmId).style.display = 'none';
	}
	Validate_ScheduleClass();
	ClassMeeting_SetHeight('ScheduleClass_RemoveClassMeetingVerify');
} // END ScheduleClass_RemoveClassMeetingVerify.

// ScheduleClassDialog_SetWidth(by)
// Set the width of the Schedule Class dialogDiv.
function ScheduleClassDialog_SetWidth(by) {
	var DEBUG = false;
	if ( DEBUG ) { console.groupCollapsed(PC+'ScheduleClassDialog_SetWidth[] by='+by,CG); }
	var divClassMeetings = document.getElementsByClassName('divClassMeeting'); // Get the divClassMeetings.
	if ( divClassMeetings.length >= 1 ) { // Does the class have meetings?
		// Yes, Set the Schedule Class Dialog width.
		if ( DEBUG ) { console.log(PC+'Set the Schedule Class Dialog width',CI); }
		var MeetingColumns = 1; // Set to 1 or 2 below. A max of 2 columns is allowed.
		var ClassMeetingBoxWidth = 0;
		if ( divClassMeetings.length !== 0 ) { // Are there ClassMeetings?
			// Yes, set the number of columns and get the max divClassMeeting width;
			MeetingColumns = divClassMeetings.length;
			if ( MeetingColumns > 2 ) { MeetingColumns = 2; } // Max of 2 columns.
			// Need maximum width of the divClassMeetings.
			for ( var i=0; i<divClassMeetings.length; i++ ) {
				var ClassMeetingsBounds = ElementBounds(divClassMeetings[0],'schedule.js 1334');
				if ( DEBUG ) { console.log(PC+'ClassMeetings['+i+']Bounds='+JSON.stringify(ClassMeetingsBounds),CL); }
				var ThisClassMeetingBoxWidth = ClassMeetingsBounds.margin.left + ClassMeetingsBounds.margin.right + ClassMeetingsBounds.width;
				if ( DEBUG ) { console.log(PC+'ThisClassMeetingBoxWidth='+ThisClassMeetingBoxWidth,CL); }
				if ( ThisClassMeetingBoxWidth > ClassMeetingBoxWidth ) {
					ClassMeetingBoxWidth = ThisClassMeetingBoxWidth;
					if ( DEBUG ) { console.log(PC+'ClassMeetingBoxWidth changed to '+ClassMeetingBoxWidth,CS); }
				}
			}
		} // Are there ClassMeetings?
		if ( DEBUG ) { console.log(PC+'divClassMeetings.length='+divClassMeetings.length+' MeetingColumns='+MeetingColumns+' ClassMeetingBoxWidth='+ClassMeetingBoxWidth,CL); }
		// Get the bounds and offsetWidth of the fldMeetings fieldset element.
		var eMeetingFieldset = document.getElementById('fldMeetings');
		var MeetingFieldsetBounds = ElementBounds(eMeetingFieldset,'schedule.js 1344');
		if ( DEBUG ) { console.log(PC+'MeetingFieldsetBounds='+JSON.stringify(MeetingFieldsetBounds),CL); }
		var MeetingFieldsetPartWidth = 50;//MeetingFieldsetBounds.padding.left + MeetingFieldsetBounds.padding.right + MeetingFieldsetBounds.border.left + MeetingFieldsetBounds.border.right + 50;
		var NewMeetingFieldsetWidth = MeetingFieldsetPartWidth + ( ClassMeetingBoxWidth * MeetingColumns ) + 3; // Added 3 to make it work. Find out why!
		if ( DEBUG ) { console.log(PC+'fldMeetings width = '+NewMeetingFieldsetWidth+' MeetingFieldsetPartWidth='+MeetingFieldsetPartWidth,CS); }
		eMeetingFieldset.style.width = NewMeetingFieldsetWidth + 'px';
		ClassMeeting_SetHeight('ScheduleClassDialog_SetWidth');
		// Fix frmSchedule_form width.
		var eScheduleForm = document.getElementById('frmSchedule_form');
		var ScheduleFormBounds = ElementBounds(eScheduleForm,'schedule.js 1392');
		if ( DEBUG ) { console.log(PC+'ScheduleFormBounds='+JSON.stringify(ScheduleFormBounds),CL); }
		var NewScheduleFormWidth = NewMeetingFieldsetWidth;// + ScheduleFormBounds.padding.left + ScheduleFormBounds.padding.right + ScheduleFormBounds.border.left + ScheduleFormBounds.border.right;
		if ( DEBUG ) { console.log(PC+'frmSchedule_form width = '+NewScheduleFormWidth,CS); }
		eScheduleForm.style.width = NewScheduleFormWidth + 'px';
		/** /
	} else { // Does the class have meetings?
		// No, Check if this is a move class dialog (MCD).
		if ( document.getElementById('fldMoveClassMeetings') ) { // Is this a MCD?
			// Yes, Set the Move Class Dialog width.
			if ( DEBUG ) { console.log(PC+'Set the Move Class Dialog width',CI); }
			let eMoveClassMeetingsFieldset = document.getElementById('fldMoveClassMeetings'); // Get the fldMoveClassMeetings fieldset element.
			var MoveClassMeetingsFieldsetBounds = ElementBounds(eMoveClassMeetingsFieldset,'schedule.js 1419'); // Get the fldMoveClassMeetings bounds.
			if ( DEBUG ) { console.log(PC+'MoveClassMeetingsFieldsetBounds='+JSON.stringify(MoveClassMeetingsFieldsetBounds),CL); }
			var NewMoveClassMeetingFieldsetWidth = MoveClassMeetingsFieldsetBounds.padding.left + MoveClassMeetingsFieldsetBounds.padding.right + MoveClassMeetingsFieldsetBounds.border.left + MoveClassMeetingsFieldsetBounds.border.right; // Calc new width.
			if ( DEBUG ) { console.log(PC+'NewMoveClassMeetingFieldsetWidth='+NewMoveClassMeetingFieldsetWidth,CS); }
			eMoveClassMeetingsFieldset.style.width = NewMoveClassMeetingFieldsetWidth + 'px';
		} else { // Is this a MCD?
			// No, do nothing
		} // Is this a MCD?
		/**/
		//ClassMeeting_SetHeight('ScheduleClassDialog_SetWidth');
	} // Does the class have meetings?
	if ( DEBUG ) { console.groupEnd(); }
} // END ScheduleClassDialog_SetWidth.

// ScheduleClassDialogDrag(e)
// Handles the drag event from the Schedule Class dialog.
function ScheduleClassDialogDrag(e) {
	var DEBUG_ScheduleClassDialogDrag = true;
	if ( DEBUG_ScheduleClassDialogDrag ) { console.warn('ScheduleClassDialogDrag[e.id='+e.id+']'); }
	var pos1 = 0,
		pos2 = 0,
		pos3 = 0,
		pos4 = 0;
	var e_dialogContainer = document.getElementById('dialogContainer');
	document.removeEventListener('scroll', ScrollDialogDiv);
	function dragMouseDown(e) {
		e = e || window.event;
		// Get the mouse cursor position at startup:
		pos3 = e.clientX;
		pos4 = e.clientY;
		document.onmouseup = closeDragElement;
		document.onmousemove = elementDrag;
	}
	function elementDrag(e) {
		var DEBUG = false;
		e = e || window.event;
		if ( DEBUG ) { console.warn('elementDrag[e.id='+e.id+']'); }
		// Calculate the new cursor position
		pos1 = pos3 - e.clientX;
		pos2 = pos4 - e.clientY;
		pos3 = e.clientX;
		pos4 = e.clientY;
		// Remove any text selection.
		ClearTextSelection();
		// Set the element's new position
		e_dialogContainer.style.top = (e_dialogContainer.offsetTop - pos2) + "px";
		e_dialogContainer.style.left = (e_dialogContainer.offsetLeft - pos1) + "px";
	}
	function closeDragElement() {
		// TODO: Save location to database
		document.onmouseup = null;
		document.onmousemove = ttPosition; // Restore onmousemove handler to ttPosition[].
		document.addEventListener('scroll', ScrollDialogDiv);
		KeepElementInViewport(e_dialogContainer);
	}
	dragMouseDown(e);
} // END ScheduleClassDialogDrag

// ScheduleClassDragCheck(evt)
// Determine if this is a click or a drag of a schedule class.
function ScheduleClassDragCheck(evt) {
	//var DEBUG_ScheduleClassDragCheck = true; // unused 2022/04/06 jfm
	evt = (evt) ? evt : window.event;
	//console.log('evt='+JSON.stringify(evt));
	//element.removeEventListener('mousedown',ScheduleClassDragCheck);
	//console.warn('ScheduleClassDragCheck[] evt.target.id='+evt.target.id+' mousedownFlag='+mousedownFlag+' button='+evt.button);
	if ( evt.button !== 0 ) { return; }
	ClearTextSelection();
	mousedownFlag = 'clickwait';
	var d = new Date();
	mousedownTimer = d.getTime();
	//console.log('mousedownTimer='+mousedownTimer);
	evt.currentTarget.addEventListener('mousemove', ScheduleClassDragCheckWait);
} // END ScheduleClassDragCheck.

// ScheduleClassDragCheckWait(evt)
// Wait 50 ms to ensure this is a drag vs a click.
function ScheduleClassDragCheckWait(evt) {
	evt = (evt) ? evt : window.event;
	//console.warn('ScheduleClassDragCheckWait[] evt.currentTarget.id='+evt.currentTarget.id+' mousedownFlag='+mousedownFlag);
	ClearTextSelection();
	var d = new Date();
	var now = d.getTime();
	var diff = now - mousedownTimer;
	console.log('mousemove mousedownTimer='+mousedownTimer+' now='+now+' diff='+diff);
	if ( diff > 50 ) {
		evt.currentTarget.removeEventListener('mousemove', ScheduleClassDragCheckWait);
		mousedownFlag = 'mousemove';
		ScheduleClassDragBegin(evt);
	} else {
		console.log('WAITING');
	}
} // END ScheduleClassDragCheckWait.

// ScheduleClassDragBegin(evt)
// Begin the schedule class drag.
function ScheduleClassDragBegin(evt) {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.groupCollapsed(PC+`ScheduleClassDragBegin[evt.target.id=${evt.target.id}] evt.type=${evt.type}`,CG); }
	evt = (evt) ? evt : window.event;
	//console.warn('ScheduleClassDragBegin[] evt.currentTarget.id='+evt.currentTarget.id+' mousedownFlag='+mousedownFlag);
	dragElement = evt.currentTarget;
	ClearTextSelection();
	ttHide();
	document.body.addEventListener('mouseup',ScheduleClassDrop);
	document.body.addEventListener('mousemove',ScheduleClassDragMove);
	document.body.addEventListener('keydown',ScheduleClassDragMoveAbortCheck);
	evt.preventDefault();
	var mX = mouseX(evt);
	mXprevious = mX;
	var mY = mouseY(evt);
	mYprevious = mY;
	if ( DEBUG ) { console.log('mX='+mX+' mY='+mY); }
	dragElement.style.zIndex = 500; // Move the class meeting up the z.
	dragElementTL = ElementBounds(dragElement.id,'schedule.js 1449');
	//dragElementTL.offsetLeft = (evt.offsetX || evt.clientX - $(dragElement).offset().left);
	//dragElementTL.offsetTop = (evt.offsetY || evt.clientY - $(dragElement).offset().top);
	dragElementTL.offsetLeft = (evt.offsetX || evt.clientX - dragElementTL.left);
	dragElementTL.offsetTop = (evt.offsetY || evt.clientY - dragElementTL.top);
	dragElementOriginalTL = JSON.parse(JSON.stringify(dragElementTL));
	if ( DEBUG ) { console.log('dragElementTL left='+dragElementTL.left+' top='+dragElementTL.top+' right='+dragElementTL.right+' bottom='+dragElementTL.bottom+' offsetLeft='+dragElementTL.offsetLeft+' offsetTop='+dragElementTL.offsetTop); }
	
	schedulecontainerTL = ElementBounds('schedulecontainer','schedule.js 1455');
	if ( DEBUG ) { console.log('schedulecontainerTL left='+schedulecontainerTL.left+' top='+schedulecontainerTL.top+' right='+schedulecontainerTL.right+' bottom='+schedulecontainerTL.bottom); }
	
	scrollTL = ScrollLeftTop();	
	if ( DEBUG ) { console.log('scrollTL left='+scrollTL.left+' top='+scrollTL.top); }
	
	
	viewportTL = {};
	viewportTL.width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
	viewportTL.height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
	if ( DEBUG ) { console.log('viewportTL width='+viewportTL.width+' height='+viewportTL.height); }
	if ( DEBUG ) { console.log(`${PC}END ${PC}ScheduleClassDragBegin`,SE,ST); console.groupEnd(); }
	
} // END ScheduleClassDragBegin.

// ScheduleClassDragMove(evt)
// Follow the mouse with the schedule class being dragged.
function ScheduleClassDragMove(evt) {
	//return 'dragdrop';
	var DEBUG_ScheduleClassDragMove = false;
	evt = (evt) ? evt : window.event;
	ClearTextSelection();
	if ( DEBUG_ScheduleClassDragMove ) { console.warn('ScheduleClassDragMove[] evt.target.id='+evt.target.id); }
	ttHide();
	// Find current mouse position.
	var mX = mouseX(evt);
	var mY = mouseY(evt);
	if ( DEBUG_ScheduleClassDragMove ) { console.log('mX='+mX+' mY='+mY+' dragElementTL offsetLeft='+dragElementTL.offsetLeft+' offsetTop='+dragElementTL.offsetTop); }
	// Calculate position to move class meeting to in order to follow the mouse.
	let schedulecontainerBounds = ElementBounds('schedulecontainer');
	var posX =  mX - dragElementTL.offsetLeft - schedulecontainerBounds.left;
	var posY =  mY - dragElementTL.offsetTop - schedulecontainerBounds.top;
	if ( DEBUG_ScheduleClassDragMove ) { console.log('posX='+posX+' posY='+posY); }
	// Move the class meeting to follow the mouse.
	dragElement.style.left = posX + 'px';
	dragElement.style.top = posY + 'px';
	// Remember offsetLeft and offsetTop.
	var offsetLeft = dragElementTL.offsetLeft;
	var offsetTop = dragElementTL.offsetTop;
	dragElementTL = ElementBounds(dragElement.id,'schedule.js 1490');
	// Put back offsetLeft and offsetTop;
	dragElementTL.offsetLeft = offsetLeft;
	dragElementTL.offsetTop = offsetTop;
	if ( DEBUG_ScheduleClassDragMove ) { console.log('dragElementTL left='+dragElementTL.left+' top='+dragElementTL.top+' right='+dragElementTL.right+' bottom='+dragElementTL.bottom+' offsetLeft='+dragElementTL.offsetLeft+' offsetTop='+dragElementTL.offsetTop); }
	// Check if scroll up needed.
	while ( dragElementTL.top > schedulecontainerTL.top && scrollTL.top > 0 && posY < ( scrollTL.top + 1 ) ) {
		if ( DEBUG_ScheduleClassDragMove ) { console.info('Scroll up'); }
		window.scrollBy(0, -1);
		scrollTL = ScrollLeftTop();
		console.log('scrollTL left='+scrollTL.left+' top='+scrollTL.top);
	}
	// Check if scroll down needed.
	/** /
	console.log('dragElementTL.top='+dragElementTL.top+' schedulecontainerTL.bottom='+schedulecontainerTL.bottom+' ScheduleIncrementHeight='+ScheduleIncrementHeight);
	console.log('scrollTL.top='+scrollTL.top+' dragElementTL.bottom='+dragElementTL.bottom);
	console.log('scrollTL.top='+scrollTL.top+' viewportTL.height='+viewportTL.height);
	/**/
	while ( dragElementTL.top < ( schedulecontainerTL.bottom - ScheduleIncrementHeight ) && scrollTL.top < viewportTL.height && dragElementTL.bottom > ( scrollTL.top + viewportTL.height - 1 ) ) {
		if ( DEBUG_ScheduleClassDragMove ) { console.info('Scroll down'); }
		window.scrollBy(0, 1);
		scrollTL = ScrollLeftTop();	
		console.log('scrollTL left='+scrollTL.left+' top='+scrollTL.top);
	}
} // END ScheduleClassDragMove.

// ScheduleClassDragMoveAbortCheck(evt)
// Check for ESC key to abort sheedule class drag.
function ScheduleClassDragMoveAbortCheck(evt) {
	evt = (evt) ? evt : window.event;
	var theKey;
	if (evt) {
		theKey = evt.which;
	} else {
		theKey = window.event.keyCode;
	}
	console.log('theKey='+theKey);
	if ( theKey === 27 ) {
		console.info(dragElement.id+' not dropped in schedule td. dragElementOriginalTL left='+dragElementOriginalTL.left+' top='+dragElementOriginalTL.top);
		ScheduleClassDragAbort('ScheduleClassDragMoveAbortCheck 2259');
		evt.preventDefault();
	}
} // END ScheduleClassDragMoveAbortCheck.

// ScheduleClassDragAbort(by)
// Abort sheedule class drag.
function ScheduleClassDragAbort(by) {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.groupCollapsed(PC+`ScheduleClassDragAbort[] by=${by}`,CG); }
	// Return dragElement to original position.
	dragElement.style.zIndex = 1; // Move the class meeting back down the z.
	let schedulecontainerBounds = ElementBounds('schedulecontainer');
	dragElement.style.left = dragElementOriginalTL.left - schedulecontainerBounds.left + 'px';
	dragElement.style.top = dragElementOriginalTL.top - schedulecontainerBounds.top + 'px';
	// Remove drag event listeners.
	document.body.removeEventListener('mouseup',ScheduleClassDrop);
	document.body.removeEventListener('mousemove',ScheduleClassDragMove);
	document.body.removeEventListener('keydown',ScheduleClassDragMoveAbortCheck);
	if ( DEBUG ) { console.log(`${PC}END ${PC}ScheduleClassDragAbort`,SE,ST); console.groupEnd(); }
} // END ScheduleClassDragAbort.

// ScheduleClassDrop(evt)

// ScheduleClassDrop_Change_calendar_class_id(droppedIn_day, droppedIn_mTime)
// Change the calendar_class div id, this needs to be changed AFTER the updateInclude() call.
function ScheduleClassDrop_Change_calendar_class_id(droppedIn_day, droppedIn_mTime) {
	var DEBUG_Change_calendar_class_id = false;
	if ( DEBUG_Change_calendar_class_id ) { console.log('BEGIN ScheduleClassDrop_Change_calendar_class_id[droppedIn_day='+droppedIn_day+', droppedIn_mTime='+droppedIn_mTime+'] dragElement.id='+dragElement.id); }
	// BEGIN Change the calendar_class div id.
	if ( DEBUG_Change_calendar_class_id ) { console.log('BEGIN Change the calendar_class div.id.'); }
	var e_calendar_class = document.getElementById(dragElement.id); // Get the calendar_class div element.
	if ( DEBUG_Change_calendar_class_id ) { console.log("\t"+'ORIGINAL e_calendar_class.id='+e_calendar_class.id); }
	var newTimeID = dragElement.id.substr(0, dragElement.id.lastIndexOf("_")) + "_" + droppedIn_day + droppedIn_mTime;
	e_calendar_class.id = newTimeID; // Change the id.
	if ( DEBUG_Change_calendar_class_id ) { console.log("\t"+'REPLACED e_calendar_class.id='+e_calendar_class.id); }
	// END Change the calendar_class div id.
	if ( DEBUG_Change_calendar_class_id ) { console.log('END Change the calendar_class div.id.'); }		
	// Redraw the calendar
	DisplaySchedule('ScheduleClassDrop 1944');
} // END ScheduleClassDrop_Change_calendar_class_id.

// ScheduleClassDrop(evt)
// Handle schedule class drop.
function ScheduleClassDrop(evt) {
	var DEBUG = DEBUG_ON;
	evt = (evt) ? evt : window.event;
	if ( DEBUG ) { console.groupCollapsed(PC+'ScheduleClassDrop[] evt.currentTarget.id='+evt.currentTarget.id+' dragElement.id='+dragElement.id,CG); }
	evt.preventDefault();
	dragElement.style.zIndex = 1; // Move the class meeting back down the z.
	dragElement.mX = mouseX(evt);
	dragElement.mY = mouseY(evt);
	//return 'dragdrop'; // Uncomment to stop ScheduleClassDrop().
	var DEBUG_AllowAJAXrequest = true; // Allow the AJAX request to update the database.
	//DEBUG_AllowAJAXrequest = false; // Uncomment to prevent the AJAX request to update the database.
	if ( DEBUG ) { console.groupCollapsed(PB+'Find out where the class meeting was dropped.',SB,ST); }
	// Get mouse position.
	//var mX = mouseX(evt); // unused 2022/04/06 jfm
	//var mY = mouseY(evt); // unused 2022/04/06 jfm
	let dragElementTLNow = ElementBounds(dragElement.id,'schedule.js 1675'); // Calculate upper left corner position of class meeting.
	var dayIndexMin; // Min day index in the schedule view.
	var dayIndexMax; // Max day index in the schedule view.
	if ( ScheduleDayView === 'Work week' ) {
		dayIndexMin = 1;
		dayIndexMax = 5;
	} else {
		dayIndexMin = 0;
		dayIndexMax = 6;
	}
	var droppedInCalendarDayTime = false; // Set true if class meeting was dropped in a scheduleCell.
	var droppedIn_day = ''; // The day the class meeting was moved to.
	var droppedIn_mTime = ''; // The mTime the class meeting was moved to.
	var meetingIndex = 0; // Used to loop thru schedule class meetings.
	var mScheduleTimeBegin = ScheduleTimeBegin * 60; // The beginning time in the schedule view.
	var mScheduleTimeEnd = ScheduleTimeEnd * 60; // The ending time in the schedule view.
	// Get the days of the week.
	var daysOfWeek = [];
	var daysOfWeekIndex = 0;
	for ( var weekdayId in Weekdays ){if(Weekdays.hasOwnProperty(weekdayId)){
		daysOfWeek[daysOfWeekIndex] = Weekdays[weekdayId].weekdayD;
		daysOfWeekIndex++;
	}}
	var scId;
	var scmId = 0;
	var scmIndex = false;
	var original_day;
	var original_mTime;
	var dayIndex;
	var droppedIn_eTime;
	daysOfWeekLoop:
	for ( var d=dayIndexMin; d<=dayIndexMax; d++ ) { // Loop thru the days in the schedule view.
		droppedIn_day = daysOfWeek[d];
		for ( droppedIn_mTime=mScheduleTimeBegin; droppedIn_mTime<=mScheduleTimeEnd; droppedIn_mTime+=ScheduleTimeIncrement ) { // Loop thru the times in the schedule view.
			var tdId = droppedIn_day + droppedIn_mTime;
			//var eTD = document.getElementById(tdId); // The td we are testing. // unused 2022/04/06 jfm
			let tdBounds = ElementBounds(tdId,'schedule.js 1712');
			if ( DEBUG ) { console.log(PC+`tdBounds = ${D_formatJSONstring(tdBounds)}`,CI); }
			if ( dragElementTLNow.left >= tdBounds.left &&  dragElementTLNow.left <= tdBounds.right && dragElementTLNow.top >= tdBounds.top &&  dragElementTLNow.top <= tdBounds.bottom ) { // Did the class meeting get dropped on the schedule?
				let schedulecontainerBounds = ElementBounds('schedulecontainer');
				droppedInCalendarDayTime = true;
				if ( DEBUG ) { console.log('Dropped in '+tdId); }
				// Snap class meeting to top left of schedule td.
				dragElement.style.left = tdBounds.left - schedulecontainerBounds.left + 1 + 'px';
				dragElement.style.top = tdBounds.top - schedulecontainerBounds.top + 8 + 'px';
				//var newBounds = ElementBounds(dragElement.id,'schedule.js 1603');
				//if ( DEBUG ) { console.log('newBounds left='+newBounds.left+' top='+newBounds.top); }
				break daysOfWeekLoop; // Found where it was dropped so we can stop looping.
			} // Did the class meeting get dropped on the schedule?
		} // Loop thru the times in the schedule view.
	} // Loop thru the days in the schedule view.
	if ( DEBUG ) { console.log('droppedInCalendarDayTime='+droppedInCalendarDayTime+' droppedIn_day='+droppedIn_day+' droppedIn_mTime='+droppedIn_mTime); }
	// END Find where the class meeting was dropped.
	if ( DEBUG ) { console.groupEnd(); console.log(PE+'Find out where the class meeting was dropped.',SE,ST); }
	if ( droppedInCalendarDayTime ) { // Was the class meeting dropped in a valid scheduleCell?
		if ( DEBUG ) { console.log(PC+`The class meeting was dropped in a valid scheduleCell.`,CT); }
		if ( DEBUG ) { console.groupCollapsed(`${PB}Find the scId, scmId, and scmIndex.`,SB,ST); }
		// Find old day of class meeting.
		var idParts = dragElement.id.split('_');
		scId = parseInt(idParts[2]);
		original_day = idParts[3].substr(0,1);
		original_mTime = parseInt(idParts[3].substr(1));
		if ( DEBUG ) { console.log('scId='+scId+' original_day='+original_day+' original_mTime='+original_mTime); }
		if ( DEBUG ) { console.log('SCMnow['+scId+']='+D_formatJSONstring(SCMnow[scId])); }
		var meetingDay;
		var bTime;
		var mTime;
		if ( DEBUG ) { console.log('Count of meetings = SCMnow[scId].length='+SCMnow[scId].length); }
		if ( DEBUG ) { console.log('Search meetings for the original day meeting was on = original_day='+original_day); }
		if ( DEBUG ) { console.log('BEGIN Loop thru meetings.'); }
		loopMeeting:
		for ( meetingIndex=0; meetingIndex<SCMnow[scId].length; meetingIndex++ ) { // Loop thru meetings.
			if ( DEBUG ) { console.log('Meeting days = SCMnow['+scId+']['+meetingIndex+'].days='+SCMnow[scId][meetingIndex].days); }
			// Change bTime to mTime
			bTime = SCMnow[scId][meetingIndex].bTime;
			var timeInMinutes = ConvertTimeToMinutes(SCMnow[scId][meetingIndex].bTime);
			if ( DEBUG ) { console.log(PC+'timeInMinutes='+timeInMinutes+' ScheduleTimeIncrement='+ScheduleTimeIncrement,CI); }
			mTime = parseInt(ConvertTimeToMinutes(SCMnow[scId][meetingIndex].bTime)); // No longer set to calendar time boundry.
			if ( DEBUG ) { console.log(PC+'meetingIndex='+meetingIndex+' bTime='+bTime+' mTime='+mTime+' original_mTime='+original_mTime,CI); }
			if ( mTime === original_mTime ) { // Is this mTime the same as the original_mTime?
				// Yes, check if the day is also the same.
				for ( dayIndex=0; dayIndex<SCMnow[scId][meetingIndex].days.length; dayIndex++ ) { // Loop thru meeting days.
					meetingDay = SCMnow[scId][meetingIndex].days[dayIndex];
					if ( meetingDay === original_day ) { // Is this meetingDay the same as the original_day?
						// Yes, we found the original day and mTime.
						scmIndex = meetingIndex;
						scmId = SCMnow[scId][scmIndex].scmId;
						break loopMeeting;
					} // Is this meetingDay the same as the original_day?
				} // Loop thru meeting days.
			} // Is this mTime the same as the original_mTime?
		} // Loop thru meetings.
		if ( DEBUG ) { console.log('scmIndex='+scmIndex+' meetingDay='+meetingDay); }
		if ( DEBUG ) { console.log('END Loop thru meetings.'); }
		console.log('scId='+scId+' scmId='+scmId+' scmIndex='+scmIndex+' meetingDay='+meetingDay+' dayIndex='+dayIndex);
		if ( DEBUG ) { console.groupEnd(); console.log(`${PE}Find the scId, scmId, and scmIndex.`,SE,ST); }
		if ( DEBUG ) { console.log(PC+`scId = ${scId}, scmId = ${scmId}, scmIndex = ${scmIndex}`,CI); }
		if ( scmIndex !== false ) {
			if ( DEBUG ) { console.groupCollapsed(PB+'Find the day diff.',SB,ST); }
			if ( DEBUG ) { console.log(PC+`Moved SCMnow[${scId}][${dayIndex}] meeting day from ${meetingDay} to ${droppedIn_day}`,CL); }
			if ( DEBUG ) { console.log(PC+`Moved SCMnow[${scId}][${dayIndex}] meeting mTime from ${mTime} to ${droppedIn_mTime}`,CL); }
			// Find the day and time diff.
			var mIndexFrom = daysOfWeek.indexOf(meetingDay);
			var mIndexTo = daysOfWeek.indexOf(droppedIn_day);
			var dayDiff = mIndexTo - mIndexFrom;
			var newDayIndex;
			if ( DEBUG ) { console.log('mIndexFrom='+mIndexFrom+' mIndexTo='+mIndexTo+' dayDiff='+dayDiff); }
			var daysOK = true;
			for ( dayIndex=0; dayIndex<SCMnow[scId][scmIndex].days.length; dayIndex++ ) {
				meetingDay = SCMnow[scId][scmIndex].days[dayIndex];
				var thisDayIndex = daysOfWeek.indexOf(SCMnow[scId][scmIndex].days[dayIndex]);
				if ( DEBUG ) { console.log('meetingDay='+meetingDay+' thisDayIndex='+thisDayIndex); }
				newDayIndex = thisDayIndex + dayDiff;
				if ( newDayIndex < dayIndexMin || newDayIndex > dayIndexMax ) {
					if ( DEBUG ) { console.log('newDayIndex '+newDayIndex+' out of range '+dayIndexMin+'-'+dayIndexMax); }
					daysOK = false;

					break;
				}
			}
			var timeDiff = droppedIn_mTime - mTime;
			droppedIn_eTime = ConvertTimeToMinutes(SCMnow[scId][scmIndex].eTime) + timeDiff;
			if ( DEBUG ) { console.log('daysOK='+daysOK+' newDayIndex='+newDayIndex+' day of week='+daysOfWeek[newDayIndex]+' timeDiff='+timeDiff+' droppedIn_mTime='+droppedIn_mTime+' droppedIn_eTime='+droppedIn_eTime); }
			if ( DEBUG ) { console.groupEnd(); console.log(PE+'Find the day diff.',SE,ST); }
			// Store needed values in dragElement
			dragElement.droppedIn_day = droppedIn_day; // diDay
			dragElement.droppedIn_mTime = droppedIn_mTime; // diMtime
			dragElement.scId = scId;
			dragElement.scmId = scmId;
			dragElement.scmIndex = scmIndex;
			dragElement.scmNewIndex = SCMnow[scId].length;
			dragElement.original_day = original_day; // From_day
			dragElement.original_mTime = original_mTime; // From_mTime
			var preloadText;
			var jsReturnCode;
			if ( SCMnow[scId][scmIndex].days.length === 1 ) { // Is there only one day?
				// There is only one day, simply update the SCMnow[scId][scmIndex].
				if ( DEBUG ) { console.log(PC+`There is only one day for this meeting.`,CI); }
				if ( DEBUG ) { console.groupCollapsed(PB+'Update the SCMnow JSON object.',SB,ST); }
				SCMnow[scId][scmIndex].bTime = ConvertMinutesToTime(droppedIn_mTime)+':00'; // Set new bTime.
				SCMnow[scId][scmIndex].eTime = ConvertMinutesToTime(droppedIn_eTime)+':00'; // Set new eTime.
				// Find the day it was moved from in the days array and replace it.
				for ( dayIndex = 0; dayIndex < SCMnow[scId][scmIndex].days.length; dayIndex++ ) {
					// If this is the day the class was moved from, replace it.
					if ( SCMnow[scId][scmIndex].days[dayIndex] === original_day) {
						SCMnow[scId][scmIndex].days[dayIndex] = droppedIn_day;
					}
				}
				if ( DEBUG ) { console.log('REPLACED SCMnow['+scId+']='+JSON.stringify(SCMnow[scId])); }
				if ( DEBUG_AllowAJAXrequest ) { // Should we perform the AJAX call?
					// BEGIN Make AJAX call.
					// Build the URL for the AJAX call
					if ( DEBUG ) { console.log('BEGIN Make AJAX call.'); }		
					URI = ROOT_http + '/Schedule/ScheduleClass/ScheduleClassUpdate.php?';
					URI += 'task=MoveClassMeeting';
					URI += '&scId='+scId;
					URI += '&scmId='+scmId;
					URI += '&bTime='+SCMnow[scId][scmIndex].bTime;
					URI += '&eTime='+SCMnow[scId][scmIndex].eTime;
					var days = '';
					for ( var di=0; di<SCMnow[scId][scmIndex].days.length; di++) {
						days += SCMnow[scId][scmIndex].days[di];
					}
					URI += '&days='+days;
					var eId = dragElement.id;
					preloadText = 'Updating class';
					jsReturnCode = "ScheduleClassDrop_Change_calendar_class_id('"+droppedIn_day+"', '"+droppedIn_mTime+"');";
					UpdateInclude(URI, eId, preloadText, jsReturnCode);
					// END Make AJAX call.
					if ( DEBUG ) { console.log('END Make AJAX call.'); }		
				} else { // Should we perform the AJAX call?
					// No.
					if ( DEBUG ) { console.log('AJAX call skipped for now because DEBUG_AllowAJAXrequest is false.'); }
					// Put the class meeting back.
					console.info(dragElement.id+' not dropped in schedule td. dragElementOriginalTL left='+dragElementOriginalTL.left+' top='+dragElementOriginalTL.top);
					dragElement.style.left = dragElementOriginalTL.left + 'px';
					dragElement.style.top = dragElementOriginalTL.top + 'px';
				} // Should we perform the AJAX call?
				if ( DEBUG ) { console.groupEnd(); console.log(PE+'Update the SCMnow JSON object.',SE,ST); }
			} else { // Is there only one day?
				// There are multiple days, Make an AJAX call and open a Move Class Dialog.
				if ( DEBUG ) { console.log(PC+`There are ${SCMnow[scId][scmIndex].days.length} days for this meeting.`,CI); }
				if ( DEBUG ) { console.groupCollapsed(PB+'Make an AJAX call to open a Move Class Dialog.',SB,ST); }
				console.log('ScheduleCurrent.scheduleId='+ScheduleCurrent.scheduleId+', ScheduleCurrent.departmentId='+ScheduleCurrent.departmentId+', scId='+scId);
				ScheduleClassDragAbort('ScheduleClassDrop 2500');
				console.log(PC+'Stop click for '+dragElement.id,CI);
				evt.preventDefault();
				EventListeners_Remove();
				// Get the Move Class Dialog via AJAX.
				URI = ROOT_http + '/Schedule/MoveClass/MoveClassDialog.php';
				URI += '?scheduleclassId='+scId;
				URI += '&divId='+dragElement.id;
				URI += '&droppedIn_day='+droppedIn_day;
				URI += '&droppedIn_mTime='+droppedIn_mTime;
				URI += '&scheduleclassmeetingId='+scmId;
				preloadText = 'Getting class meetings for move';
				UpdateLoadingText = preloadText;
				jsReturnCode = "ScheduleClass_MoveSingleMeetingDiv('ScheduleClassDrop~2531');";
				jsReturnCode += ` OpenDialog(${ScheduleCurrent.departmentId}, ${scId});`;
				jsReturnCode += ` PositionMoveClassDialog();`;
				console.log('jsReturnCode='+jsReturnCode);
				ScheduleClassOpenCount = 0;
				UpdateInclude(URI, 'dialogDiv', preloadText, jsReturnCode);
				if ( DEBUG ) { console.groupEnd(); console.log(PE+'Make an AJAX call to open a Move Class Dialog.',SE,ST); }
			} // Is there only one day?
		}
	} else { // Was the class meeting dropped in a valid scheduleCell?
		if ( DEBUG ) { console.log(PC+'The class meeting was NOT dropped in a valid scheduleCell.',CF); }
		evt.preventDefault();
		ScheduleClassDragAbort('ScheduleClassDrop 2542');
	} // Was the class meeting dropped in a valid scheduleCell?
	evt.preventDefault();
	document.body.removeEventListener('mouseup',ScheduleClassDrop);
	document.body.removeEventListener('mousemove',ScheduleClassDragMove);
	document.body.removeEventListener('keydown',ScheduleClassDragMoveAbortCheck);
	//evt.preventDefault();
	if ( DEBUG ) { console.log(`${PC}END ${PC}ScheduleClassDrop`,SE,ST); console.groupEnd(); }
} // END ScheduleClassDrop.

// OpenDialog(scheduleclassId, CallCount)
// Open the dialogDiv with the scheduleclass info loaded.
function OpenDialog(scheduleclassId=0, CallCount=0) {
	var DEBUG = true;
	var DEBUG_CourseNumber = true;
	let courseNumber = 'NOLOOKUP';
	if (DEBUG_CourseNumber) {
		for ( var scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){
			if (scheduleclassId == scId) {
				courseNumber = ScheduleClass[scId].Course;
			}
		}}
	}
	if ( DEBUG ) {
		console.group(PC+`OpenDialog[scheduleclassId = ${scheduleclassId}, ${courseNumber}, CallCount = ${CallCount}]`,CG);//Collapsed
	} else {
		console.log(PC+`OpenDialog[scheduleclassId = ${scheduleclassId}, ${courseNumber}, CallCount = ${CallCount}]`,CH);
	}
	if ( DEBUG && dragElement && dragElement.id ) { console.log(PC+`dragElement = ${NL}"id":"${dragElement.id}" ${D_formatJSONstring(dragElement)}`,CL); }
	var e_dialogDiv = document.getElementById('dialogDiv');
	dialogDivContents = e_dialogDiv.innerHTML;
	if ( dialogDivContents.indexOf('Load OK') !== -1 ) { // Did the dialog contents load OK?
		// Yes.
		if ( DEBUG ) { console.log(`${PC}Load OK`,CT); }
		document.addEventListener('keydown',KeydownDialog);
		e_dialogDiv.style.display = 'block';
		ScheduleClassDialog_SetWidth('OpenDialog 2548'); // Set dialog width.
		// BEGIN Position the dialog.
		var e_dialogContainer = document.getElementById('dialogContainer');
		//.addEventListener('keydown',KeydownDialog);
		var docScroll = document.documentElement;
		var docLeft = (window.pageXOffset || docScroll.scrollLeft) - (docScroll.clientLeft || 0);
		var docTop = (window.pageYOffset || docScroll.scrollTop)  - (docScroll.clientTop || 0);
		if ( DEBUG ) { console.log(PC+'docLeft='+docLeft+' docTop='+docTop,CL); }
		if ( DEBUG ) { console.log(PC+'dialogContainerLeft='+dialogContainerLeft+' dialogContainerTop='+dialogContainerTop,CL); }
		if ( dialogContainerLeft < docLeft ) {
			dialogContainerLeft = docLeft;
			e_dialogContainer.style.left = dialogContainerLeft+'px';
			if ( DEBUG ) { console.log(PC+'dialogContainer left changed to docLeft='+dialogContainerLeft,CS); }
		}
		if ( dialogContainerLeft < 0 ) {
			dialogContainerLeft = 0;
			e_dialogContainer.style.left = dialogContainerLeft+'px';
			if ( DEBUG ) { console.log(PC+'dialogContainer left changed to 0',CS); }
		}
		if ( dialogContainerTop < docTop ) {
			dialogContainerTop = docTop;
			e_dialogContainer.style.top = dialogContainerTop+'px';
			if ( DEBUG ) { console.log(PC+'dialogContainer top changed to docTop='+dialogContainerTop,CS); }
		}
		// Make sure dialog is rendered in the viewport
		if ( dialogContainerTop > docTop ) {
			// Get the distance of the sidenav from the top
			// By getting this, it insures the dialogDiv will never render above the top of the sidenav
			// Without this the dialog could render on the top navbar 
			var e_sidenav = document.getElementById("navSidenav");
			var sidenavDistanceFromTop = parseInt(e_sidenav.style.top);
			// Check to see if dialog will be rendered above the sidenav
			if ( dialogContainerTop >= sidenavDistanceFromTop ) {
				dialogContainerTop = sidenavDistanceFromTop;
				e_dialogContainer.style.top = dialogContainerTop+'px';
			if ( DEBUG ) { console.log(PC+'dialogContainer top changed to sidenavDistanceFromTop='+dialogContainerTop,CS); }
			} else {
				dialogContainerTop = docTop;
				e_dialogContainer.style.top = dialogContainerTop+'px';
			if ( DEBUG ) { console.log(PC+'dialogContainer top changed to docTop='+dialogContainerTop,CS); }
			}			
		} else {
			if ( DEBUG ) { console.log('dialogContainerTop ['+dialogContainerTop+'] <= docTop ['+docTop+']'); }
		}
		if ( dialogContainerTop < 0 ) {
			dialogContainerTop = 0;
			e_dialogContainer.style.top = dialogContainerTop+'px';
			if ( DEBUG ) { console.log(PC+'dialogContainer top set to 0',CS); }
		}
		//e_dialogDiv.style.display = 'block';
		// END Position the dialog.
		// Get legend button and add drag event listener
		var e_legends = e_dialogContainer.getElementsByTagName("legend");
		e_legends[0].onmousedown = ScheduleClassDialogDrag;
	} else { // Did the dialog contents load OK?
		// No. Try the UpdateInclude again.
		if ( DEBUG ) { console.log(`${PC}Load Failed`,CF); }
		if ( DEBUG ) { if (!CallCount) { console.log(PC+'Make first AJAX call.',CC); } else { console.log(PC+'Dialog in not OK after '+CallCount+' tries.',CE); } }
		if ( CallCount < 10 ) {
			CallCount++;
			URI = ROOT_http + '/Schedule/ScheduleClass/ScheduleClassForm.php?task=EditCLass';
			if ( typeof scheduleclassId === 'undefined' ) { scheduleclassId = 0; }
			URI += '&scheduleclassId='+scheduleclassId;
			let eId = 'dialogDiv';
			let preloadText = 'Getting class';
			UpdateInclude(URI, eId, preloadText);
			let callTimer = CallCount*200;
			if ( DEBUG ) { console.log(`${PC}callTimer=${callTimer}`,CI); }
			setTimeout(function(){ OpenDialog(scheduleclassId, CallCount); },callTimer);
		} else {
			//alert('OpenDialog: Never got return from URI='+URI);
			console.log(`${PC}OpenDialog: Never got return from URI=${URI}`,CF);
			let e_errorDiv = document.getElementById('errorDiv');
			e_errorDiv.innerHTML = `ERROR: There was a problem communicating with the server.

Unable to get the class information within 1 second.
Please try again. If this error continues, please notify the site Administrator.`;
			ttLoad(e_errorDiv, '', '', 'error', true);
			
		}
	} // Did the dialog contents load OK?
	if ( DEBUG ) { console.groupEnd(); console.log(PC+'END '+PC+'OpenDialog',SE,ST); }
} // END OpenDialog.

// OpenTextbox(evt, title, text, buttons, returnFunction)
// Open the textboxDiv.
//            evt = event that called this function.
//          title = title of the textbox.
//           text = text for the textbox. Can contain html.
//        buttons = button text in an array.
//                  e.g. ['Yes','No']
//                  Clicking Yes will return 0 and clicking No will return 1
//                  (the array index of the button that was clicked).
// returnFunction = name of a callback function.
// targetLocation = name of field to position TextBox (optional).
function OpenTextbox(evt, title, text, buttons, returnFunction, targetLocation=false) {
	var DEBUG = true;
	if ( DEBUG ) { console.group(PC+`OpenTextbox[title=${title} id=${evt.target.id}]`,CG); }//Collapsed
	if ( DEBUG ) { console.log(PC+`title=${title}, text=${text}, buttons=${buttons}`,CI); }
	if ( DEBUG && dragElement && dragElement.id ) { console.log(PC+`dragElement = ${NL}"id":"${dragElement.id}" ${D_formatJSONstring(dragElement)}`,CL); }
	var e_textboxDiv = document.getElementById('textboxDiv');
	let textboxDivContents = `<fieldset><legend>${title}</legend>\n${text}\n<br><br>\n`;
	for ( let b=0; b<buttons.length; b++ ) {
		textboxDivContents += `<input type="button" class="textboxButton" value="${buttons[b]}" onClick="${returnFunction}(${b});">`;
	}
	textboxDivContents += `\n</fieldset>`;
	e_textboxDiv.innerHTML = textboxDivContents;
	e_textboxDiv.style.display = 'table-cell';
	// BEGIN Position the textbox.
	var e_textboxContainer = document.getElementById('textboxContainer');
	let textboxBounds = ElementBounds('textboxDiv');
	let textboxWidthOffset = textboxBounds.width/2;
	let targetBounds;
	if (!targetLocation) {
		targetBounds = ElementBounds(evt.target.id);
	} else {
		targetBounds = ElementBounds(targetLocation);
	}
	if ( DEBUG ) { console.log(`${PC}targetBounds=${JSON.stringify(targetBounds)}`,CL); }
//	textboxContainerLeft = targetBounds.left + targetBounds.width/2 - textboxWidthOffset;
	textboxContainerLeft = targetBounds.left + targetBounds.width + 50;
	e_textboxContainer.style.left = textboxContainerLeft+'px';
	textboxContainerTop = targetBounds.bottom;
	e_textboxContainer.style.top = textboxContainerTop+'px';
	//.addEventListener('keydown',KeydownTextbox);
	var docScroll = document.documentElement;
	var docLeft = (window.pageXOffset || docScroll.scrollLeft) - (docScroll.clientLeft || 0);
	var docTop = (window.pageYOffset || docScroll.scrollTop)  - (docScroll.clientTop || 0);
	if ( DEBUG ) { console.log(PC+'docLeft='+docLeft+' docTop='+docTop,CL); }
	if ( DEBUG ) { console.log(PC+'textboxContainerLeft='+textboxContainerLeft+' textboxContainerTop='+textboxContainerTop,CL); }
	if ( textboxContainerLeft < docLeft ) {
		textboxContainerLeft = docLeft;
		e_textboxContainer.style.left = textboxContainerLeft+'px';
		if ( DEBUG ) { console.log(PC+'textboxContainer left changed to docLeft='+textboxContainerLeft,CS); }
	}
	if ( textboxContainerLeft < 0 ) {
		textboxContainerLeft = 0;
		e_textboxContainer.style.left = textboxContainerLeft+'px';
		if ( DEBUG ) { console.log(PC+'textboxContainer left changed to 0',CS); }
	}
	if ( textboxContainerTop < docTop ) {
		textboxContainerTop = docTop;
		e_textboxContainer.style.top = textboxContainerTop+'px';
		if ( DEBUG ) { console.log(PC+'textboxContainer top changed to docTop='+textboxContainerTop,CS); }
	}	
	// Make sure textbox is rendered in the viewport
	if ( textboxContainerTop > docTop ) {
		// Get the distance of the sidenav from the top
		// By getting this, it insures the textboxDiv will never render above the top of the sidenav
		// Without this the textbox could render on the top navbar 
		var e_sidenav = document.getElementById("navSidenav");
		var sidenavDistanceFromTop = parseInt(e_sidenav.style.top);
		// Check to see if textbox will be rendered above the sidenav
		if ( textboxContainerTop >= sidenavDistanceFromTop ) {
			textboxContainerTop = sidenavDistanceFromTop;
			e_textboxContainer.style.top = textboxContainerTop+'px';
		if ( DEBUG ) { console.log(PC+'textboxContainer top changed to sidenavDistanceFromTop='+textboxContainerTop,CS); }
		} else {
			textboxContainerTop = docTop;
			e_textboxContainer.style.top = textboxContainerTop+'px';
		if ( DEBUG ) { console.log(PC+'textboxContainer top changed to docTop='+textboxContainerTop,CS); }
		}			
	} else {
		if ( DEBUG ) { console.log('textboxContainerTop ['+textboxContainerTop+'] <= docTop ['+docTop+']'); }
	}
	if ( textboxContainerTop < 0 ) {
		textboxContainerTop = 0;
		e_textboxContainer.style.top = textboxContainerTop+'px';
		if ( DEBUG ) { console.log(PC+'textboxContainer top set to 0',CS); }
	}
	if ( DEBUG ) { console.groupEnd(); }
} // END OpenTextbox.

// ScheduleClass_OpenAddDialog()
// Add a class to the schedule.
function ScheduleClass_OpenAddDialog() {
	var DEBUGAdd = true;
	if ( DEBUGAdd ) { console.warn('ScheduleClass_OpenAddDialog[]'); }
	OpenDialog();
	document.addEventListener('scroll', ScrollDialogDiv);
	return false;
} // END ScheduleClass_OpenAddDialog.

// ScheduleClass_OpenEditDialog(evt)
// Edit the class.
function ScheduleClass_OpenEditDialog(evt) {
	var DEBUG = false;
	evt = (evt) ? evt : window.event;
	if ( DEBUG ) { console.groupCollapsed(PC+`ScheduleClass_OpenEditDialog[] evt.currentTarget.id = ${evt.currentTarget.id}, mousedownFlag = ${mousedownFlag}`,CG); }
	ClearTextSelection();
	evt.currentTarget.removeEventListener('mousemove', ScheduleClassDragCheckWait);
	if ( mousedownFlag === 'mousemove' || evt.button !== 0 ) {
		mousedownFlag = '';
		if ( DEBUG ) { console.log(PC+`mousedownFlag = ${mousedownFlag}`,CI); }
	} else {
		mousedownFlag = 'click';
		if ( DEBUG ) { console.log(PC+`mousedownFlag = ${mousedownFlag}`,CI); }
		// Get scheduleclassId.
		var calendar_class_parts = this.id.split('_');
		currentOpenScheduleClassId = parseInt(calendar_class_parts[2]);
		// Clear the dialogDiv div.
		var e_dialogDiv = document.getElementById('dialogDiv');
		e_dialogDiv.innerHTML = '';
		if ( DEBUG ) { console.log('ScheduleCurrent.scheduleId='+ScheduleCurrent.scheduleId+', ScheduleCurrent.departmentId='+ScheduleCurrent.departmentId+', currentOpenScheduleClassId='+currentOpenScheduleClassId+'];'); }
		ScheduleClassOpenCount = 0; // Reset the ScheduleClassOpenCount counter.
		OpenDialog(currentOpenScheduleClassId);
		document.addEventListener('scroll', ScrollDialogDiv);
	}
	if ( DEBUG ) { console.log(PC+`mousedownFlag = ${mousedownFlag}`,CL); }
	if ( DEBUG ) { console.groupEnd(); console.log(PC+'END '+PC+'ScheduleClass_OpenEditDialog',SE,ST); }
	return false;
} // END ScheduleClass_OpenEditDialog.

// ScrollDialogDiv()
// Reposition the Schedule Class dialog on page scroll.
function ScrollDialogDiv() {
	var DEBUG = false;
	if ( DEBUG ) { console.group(PC+'ScrollDialogDiv[]',CG); }
	if ( DEBUG ) { console.log(PC+'ScrollDialogDiv[] does nothing for now.',CF); }

	if ( DEBUG ) { console.groupEnd(); }
} // END ScrollDialogDiv.

// ScheduleImportClasses(thisTask)
// Handle class import from another schedule.
function ScheduleImportClasses(thisTask) {
	var DEBUG_ScheduleImportClasses = true;
	if ( typeof thisTask === 'undefined' ) { thisTask = ''; }
	if ( DEBUG_ScheduleImportClasses ) { console.warn('ScheduleViewSettings[thisTask='+thisTask+']'); }
	var eId = 'div_ScheduleFunctionsContainer';
	var e = document.getElementById(eId);
	var eDisplay = e.style.display; // Get schedulecontainer height.
	if ( DEBUG_ScheduleImportClasses ) { console.log('eDisplay='+eDisplay); }
	if ( DEBUG_ScheduleImportClasses && eDisplay === 'block' ) { console.log("e.innerHTML.indexOf('Import classes into')="+e.innerHTML.indexOf('Import classes into')); }
	if ( thisTask === '' && eDisplay === 'block' && e.innerHTML.indexOf('Import classes into') !== -1 ) {
		ScheduleTaskShow('ScheduleImportClasses 1528');
		return false;
	} else {
		ScheduleTaskHide();
	}
	switch ( thisTask ) { // switch thisTask.
		case '':
			URI = ROOT_http +'/Schedule/ScheduleImportClasses/ScheduleImportClasses.php';
			var preloadText = '<br><br><span class="bold info">Getting import form. Please wait ...</span><br><br><br>';
			UpdateInclude(URI, eId, preloadText);
			//setTimeout(DisplaySchedule,50);
			window.scrollTo(0, 0);
		break;
		case 'Import classes':
			
			if ( DEBUG_ScheduleImportClasses ) {
				
			}
		break;
		case 'Cancel':
			document.getElementById(eId).style.display = 'none';
			ScheduleTaskShow('ScheduleImportClasses 1552');
		break;
	} // switch thisTask.
	return false;
} // END ScheduleImportClasses.

// ScheduleImportClasses_ScheduleButtonCheck(e)
// Enable/disable Change schedule button.
function ScheduleImportClasses_ScheduleButtonCheck(e) {
	var scheduleIdSelected = e.value;
	console.log('scheduleIdSelected='+scheduleIdSelected);
	if ( scheduleIdSelected ) {
		document.getElementById('btn_Import_schedule_classes').disabled = false;
	} else {
		document.getElementById('btn_Import_schedule_classes').disabled = true;
	}
} // END ScheduleImportClasses_ScheduleButtonCheck.

// ScheduleImportClasses_ParseButtonCheck(e)
// Enable/disable Change schedule button.
function ScheduleImportClasses_ParseButtonCheck(e) {
	var scheduleIdSelected = e.value;
	console.log('scheduleIdSelected='+scheduleIdSelected);
	if ( scheduleIdSelected ) {
		document.getElementById('btn_Import_parsed_classes').disabled = false;
	} else {
		document.getElementById('btn_Import_parsed_classes').disabled = true;
	}
} // END ScheduleImportClasses_ParseButtonCheck.

// ScheduleTaskHide()
// Hide the schedule and display the div_ScheduleFunctionsContainer.
function ScheduleTaskHide() {
	if ( document.getElementById('schedulecontainer') ) {
		var ContainerHeight = Math.max(document.getElementById('schedulecontainer').offsetHeight,document.getElementById('div_ScheduleFunctionsContainer').offsetHeight); // Get schedulecontainer height.
		//console.log('ContainerHeight='+ContainerHeight);
		document.getElementById('schedulecontainer').style.display = 'none'; // Hide the main schedulecontainer.
		document.getElementById('div_CalendarKey').style.display = 'none'; // Hide the calendar key.
		var scheduleClasses = document.getElementsByClassName('calendar_class');
		for ( var i=0; i<scheduleClasses.length; i++ ) {
			scheduleClasses[i].style.display = 'none'; // Hide each schedule class.
		}
		document.getElementById('div_ScheduleFunctionsContainer').style.height = ContainerHeight+'px'; // Set div_ScheduleFunctionsContainer height the same as the main schedulecontainer.
		document.getElementById('div_ScheduleFunctionsContainer').style.display = 'block'; // Show the div_ScheduleFunctionsContainer.
	}
	return false;
} // END ScheduleTaskHide.

// ScheduleTaskShow(callDisplaySchedule)
// Show the schedule and hide the div_ScheduleFunctionsContainer.
function ScheduleTaskShow(by,callDisplaySchedule) {
	console.warn('ScheduleTaskShow[by='+by+', callDisplaySchedule='+callDisplaySchedule+']');
	if ( document.getElementById('schedulecontainer') ) {
		//document.getElementById('schedulecontainer').style.display = 'block'; // Show the main schedulecontainer.
		document.getElementById('div_CalendarKey').style.display = 'block'; // Show the calendar key.
		var scheduleClasses = document.getElementsByClassName('calendar_class');
		for ( var i=0; i<scheduleClasses.length; i++ ) {
			scheduleClasses[i].style.display = 'block'; // Show each schedule class.
		}
		document.getElementById('div_ScheduleFunctionsContainer').style.display = 'none'; // Hide the div_ScheduleFunctionsContainer.
	}
	//if ( typeof callDisplaySchedule === 'undefined' || !callDisplaySchedule ) { DisplaySchedule('1613 '+by); } // Re-display the schedule.
	DisplaySchedule('ScheduleTaskShow 1622 '+by);
	return false;
} // END ScheduleTaskShow.

// ScheduleViewSettings(makeChange)
// Set schedule settings: calendar_dayview, calendar_timebegin, calendar_timeend, calendar_timeincrement, and calendar_incrementheight.
function ScheduleViewSettings(makeChange) {
	var DEBUG = false;
	if ( typeof makeChange === 'undefined' ) { makeChange = ''; }
	if ( DEBUG ) { console.group(`${PC}ScheduleViewSettings[makeChange=${makeChange}]`,CG); }//Collapsed
	var eId = 'div_ScheduleFunctionsContainer';
	var e = document.getElementById(eId);
	var eDisplay = e.style.display; // Get schedulecontainer height.
	if ( DEBUG ) { console.log('eDisplay='+eDisplay); }
	if ( DEBUG && eDisplay === 'block' ) { console.log("e.innerHTML.indexOf('Schedule view settings')="+e.innerHTML.indexOf('Schedule view settings')); }
	if ( makeChange === '' && eDisplay === 'block' && e.innerHTML.indexOf('Schedule view settings') !== -1 ) {
		ScheduleTaskShow('schedule2.js ScheduleViewSettings 149');
		return false;
	} else {
		ScheduleTaskHide();
	}
	switch ( makeChange ) { // switch makeChange.
		case '':
			URI = ROOT_http +'/Schedule/ScheduleViewSettings/ScheduleViewSettings.php';
			var preloadText = '<br><br><span class="bold info">Getting schedule settings. Please wait ...</span><br><br><br>';
			UpdateInclude(URI, eId, preloadText);
			//setTimeout(DisplaySchedule,50);
			window.scrollTo(0, 0);
		break;
		case 'Update schedule settings via javascript':
			// Get settings.
			ScheduleDayView = getRadioValue('calendar_dayview'); // calendar_dayview is work/full week.
			console.log('ScheduleDayView='+ScheduleDayView);
			e = document.getElementById('inp_calendar_timebegin');
			ScheduleTimeBegin = parseInt(e.options[e.selectedIndex].value);
			console.log('ScheduleTimeBegin='+ScheduleTimeBegin);
			e = document.getElementById('inp_calendar_timeend');
			ScheduleTimeEnd = parseInt(e.options[e.selectedIndex].value);
			console.log('ScheduleTimeEnd='+ScheduleTimeEnd);
			e = document.getElementById('inp_calendar_timeincrement');
			ScheduleTimeIncrement = parseInt(e.options[e.selectedIndex].value);
			console.log('ScheduleTimeIncrement='+ScheduleTimeIncrement);
			e = document.getElementById('inp_calendar_incrementheight');
			ScheduleIncrementHeight = parseInt(e.options[e.selectedIndex].value);
			console.log('ScheduleIncrementHeight='+ScheduleIncrementHeight);
			// Need to ensure settings are valid.
			// Calc ScheduleHeightMultiplier.
			ScheduleHeightMultiplier = parseInt(ScheduleIncrementHeight) / parseInt(ScheduleTimeIncrement);
			console.log('ScheduleHeightMultiplier='+ScheduleHeightMultiplier);
			// Calc ScheduleViewDays.
			switch ( ScheduleDayView ) {
				case 'Full week':
					ScheduleViewDays = ScheduleDaysFullWeek; // Should get the string from Weekdays.
				break;
				case 'Work week':
					ScheduleViewDays = ScheduleDaysWorkWeek; // Should get the string from Weekdays.
				break;
			}
			console.log('ScheduleViewDays='+ScheduleViewDays);
			// Save settings in the database.
			URI = ROOT_http + '/Schedule/ScheduleViewSettings/ScheduleViewSettings.php?Update=true';
			URI += '&calendar_dayview='+ScheduleDayView.replace(' ','%20');
			URI += '&calendar_timebegin='+ScheduleTimeBegin;
			URI += '&calendar_timeend='+ScheduleTimeEnd;
			URI += '&calendar_timeincrement='+ScheduleTimeIncrement;
			URI += '&calendar_incrementheight='+ScheduleIncrementHeight;
			eId = 'div_ScheduleFunctionsContainer';
			preloadText = 'Saving schedule view settings ...';
			UpdateInclude(URI, eId, preloadText);
			ScheduleTaskShow('schedule2.js ScheduleViewSettings 203',false);
		break;
		case 'Cancel':
			document.getElementById(eId).style.display = 'none';
			ScheduleTaskShow('schedule2.js ScheduleViewSettings Cancel 207');
		break;
	} // switch makeChange.
	if ( DEBUG ) { console.groupEnd(); }
	return false;
	// getRadioValue(radioName)
	// Returns the value of the radio button that is checked.
	// Returns empty string if no buttons selected or radio control does not exist.
	function getRadioValue(radioName) {
		var DEBUG_getRadioValue = false;
		if ( DEBUG_getRadioValue ) { console.warn('getRadioValue['+radioName+']'); }
		if ( !radioName ) { 
			if ( DEBUG_getRadioValue ) { console.log('radioName is empty.'); }
			return "";
		}
		var radioObj = document.getElementsByName(radioName);
		if ( !radioObj ) {
			if ( DEBUG_getRadioValue ) { console.log('radio with name ['+radioName+'] not found.'); }
		}
		var radioLength = radioObj.length;
		if ( radioLength === undefined ) {
			// Only one radio button.
			if ( radioObj.checked ) {
				if ( DEBUG_getRadioValue ) { console.log('Single radio value=.'+radioObj.value); }
				return radioObj.value;
			} else {
				if ( DEBUG_getRadioValue ) { console.log('Single radio not selected.'); }
				return "";
			}
		} else {
			for(var i = 0; i < radioLength; i++) { // Loop thru radio buttons.
				if (radioObj[i].checked) {
					if ( DEBUG_getRadioValue ) { console.log('Multiple radio value=.'+radioObj[i].value); }
					return radioObj[i].value;
				} // Loop thru radio buttons.
			}
		}
		if ( DEBUG_getRadioValue ) { console.log('Multiple radio none selected.'); }
		return "";
	} // END getRadioValue.
} // END ScheduleViewSettings.

// SetClassEndTime(e)
// Set the class end time based on the # credits, # meeting days, and 'As lab'.
function SetClassEndTime(e) {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.groupCollapsed(`${PC}SetClassEndTime[e.id=${e.id}]`,CG); }//Collapsed
	//document.getElementById('errorDiv').style.display = 'none';
	//divHide('errorDiv');
	// Get scmId.
	var eIdParts = e.id.split('_');
	let scmId = eIdParts[2];
	var EndTime;
	var chkAutoEndId = 'chk_AutoEnd_'+scmId;
	if ( DEBUG ) { console.log('chkAutoEndId='+chkAutoEndId); }
	if ( document.getElementById(chkAutoEndId).checked ) {
		document.getElementById('spn_asLab_'+scmId).style.display = 'inline';
		// Get course credits.
		let courseId = document.getElementById('id_courseId').value;
		if ( courseId ) { // Is the courseId set?
			var CourseCredits = Course[courseId].Cr;
			if ( DEBUG ) { console.log(Course[courseId].Title+' CourseCredits='+CourseCredits); }
			// Get meeting days.
			var days = 0;
			var radioId;
			for ( var weekdayId in Weekdays ){if(Weekdays.hasOwnProperty(weekdayId)){
				radioId = 'chk_Weekday_'+scmId+'_'+weekdayId;
				console.log('radioId='+radioId+' document.getElementById(radioId).checked='+document.getElementById(radioId).checked);
				if ( document.getElementById(radioId).checked ) { days++; }
			}}
			if ( DEBUG ) { console.log('days='+days); }
			if ( days > 0 ) {
				// Get beginning time.
				var BeginTime = document.getElementById('id_scheduleclassmeetingBeginTime_'+scmId).value;
				if ( BeginTime ) {
					var flags = '';
					if ( BeginTime.indexOf('m') !== -1 ) {
						flags = 'a';
					} else {
						if ( BeginTime.indexOf('M') !== -1 ) {
							flags = 'P';
						}
					}
					var BeginMin = ConvertTimeToMinutes(BeginTime);
					if ( DEBUG ) { console.log('BeginTime='+BeginTime+' BeginMin='+BeginMin+' flags='+flags); }
					var meetingMinutes;
					if ( !document.getElementById('chk_AsLab_'+scmId).checked ) {
						meetingMinutes = parseInt( 50 * parseInt(CourseCredits) / days );
					} else {
						meetingMinutes = parseInt( 110 * parseInt(CourseCredits) / days );
					}
					var EndMin = BeginMin + meetingMinutes;
					if ( DEBUG ) { console.log('meetingMinutes='+meetingMinutes+' EndMin='+EndMin); }
					EndTime = ConvertMinutesToTime(EndMin,flags+'h');
					if ( DEBUG ) { console.log('EndTime='+EndTime); }
				} else {
					EndTime = '';
				if ( DEBUG ) { console.log('No begin time, EndTime='+EndTime); }
				}
			} else {
				EndTime = '';
				if ( DEBUG ) { console.log('No days, EndTime='+EndTime); }
			}
			let e_scheduleclassmeetingEndTime = document.getElementById('id_scheduleclassmeetingEndTime_'+scmId);
			e_scheduleclassmeetingEndTime.value = EndTime;
			let e_scheduleclassmeetingBeginTime = document.getElementById('id_scheduleclassmeetingBeginTime_'+scmId);
			// Clear errors.
			divHide('errorDiv');
			if ( DEBUG ) { console.log(`${PC}e_scheduleclassmeetingBeginTime.className=${e_scheduleclassmeetingBeginTime.className} e_scheduleclassmeetingEndTime.className=${e_scheduleclassmeetingEndTime.className}`,CA); }
			if ( e_scheduleclassmeetingBeginTime.className.indexOf('error') !== -1 ) {
				if ( DEBUG ) { console.log(`${PC}Removing error from scheduleclassmeetingBeginTime.`,CD); }
				e_scheduleclassmeetingBeginTime.className = e_scheduleclassmeetingBeginTime.className.replace(' error',''); // Remove error.
			}
			if ( e_scheduleclassmeetingEndTime.className.indexOf('error') !== -1 ) {
				if ( DEBUG ) { console.log(`${PC}Removing error from scheduleclassmeetingEndTime.`,CD); }
				e_scheduleclassmeetingEndTime.className = e_scheduleclassmeetingEndTime.className.replace(' error',''); // Remove error.
			}
		} // Is the courseId set?
	} else {
		document.getElementById('spn_asLab_'+scmId).style.display = 'none';
	}
	Validate_ScheduleClass();
	if ( DEBUG ) { console.groupEnd(); }
} // END SetClassEndTime.

// SetupBuildingSelectOptions(e)
// Set the options for the building select.
function SetupBuildingSelectOptions(e) {
	var DEBUG_SetupBuildingSelectOptions = false;
	if ( DEBUG_SetupBuildingSelectOptions ) { console.log('BEGIN SetupBuildingSelectOptions[e.Id='+e.id+']'); }
	// Get the campusId.
	campusId = parseInt(e.value);
	if ( DEBUG_SetupBuildingSelectOptions ) { console.log('campusId='+campusId); }
	var eId = e.id.split('_');
	var scmId = eId[1];
	var campusIndex = parseInt(eId[2]); // Get the room order.
	if ( DEBUG_SetupBuildingSelectOptions ) { console.log('scmId='+scmId+' campusIndex='+campusIndex); }
	// Clear the building select.
	var eBuildingId = 'selBuilding_'+scmId+'_'+campusIndex;
	if ( DEBUG_SetupBuildingSelectOptions ) { console.log('eBuildingId='+eBuildingId); }
	var eBuilding = document.getElementById(eBuildingId); // Get building select.
	eBuilding.options.length = 0;
	// Clear the room select.
	var eRoomId = 'selRoom_'+scmId+'_'+campusIndex;
	if ( DEBUG_SetupBuildingSelectOptions ) { console.log('eRoomId='+eRoomId); }
	var eRoom = document.getElementById(eRoomId); // Get room select.
	eRoom.options.length = 0;
	var opt = document.createElement('option');
	opt.value = '';
	opt.innerHTML = '';
	eBuilding.appendChild(opt);
	/**/
	if ( DEBUG_SetupBuildingSelectOptions ) { console.log('CollegeBuilding.length='+CollegeBuilding.length+' campusId='+campusId); }
	for ( var i=0; i<CollegeBuilding.length; i++  ) {
		//if ( DEBUG_SetupBuildingSelectOptions ) { console.log('CollegeBuilding['+i+'].campusId='+CollegeBuilding[i].campusId); }
		if ( CollegeBuilding[i].campusId === campusId ) {
			if ( DEBUG_SetupBuildingSelectOptions ) { console.log('CollegeBuilding['+i+'].buildingId='+CollegeBuilding[i].buildingId); }
			if ( DEBUG_SetupBuildingSelectOptions ) { console.log('CollegeBuilding['+i+'].Code='+CollegeBuilding[i].Code); }
			opt = document.createElement('option');
			opt.value = CollegeBuilding[i].buildingId;
			//if ( buildingId === CollegeBuilding[i].buildingId ) { opt.selected = true; }
			opt.innerHTML = CollegeBuilding[i].Code;
			eBuilding.appendChild(opt);
		}
	} // Clear and hide the room select.
	eRoom = document.getElementById('selRoom_'+scmId+'_'+campusIndex); // Get room select.
	eRoom.options.length = 0;
	/**/
	if ( !isNaN(campusId) ) {
		//document.getElementById('labBuilding_'+scmId+'_'+campusIndex).style.display = 'inline-block';
		document.getElementById('labBuilding_'+scmId+'_'+campusIndex).classList.remove("hidden");
	} else {
		var eBuildingLabelId = 'labBuilding_'+scmId+'_'+campusIndex;
		if ( DEBUG_SetupBuildingSelectOptions ) { console.log('Hide '+eBuildingLabelId); }
		var eBuildingLabel = document.getElementById(eBuildingLabelId);
		eBuildingLabel.classList.add("hidden");
		RoomLine_RoomSelect_Hide(scmId, campusIndex); // Hide the room select (label).
	}
	SetupNextCampusSelectOptions(scmId, campusIndex);
} // END SetupBuildingSelectOptions.

// SetupInstructorOptions(e)
// Set the options for the next instructor select.
// Any already selected instructores are not added to the select.
function SetupInstructorOptions(e) {
	var DEBUG_setInstructor = false;
	var c,
			thisSelectId, thisSelect;
	let SelectedInstructorId;
	if ( DEBUG_setInstructor ) { console.log('BEGIN SetupInstructorOptions[e.id='+e.id+']'); }
	var eIdParts = e.id.split('_');
	var scmId = eIdParts[1];
	//var campusIndex = parseInt(eIdParts[2]);
	//var instructorIndex = parseInt(eIdParts[3]);
	//var instructorIndex = parseInt(eIdParts[2]); // unused 2022/04/06 jfm
	if ( DEBUG_setInstructor ) { console.log('ScheduleInstructor.length='+ScheduleInstructor.length); }
	let instructorIdsSelected = []; // Array of instructorIds that have been selected to this point.
	for ( c=0; c<ScheduleInstructor.length; c++ ) { // Loop thru instructor indexes.
		thisSelectId = 'selInstructor_'+scmId+'_'+c;
		if ( DEBUG_setInstructor ) { console.log('thisSelectId='+thisSelectId); }
		thisSelect = document.getElementById(thisSelectId);
		SelectedInstructorId = parseInt(thisSelect.options[thisSelect.selectedIndex].value);
		if ( DEBUG_setInstructor ) { console.log('SelectedInstructorId='+SelectedInstructorId); }
		if ( !isNaN(SelectedInstructorId) ) { instructorIdsSelected.push(SelectedInstructorId); } // Add the instructorId to the array.
	} // Loop thru instructor indexes.
	if ( DEBUG_setInstructor ) { console.log('instructorIdsSelected='+instructorIdsSelected); }
	for ( c=0; c<ScheduleInstructor.length; c++ ) { // Loop thru instructor indexes.
		thisSelectId = 'selInstructor_'+scmId+'_'+c;
		if ( DEBUG_setInstructor ) { console.log('thisSelectId='+thisSelectId); }
		thisSelect = document.getElementById(thisSelectId);
		console.log('thisSelect.selectedIndex='+thisSelect.selectedIndex);
		SelectedInstructorId = parseInt(thisSelect.options[thisSelect.selectedIndex].value);
		let SelectedIndex;
		if ( !isNaN(SelectedInstructorId) ) {
			SelectedIndex = thisSelect.selectedIndex;
		} else {
			SelectedInstructorId = 0;
			SelectedIndex = 0;
		}
		if ( DEBUG_setInstructor ) { console.log('SelectedInstructorId='+SelectedInstructorId+' SelectedIndex='+SelectedIndex); }
		thisSelect.options.length = 0;
		var opt = document.createElement('option');
		opt.value = '';
		opt.innerHTML = '';
		thisSelect.appendChild(opt);
		/**/
		for ( var i=0; i<ScheduleInstructor.length; i++  ) {
			if ( ScheduleInstructor[i].instructorId === SelectedInstructorId || instructorIdsSelected.indexOf(ScheduleInstructor[i].instructorId) === -1 ) { 
				if ( DEBUG_setInstructor ) { console.log('Adding selInstructor_'+c+' option for '+ScheduleInstructor[i].Name+'.'); }
				opt = document.createElement('option');
				opt.value = ScheduleInstructor[i].instructorId;
				opt.innerHTML = ScheduleInstructor[i].Name;
				thisSelect.appendChild(opt);
			}
		}
		if ( SelectedInstructorId ) {
			//thisSelect.selectedIndex = SelectedInstructorId;
			thisSelect.value = SelectedInstructorId;
		}
	} // Loop thru instructor indexes.
} // END SetupInstructorOptions.

// SetupNextCampusSelectOptions(scmId, campusIndex)
// scmId = the scheduleclassmeetingId
// campusIndex = the current campusIndex.
// Set the options for the next campus select (campusIndex+1).
// Any already selected campuses are not added to the next campus select.
function SetupNextCampusSelectOptions(scmId, campusIndex) {
	var DEBUG = false;
	if ( DEBUG ) { console.group(`${PC}SetupNextCampusSelectOptions[scmId=${scmId} campusIndex=${campusIndex}]`,CG); }//Collapsed
	if ( DEBUG ) { console.log(`${PC}END ${PC}SetupNextCampusSelectOptions`,SE,ST); console.groupEnd(); }
	if ( DEBUG ) { console.log('CollegeCampus.length='+CollegeCampus.length); }
	// Get already selected (used) campuses.
	let campusIdsSelected = []; // Array of campusIds that have been selected to this point.
	for ( var c = 0; c <= campusIndex; c++ ) { // Loop thru campuses.
		var thisSelectId = 'selCampus_'+scmId+'_'+c;
		if ( DEBUG ) { console.log('thisSelectId='+thisSelectId); }
		var thisSelect = document.getElementById(thisSelectId);//CollegeCampus[c].campusId);
		let selectedCampusId = parseInt(thisSelect.options[thisSelect.selectedIndex].value);
		if ( DEBUG ) { console.log('selectedCampusId='+selectedCampusId); }
		if ( !isNaN(selectedCampusId) ) { campusIdsSelected.push(selectedCampusId); } // Add the campusId to the array.
	} // Loop thru campuses.
	if ( campusIndex >= 0 ) {
		RoomLine_AddButton_Hide(scmId, campusIndex, 'SetupNextCampusSelectOptions:3236'); // Hide the current + (Add another room) button.
		//RoomLine_RemoveButton_Hide(scmId, campusIndex);
	}
	if ( DEBUG ) { console.log('campusIdsSelected='+campusIdsSelected); }
	let campusIndex_Next = campusIndex + 1;
	if ( DEBUG ) { console.log('typeof CollegeCampus['+campusIndex_Next+']='+(typeof CollegeCampus[campusIndex_Next])); }
	if ( typeof CollegeCampus[campusIndex_Next] !== 'undefined' ) { // Is there another campus after the current one.
		// Yes, Setup campus select options.
		let nextCampusSelect = document.getElementById('selCampus_'+scmId+'_'+campusIndex_Next);
		nextCampusSelect.options.length = 0;
		let opt = document.createElement('option');
		opt.value = '';
		opt.innerHTML = '';
		nextCampusSelect.appendChild(opt);
		for ( var i=0; i<CollegeCampus.length; i++  ) {
			if ( campusIdsSelected.indexOf(CollegeCampus[i].campusId) === -1 ) { 
				if ( DEBUG ) { console.log('Adding option for '+CollegeCampus[i].Name+'.'); }
				opt = document.createElement('option');
				opt.value = CollegeCampus[i].campusId;
				opt.innerHTML = CollegeCampus[i].Name;
				nextCampusSelect.appendChild(opt);
			}
		}
		RoomLine_BuildingSelect_Hide(scmId, campusIndex_Next);
		RoomLine_RoomSelect_Hide(scmId, campusIndex_Next); // Hide the room select (label).
	} // Is there another Campus after the current one.
	if ( DEBUG ) { console.log(`${PC}END ${PC}SetupNextCampusSelectOptions`,SE,ST); console.groupEnd(); }
} // END SetupNextCampusSelectOptions.

// RoomLine_BuildingSelect_Hide(scmId, campusIndex)
// Hide the Rm select (via label) and clear the options.
function RoomLine_BuildingSelect_Hide(scmId, campusIndex) {
	// Hide the building select.
	let labBuildingId = `labBuilding_${scmId}_${campusIndex}`;
	let eBuildingLabel = document.getElementById(labBuildingId);
	if ( !eBuildingLabel.classList.contains('hidden') ) {
		eBuildingLabel.classList.add("hidden");
	}
	// Clear the building select options.
	let eBuildingId = `selBuilding_${scmId}_${campusIndex}`;
	let eBuilding = document.getElementById(eBuildingId);
	eBuilding.options.length = 0;
} // END RoomLine_BuildingSelect_Hide.

// RoomLine_RoomSelect_Hide(scmId, campusIndex)
// Hide the Rm select (via label) and clear the options.
function RoomLine_RoomSelect_Hide(scmId, campusIndex) {
	// Hide the room select.
	let labRoomId = `labRoom_${scmId}_${campusIndex}`;
	let eRoomLabel = document.getElementById(labRoomId);
	if ( !eRoomLabel.classList.contains('hidden') ) {
		eRoomLabel.classList.add("hidden");
	}
	// Clear the room select options.
	let eRoomId = `selRoom_${scmId}_${campusIndex}`;
	let eRoom = document.getElementById(eRoomId);
	eRoom.options.length = 0;
} // END RoomLine_RoomSelect_Hide.

// RoomLine_RoomSelect_Show(scmId, campusIndex)
// Show the Rm select (via label).
function RoomLine_RoomSelect_Show(scmId, campusIndex) {
	let labRoomId = `labRoom_${scmId}_${campusIndex}`;
	let eRoomLabel = document.getElementById(labRoomId);
	eRoomLabel.classList.remove("hidden"); // Show the RM select line.
} // END RoomLine_RoomSelect_Show.

// SetupRoomSelectOptions()
// Set the options for the room select.
function SetupRoomSelectOptions(e) {
	var DEBUG = false;
	if ( DEBUG ) { console.group(`${PC}SetupRoomSelectOptions[e.id=${e.id}]`,CG); }//Collapsed
	// Get the buildingId.
	buildingId = parseInt(e.value);
	if ( DEBUG ) { console.log('buildingId='+buildingId); }
	// Get the room order.
	var eIdParts = e.id.split('_');
	var scmId = eIdParts[1];
	var campusIndex = parseInt(eIdParts[2]); // Get the campusIndex.
	if ( DEBUG ) { console.log('scmId='+scmId+' campusIndex='+campusIndex); }
	let eRoom = document.getElementById('selRoom_'+scmId+'_'+campusIndex); // Get room select.
	eRoom.options.length = 0; // Remove current options.
	// Add the blank option.
	var opt = document.createElement('option');
	opt.value = '';
	opt.innerHTML = '';
	eRoom.appendChild(opt);
	// Add other room options.
	for ( let i=0; i<CollegeRoom.length; i++ ) {
		if ( CollegeRoom[i].buildingId === buildingId ) {
			opt = document.createElement('option');
			opt.value = CollegeRoom[i].roomId;
			//if ( roomId === CollegeRoom[i].roomId ) { opt.selected = true; }
			opt.innerHTML = CollegeRoom[i].Number;
			eRoom.appendChild(opt);
		}
	}
	RoomLine_RoomSelect_Show(scmId, campusIndex); // Show the room select (label).
	/** /
	let eRoomLabelId = 'labRoom_'+scmId+'_'+campusIndex;
	let eRoomLabel = document.getElementById(eRoomLabelId);
	if ( !isNaN(buildingId) ) {
		if ( DEBUG ) { console.log('Show '+eRoomLabelId); }
		eRoomLabel.classList.remove("hidden");
	} else {
		if ( DEBUG ) { console.log('Hide '+eRoomLabelId); }
		eRoomLabel.classList.add("hidden");
	}
	/**/
	// Hide + and - buttons.
	RoomLine_AddButton_Hide(scmId, campusIndex, 'SetupRoomSelectOptions:3346');
	//RoomLine_RemoveButton_Hide(scmId, campusIndex);
	if ( DEBUG ) { console.log(`${PC}END ${PC}SetupRoomSelectOptions`,SE,ST); console.groupEnd(); }
} // END SetupRoomSelectOptions.

// ShowInstructorButton(e)
// Show + add instructor button.
function ShowInstructorButton(e) {
	//console.warn('ShowInstructorButton[instructorId='+instructorId+']');
	var eIdParts = e.id.split('_');
	var scmId = eIdParts[1];
	//var campusIndex = parseInt(eIdParts[2]);
	var instructorIndex = parseInt(eIdParts[2]);
	console.log('scmId='+scmId+' instructorIndex='+instructorIndex);
	if ( document.getElementById('btnShowInstructor_'+scmId+'_'+instructorIndex) ) { document.getElementById('btnShowInstructor_'+scmId+'_'+instructorIndex).style.display = 'inline'; }
} // END ShowInstructorButton.

// ShowInstructorNext(e)
// Show next select element for instructor.
function ShowInstructorNext(e) {
	console.log('BEGIN ShowInstructorNext[e.id='+e.id+']');
	var eIdParts = e.id.split('_');
	var scmId = eIdParts[1];
	//var campusIndex = parseInt(eIdParts[2]);
	//var instructorIndex = parseInt(eIdParts[3]);
	var instructorIndex = parseInt(eIdParts[2]);
	var instructorIndexNext = instructorIndex + 1;
	console.log('scmId='+scmId+' instructorIndex='+instructorIndex+' instructorIndexNext='+instructorIndexNext);
	var btnShowInstructorId = 'btnShowInstructor_'+scmId+'_'+instructorIndex;
	console.log('btnShowInstructorId='+btnShowInstructorId);
	document.getElementById(btnShowInstructorId).style.display = 'none'; // Hide the current + button.
	var divInstructorId = 'divInstructor_'+scmId+'_'+instructorIndexNext;
	console.log('divInstructorId='+divInstructorId);
	document.getElementById(divInstructorId).className = ''; // Remove hidden class.
} // END ShowInstructorNext.

// Room_RoomLine_Hide(scmId, campusIndex)
// Hide the RoomLine (via div id).
// If all RoomLines are now hidden, check the Off campus checkbox.
function Room_RoomLine_Hide(scmId, campusIndex) {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.group(`${PC}Room_RoomLine_Hide[scmId=${scmId} campusIndex=${campusIndex}]`,CG); }//Collapsed
	let allRoomLinesAreHidden = true;
	for ( let loopIndex = 0; loopIndex < CollegeCampus.length; loopIndex++) { // Loop thru RoomLines in reverse.
		// Check if this RoomLine is shown.
		let divRoomId = 'divRoom_'+scmId+'_' + loopIndex;
		if ( DEBUG ) { console.log ('divRoomId='+divRoomId); }
		let eDivRoom = document.getElementById(divRoomId);
		if ( !eDivRoom.classList.contains('hidden') ) { // Is this RoomLine shown?
			if ( DEBUG ) { console.log(`${PC}${divRoomId} is shown`,CT); }
			if ( loopIndex === campusIndex) {
				if ( !eDivRoom.classList.contains('hidden') ) {
					eDivRoom.classList.add("hidden");
					if ( DEBUG ) { console.log(`${PC}${divRoomId} is now hidden`,CF); }
				}
			} else {
				allRoomLinesAreHidden = false;
			}
		} else { // Is this RoomLine shown?
			if ( DEBUG ) { console.log(`${PC}${divRoomId} is hidden`,CF); }
		} // Is this RoomLine shown?
	} // Loop thru RoomLines in reverse.
	if ( DEBUG ) { console.log(`${PC}allRoomLinesAreHidden=${allRoomLinesAreHidden}`,CI); }
	if ( allRoomLinesAreHidden ) {
		// Check the Off campus checkbox.
		let chkClassIsOffCampusId = `chkClassIsOffCampus_${scmId}`;
		let eClassIsOffCampus = document.getElementById(chkClassIsOffCampusId);
		eClassIsOffCampus.checked = true;
		ClassmeetingOffCampus(eClassIsOffCampus)
	}
	if ( DEBUG ) { console.log(`${PC}END ${PC}Room_RoomLine_Hide`,SE,ST); console.groupEnd(); }
} // END Room_RoomLine_Hide. chkClassIsOffCampus _add0

// Room_RoomLine_Show(scmId, campusIndex)
// Show the room line (via div id) and hide the previous + (add another room) button.
function Room_RoomLine_Show(scmId, campusIndex) {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.warn('Room_RoomLine_Show[scmId='+scmId+' campusIndex='+campusIndex+']'); }
	// Show the classroom line.
	var divRoomId = 'divRoom_'+scmId+'_'+campusIndex;
	if ( DEBUG ) { console.log ('divRoomId='+divRoomId); }
	let eDivRoom = document.getElementById(divRoomId);
	eDivRoom.classList.remove("hidden"); // Show the classroom line.
	let campusIndex_Previous = campusIndex - 1;
	if ( DEBUG ) { console.log(`${PC}campusIndex_Previous=${campusIndex_Previous}`,CD); }
	if ( campusIndex_Previous >= 0 ) {
		RoomLine_AddButton_Hide(scmId, campusIndex_Previous, 'Room_RoomLine_Show:3432') // Hide the previous + (Add another room) button.
	}
	SetupNextCampusSelectOptions(scmId, campusIndex_Previous);
	// Uncheck the Off campus checkbox.
	let chkClassIsOffCampusId = `chkClassIsOffCampus_${scmId}`;
	let eClassIsOffCampus = document.getElementById(chkClassIsOffCampusId);
	if ( eClassIsOffCampus.checked ) {
		eClassIsOffCampus.checked = false;
		ClassmeetingOffCampus(eClassIsOffCampus);
	} else {
		//Room_RoomLine_Show(scmId, 0); // Show campusIndex 0 RoomLine.
	}
} // END Room_RoomLine_Show.

// RoomLine_RemoveAddButtons_ShowHide(scmId, campusIndex)
// Show or hide the - (Remove room) and + (add another room) buttons.
function RoomLine_RemoveAddButtons_ShowHide(scmId, campusIndex) {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.group(`${PC}RoomLine_RemoveAddButtons_ShowHide[scmId=${scmId} campusIndex=${campusIndex}]`,CG); }//Collapsed
	let selRoomId = `selRoom_${scmId}_${campusIndex}`;
	let eRoomSelect = document.getElementById(selRoomId);
	if ( DEBUG ) { console.log(`${PC}${selRoomId}.value=${eRoomSelect.value}`,CI); }
	if ( eRoomSelect.value !== '' ) {
		RoomLine_RemoveButton_Show(scmId, campusIndex);
		RoomLine_AddButton_Show(scmId);
	} else {
		//RoomLine_RemoveButton_Hide(scmId, campusIndex);
		RoomLine_AddButton_Hide(scmId, campusIndex, 'RoomLine_RemoveAddButtons_ShowHide:3459');
	}
	if ( DEBUG ) { console.log(`${PC}END ${PC}RoomLine_RemoveAddButtons_ShowHide`,SE,ST); console.groupEnd(); }
} // END RoomLine_RemoveAddButtons_ShowHide.

// RoomLine_AddButton_Hide(scmId, campusIndex)
// Hide + (Add another room) button.
function RoomLine_AddButton_Hide(scmId, campusIndex, by='') {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.group(`${PC}RoomLine_AddButton_Hide[scmId=${scmId} campusIndex=${campusIndex}] by=${by}`,CG); }//Collapsed
		// Hide the + button.
		let ShowRoomLine_btnId = `ShowRoomLineBtn_${scmId}_${campusIndex}`;
		let eShowButton = document.getElementById(ShowRoomLine_btnId);
		if ( eShowButton && !eShowButton.classList.contains('hidden') ) {
			eShowButton.classList.add("hidden");
		}
	if ( DEBUG ) { console.log(`${PC}END ${PC}RoomLine_AddButton_Hide`,SE,ST); console.groupEnd(); }
} // END RoomLine_AddButton_Hide.

// RoomLine_AddButton_Show(scmId)
// Show + (add another room) button if the last shown RoomLine has a room selected.
function RoomLine_AddButton_Show(scmId) {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.group(`${PC}RoomLine_AddButton_Show[scmId=${scmId}]`,CG); }//Collapsed
	for ( let campusIndex = CollegeCampus.length - 1; campusIndex >= 0; campusIndex-- ) { // Loop thru RoomLines in reverse.
		// Check if this RoomLine is shown.
		let divRoomId = 'divRoom_'+scmId+'_'+campusIndex;
		if ( DEBUG ) { console.log ('divRoomId='+divRoomId); }
		let eDivRoom = document.getElementById(divRoomId);
		if ( !eDivRoom.classList.contains('hidden') ) { // Is this RoomLine shown?
			// Check room value.
			let selRoomId = `selRoom_${scmId}_${campusIndex}`;
			let eRoomSelect = document.getElementById(selRoomId);
			if ( DEBUG ) { console.log(`${PC}campusIndex=${campusIndex} eRoomSelect.value=${eRoomSelect.value}`,CI); }
			if ( eRoomSelect.value !== '' ) { // Is there a room value?
				let ShowRoomLine_btnId = `ShowRoomLineBtn_${scmId}_${campusIndex}`;
				if ( DEBUG ) { console.log('ShowRoomLine_btnId='+ShowRoomLine_btnId); }
				let eRoomBtn = document.getElementById(ShowRoomLine_btnId);
				if ( eRoomBtn ) {
					eRoomBtn.classList.remove("hidden");
				}
				break;
			} // Is there a room value?
		} // Is this RoomLine shown?
	} // Loop thru RoomLines in reverse.
	if ( DEBUG ) { console.log(`${PC}END ${PC}RoomLine_AddButton_Show`,SE,ST); console.groupEnd(); }
} // END RoomLine_AddButton_Show.

// RoomLine_RemoveButton_Hide(scmId, campusIndex)
// Hide - (Remove room) button.
function RoomLine_RemoveButton_Hide(scmId, campusIndex) {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.group(`${PC}RoomLine_RemoveButton_Hide[scmId=${scmId} campusIndex=${campusIndex}]`,CG); }//Collapsed
	/** /
	// Hide the - button.
	let btnRemoveId = `btnRemoveRoom_${scmId}_${campusIndex}`;
	let eRemoveButton = document.getElementById(btnRemoveId);
	if ( !eRemoveButton.classList.contains('hidden') ) {
		eRemoveButton.classList.add("hidden");
	}
	/**/
	if ( DEBUG ) { console.log(`${PC}END ${PC}RoomLine_RemoveButton_Hide`,SE,ST); console.groupEnd(); }
} // END RoomLine_RemoveButton_Hide.

// RoomLine_RemoveButton_Show(scmId, campusIndex)
// Show the - (Remove room) button.
function RoomLine_RemoveButton_Show(scmId, campusIndex) {
	let btnRemoveRoomId = 'btnRemoveRoom_'+scmId+'_'+campusIndex;
	let eRemoveRoomBtn = document.getElementById(btnRemoveRoomId);
	eRemoveRoomBtn.classList.remove("hidden");
} // END RoomLine_RemoveButton_Show.

// SidenavToggle(e)
// Show / hide side nav sub menu.
function SidenavToggle(e) {
	ttHide();
	var DEBUG = false;
	if ( DEBUG ) { console.group(PC+'SidenavToggle[e.id='+e.id+']',CG); }
	var eIdParts = e.id.split('_');
	var sidenavName = eIdParts[1]; // Get sidenav menu name.
	var subs = document.getElementsByClassName(sidenavName+' sub');
	if ( DEBUG ) { console.log(PC+'eIdParts='+eIdParts,CL); }
	if ( DEBUG ) { console.log(PC+'sidenavName='+sidenavName+' subs.length='+subs.length,CI); }
	// Get the span in the link.
	var spans = e.getElementsByTagName('span');
	//if ( DEBUG ) { console.log(PC+'spans.length='+spans.length,CL); }
	var menu_innerHTML = spans[0].innerHTML;
	if ( DEBUG ) { console.log(PC+sidenavName+' a#'+e.id+' span.innerHTML='+menu_innerHTML,CI); }
	
	if ( menu_innerHTML === '▼' )
	//if ( ShowSub ) 
	{
		// Open sub-menu.
		if ( DEBUG ) { console.log(PC+'Open '+sidenavName+' sub-menu',CD); }
		document.getElementById('a_'+sidenavName).onmouseover = function(){ttShow('Close '+sidenavName.toLowerCase()+' sub menu.');};
		spans[0].innerHTML = '▲';
		//document.getElementById('spn_'+sidenavName).innerHTML = '▲';
		ttShow('Close '+sidenavName+' task menu.');
	} else {
		// Close sub-menu.
		if ( DEBUG ) { console.log(PC+'Close '+sidenavName+' sub-menu',CD); }
		document.getElementById('a_'+sidenavName).onmouseover = function(){ttShow('Open '+sidenavName.toLowerCase()+' sub menu.');};
		spans[0].innerHTML = '▼';
		//document.getElementById('spn_'+sidenavName).innerHTML = '▼';
		ttShow('Open '+sidenavName+' task menu.');
	}
	// Show/Hide sub-menu items.
	//var ShowSub = false; // unused 2022/04/06 jfm
	for ( var i=0; i<subs.length; i++ ) {
		//if ( DEBUG ) { console.log(PC+TB+'id='+subs[i].id+' style.display='+subs[i].style.display,CL); }
		switch (menu_innerHTML) {
			case '▲':
				if ( DEBUG ) { console.log(PC+TB+'Hide '+subs[i].id,CL); }
				subs[i].style.display = 'none';
				break;
			case '▼':
				if ( DEBUG ) { console.log(PC+TB+'Show '+subs[i].id,CL); }
				subs[i].style.display = 'inline-block';
				break;
		}
		/** /
		if ( subs[i].style.display === 'inline-block' ) {
			subs[i].style.display = 'none';
		} else {
			ShowSub = true;
			subs[i].style.display = 'inline-block';
		}
		/**/
	}
	/** /
	if ( menu_innerHTML === '▼' )
	//if ( ShowSub ) 
	{
		// Open sub-menu.
		if ( DEBUG ) { console.log(PC+'Open '+sidenavName+' sub-menu',CD); }
		document.getElementById('a_'+sidenavName).onmouseover = function(){ttShow('Close '+sidenavName.toLowerCase()+' sub menu.');};
		spans[0].innerHTML = '▲';
		//document.getElementById('spn_'+sidenavName).innerHTML = '▲';
		ttShow('Close '+sidenavName+' task menu.');
	} else {
		// Close sub-menu.
		if ( DEBUG ) { console.log(PC+'Close '+sidenavName+' sub-menu',CD); }
		document.getElementById('a_'+sidenavName).onmouseover = function(){ttShow('Open '+sidenavName.toLowerCase()+' sub menu.');};
		spans[0].innerHTML = '▼';
		//document.getElementById('spn_'+sidenavName).innerHTML = '▼';
		ttShow('Open '+sidenavName+' task menu.');
	}
	/**/
	if ( DEBUG ) { console.groupEnd(); }
	return false;
} // END SidenavToggle.

function SaveAutoscrollPosition() { // by Garrett Wiley.
	document.cookie = "sp=" + document.getElementById("schedulecontainer").getBoundingClientRect().top;
} // END SaveAutoscrollPosition by Garrett Wiley.


function AutoscrollPage(todelete) { // by Garrett Wiley.
	var cook = document.cookie.split(" ");
	var scrollPos = 0;
	var scheduleVar = document.getElementById("schedulecontainer");
	//if(bcrt == 0)bcrt = scheduleVar.getBoundingClientRect().top;
	if(bcrt === 0){bcrt = scheduleVar.getBoundingClientRect().top;}
	
	for(var i = 0; i < cook.length; i++) {
		if(cook[i].substr(0, 3) === "sp=") {
			scrollPos = bcrt - parseInt(cook[i].replace(";", "").substr(3, cook[i].length-3));
		}
	}
	
	if(todelete === 1) {
		document.cookie = "sp=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
	}
	
	window.scrollTo(0, scrollPos);
} // END AutoscrollPage by Garrett Wiley.

document.addEventListener('DOMContentLoaded', function() { // addEventListener for AutoscrollPage by Garrett Wiley. See https://www.rgraph.net/canvas/docs/the-domcontentloaded-event.html
	AutoscrollPage(1);
}, false);

// ScheduleClass_RemoveClassVerify(thisTask)
// Verify removal of schedule class.
function ScheduleClass_RemoveClassVerify(thisTask) {
	var DEBUG_ScheduleClass_RemoveClassVerify = true;
	if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.log('BEGIN ScheduleClass_RemoveClassVerify[thisTask='+thisTask+']'); }
	if ( typeof thisTask === 'undefined' ) {
		if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.log('Display div_RemoveClassVerify'); }
		document.getElementById('div_RemoveClassVerify').style.display = 'block';
	} else if ( thisTask ) {
		if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.log('Yes clicked.'); }
		if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.warn('ScheduleClass_RemoveClassVerify[scheduleId='+ScheduleCurrent.scheduleId+', departmentId='+ScheduleCurrent.departmentId+', scheduleclassId='+currentOpenScheduleClassId+'];'); }
		// Remove the calendar_class divs from the DOM.
		if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.log(SCMnow[currentOpenScheduleClassId]); }
		for (let i = 0; i < SCMnow[currentOpenScheduleClassId].length; i++) { // Loop thru class meetings.
			for (let x = 0; x < SCMnow[currentOpenScheduleClassId][i].days.length; x++) { // Loop through class meeting days.
				var calendar_class_Id = 'calendar_class_'+currentOpenScheduleClassId+'_'+SCMnow[currentOpenScheduleClassId][i].days[x]+SCMnow[currentOpenScheduleClassId][i].tdMinute;
				if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.log(calendar_class_Id); }	
				document.getElementById(calendar_class_Id).remove();		
			} // Loop through class meeting days.
		} // Loop thru class meetings.

		// Remove the ClassMeetings from local.
		SCMnow[currentOpenScheduleClassId] = [];

		// Remove the ClassMeetings from the database.
		URI = ROOT_http + '/Schedule/ScheduleClass/ScheduleClassUpdate.php?';
		URI += 'task=RemoveClass';
		URI += '&scId='+currentOpenScheduleClassId;
		UpdateInclude(URI, false); 
		CloseDialog();
		DisplaySchedule('ScheduleClass_RemoveClassVerify 3699');
	} else {
		if ( DEBUG_ScheduleClass_RemoveClassVerify ) { console.log('No clicked.'); }
		document.getElementById('div_RemoveClassVerify').style.display = 'none';
	}
} // END ScheduleClass_RemoveClassVerify.

// For use by Jonathan Plotz

// ccs = Credential color set.
var ccs = [];
    ccs[0] = { index:1, color:['Tomato', 'Electric crimson'] };
    ccs[1] = { index:1, color:['Orange', 'Fulvous'] };
    ccs[2] = { index:1, color:['Yellow', 'Citrine'] };
    ccs[3] = { index:1, color:['Lime', 'Kelly green'] };
    ccs[4] = { index:1, color:['Celeste', 'Cyan'] };
    ccs[5] = { index:1, color:['Brilliant lavender', 'Heliotrope'] };

// DisplaySchedule_Highlight()
// Highlights the schedule.
function DisplaySchedule_Highlight() {
	var DEBUG = false;
	if ( DEBUG ) { console.warn('DisplaySchedule_Highlight[] ScheduleHighlightView='+ScheduleHighlightView+''); }
	// Hide all highlight type color keys.
	divHide('divHighlightNone');
	divHide('divHighlightConflict');
	divHide('divHighlightCredential');
	divHide('divHighlightInstructor');
	divHide('divHighlightRoom');
	// Show the current color key.
	switch ( ScheduleHighlightView ) {
		case 'None':
			if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_None[]',CC); }
			DisplaySchedule_Highlight_None();
			document.getElementById('divHighlightNone').style.display = 'block';
		break;
		case 'Conflict':
			if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_Conflicts[]',CC); }
			DisplaySchedule_Highlight_Conflicts();
			document.getElementById('divHighlightConflict').style.display = 'block';
		break;
		case 'Credential':
			if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_Credentials[]',CC); }
			DisplaySchedule_Highlight_Credentials();
			document.getElementById('divHighlightCredential').style.display = 'block';
		break;
		case 'Instructor':
			if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_Instructors[]',CC); }
			DisplaySchedule_Highlight_Instructors();
			document.getElementById('divHighlightInstructor').style.display = 'block';
		break;
		case 'Room':
			if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_Rooms[]',CC); }
			DisplaySchedule_Highlight_Rooms();
			document.getElementById('divHighlightRoom').style.display = 'block';
		break;
	}
} // END DisplaySchedule_Highlight.

// DisplaySchedule_Highlight_None()
// Check schedule for class 1) Degree/year, 2) room, or 3) Instructor conflicts and change meeting styles to show them.
function DisplaySchedule_Highlight_None() {
	var DEBUG = false;
	if ( DEBUG ) { console.groupCollapsed(`${PC}DisplaySchedule_HighlightNone[]`,CG); }
	/** /
	var	eCalendarClassDiv,
			calendar_class_div_base,
			calendar_class_div_id,
			dayIndex,
			meetingIndex,
			scId;
	/**/
	let CalendarClassDivs = document.querySelectorAll('div[id^="calendar_class_"]');
	//let CalendarClassDivsCount = CalendarClassDivs.length; // unused 2022/04/06 jfm
	CalendarClassDivs.forEach(function(e, index) {
		let Course, Section;
		if ( DEBUG ) {
			// Get the course numbers.
			//console.log(`${PC}${CalendarClassDivs[index].id}`,CL);
			let idParts = CalendarClassDivs[index].id.split('_');
			let scId = idParts[2];
			//console.log(`scmId = ${scmId}`);
			//let scId = ClassMeeting_ScheduleClass[scmId];
			//console.log(`scId = ${scId}`);
			Course = ScheduleClass[scId].Course;
			Section = ScheduleClass[scId].Section;
			//console.log(JSON.stringify(Course));
		}
		if ( DEBUG ) { console.log(`${PC}${Course}-${Section} ${CalendarClassDivs[index].id} ${CalendarClassDivs[index].className}`,CL); }
		// Remove highlights.
		CalendarClassDivs[index].style.border = null;
		if ( e.className.indexOf('calendar_class') !== -1 ) {
			e.className = 'calendar_class';
		} else
		if ( e.className.indexOf('calendar_arranged') !== -1 ) {
			e.className = 'calendar_arranged';
		} else {
			e.className = 'calendar_hidden';
		}
		if ( DEBUG ) { 
			if ( e.className.indexOf('calendar_class') !== -1 ) {
				console.log(`${PC}${Course}-${Section} ${CalendarClassDivs[index].id} ${CalendarClassDivs[index].className}`,CD);
			} else
			if ( e.className.indexOf('calendar_arranged') !== -1 ) {
				console.log(`${PC}${Course}-${Section} ${CalendarClassDivs[index].id} ${CalendarClassDivs[index].className}`,CI);
			} else {
				console.log(`${PC}${Course}-${Section} ${CalendarClassDivs[index].id} ${CalendarClassDivs[index].className}`,CW);
			}
		}
	});
	/** /
	for ( scId in ScheduleClass ) {if(ScheduleClass.hasOwnProperty(scId)) { // Loop thru classes.
		calendar_class_div_base = 'calendar_class_'+scId+'_';
		const MeetingCount = SCMnow[scId].length;
		for ( meetingIndex=0; meetingIndex<MeetingCount; meetingIndex++ ) { // Loop thru 1st class meetings.
			// instructor and room code see below.
			let DaysCount = SCMnow[scId][meetingIndex].days.length;
			for ( dayIndex=0; dayIndex<DaysCount; dayIndex++ ) { // Loop thru days.
				calendar_class_div_id = calendar_class_div_base + SCMnow[scId][meetingIndex].days[dayIndex] + ConvertTimeToMinutes(SCMnow[scId][meetingIndex].bTime);
				//console.log(PC+'calendar_class_div_id='+calendar_class_div_id,CI);
				eCalendarClassDiv = document.getElementById(calendar_class_div_id);
				// Do what you need here.
				// See DisplaySchedule_Highlight_Conflicts() in scheduler.js to see how to find instructors and rooms. Credential info is not available yet!
				eCalendarClassDiv.className="calendar_class";
				eCalendarClassDiv.style.border = '';
			} // Loop thru days.
		} // Loop thru 1st class meetings.
	}} // Loop thru classes.
	/**/
	if ( DEBUG ) { console.log(`${PC}END ${PC}DisplaySchedule_HighlightNone`,SE,CG); console.groupEnd(); }
} // END DisplaySchedule_Highlight_None.

// DisplaySchedule_Highlight_Rooms()
// Highlight the different rooms.
function DisplaySchedule_Highlight_Rooms() {
	var DEBUG = false;
	if ( DEBUG ) { console.warn('DisplaySchedule_Highlight_Rooms[]'); }
	if ( DEBUG ) { console.log(PC+'DisplaySchedule_Highlight_None[]',CC); }
	DisplaySchedule_Highlight_None();
} // END DisplaySchedule_Highlight_Rooms.

// HasAttributeWithValue( theObject, theAttribute, theValue )
// Search in an array of objects for an attribute with the value you are searching for.
// Returns an array of objects that have an attribute with a value that matches.
//    theObject = The array to search.
// theAttribute = The attribute to search. Must be set before function call.
//     theValue = the attribute value you are searching for.
function HasAttributeWithValue(theArray,theAttribute,theValue) {
	return theArray.filter(function(el) {
		if ( typeof el[theAttribute] !== 'object' ) {
			return el[theAttribute] === theValue;
		} else {
			return el[theAttribute].indexOf(theValue) !== -1 ;
		}
	});
} // END HasAttributeWithValue.

// MoveCLass_Cancel()
// Cancel the class move and put the calendar_class divs back to their original locations.
function MoveCLass_Cancel(scId) {
	var DEBUG = false;
	if ( DEBUG ) { console.group(PC+`MoveCLass_Cancel[scId=${scId}]`,CG); }
	CloseDialog();
	// BEGIN Restore calendar_class div ids to original.
	// Collect current calendar_class divs for this scId.
	let calendar_class_divs = document.querySelectorAll('*[id^="calendar_class_'+scId+'"]');
	if ( DEBUG ) { console.log(`${PC}calendar_class_divs=${D_formatJSONstring(calendar_class_divs)}`,CL); }
	if ( DEBUG ) { let text = 'current ids ='; calendar_class_divs.forEach(e => { text += ` ${e.id}`; }); console.log(`${PC}${text}`,CI); }
	if ( DEBUG ) { console.log(`${PC}SCMnow[${scId}]=${D_formatJSONstring(SCMnow[scId])}`,CI); }
	if ( DEBUG ) { console.log(`${PC}SCMold[${scId}]=${D_formatJSONstring(SCMold[scId])}`,CI); }
	if ( DEBUG ) { console.log(PC+'ClassMeetings = '+D_formatJSONstring(SCMnow[scId]),CD); }
	// Restore original calendar_class div Ids.
	if ( DEBUG ) { console.log(PB+'Reset div Ids',SB,ST); }
	for ( let IndexClassMeeting in SCMnow[scId] ){if(SCMnow[scId].hasOwnProperty(IndexClassMeeting)){ // Loop thru class meetings.
		if ( DEBUG ) { console.log(PC+'IndexClassMeeting = '+IndexClassMeeting,CL); }
		//if ( DEBUG ) { console.log(PC+'Current_mTime = '+Current_mTime,CL); }
		if ( DEBUG ) { console.log(`${PC}SCMnow[${scId}][${IndexClassMeeting}].days.length=${SCMnow[scId][IndexClassMeeting].days.length}`,CL); }
		if ( SCMnow[scId][IndexClassMeeting].days.length > 0 ) {
			let Original_mTime = ConvertTimeToMinutes(SCMnow[scId][IndexClassMeeting].bTime) - SCMnow[scId][IndexClassMeeting].mbTimeDiff;
			let Current_mTime = ConvertTimeToMinutes(SCMnow[scId][IndexClassMeeting].bTime);
			for ( let IndexDay in SCMnow[scId][IndexClassMeeting].days ){if(SCMnow[scId][IndexClassMeeting].days.hasOwnProperty(IndexDay)){ // Loop thru the days.
				if ( DEBUG ) { console.log(PC+'IndexDay = '+IndexDay,CL); }
				let Original_Day = Weekdays[WeekdayD[SCMnow[scId][IndexClassMeeting].days[IndexDay]] - SCMnow[scId][IndexClassMeeting].dayDiff].weekdayD;
				let Current_Day = SCMnow[scId][IndexClassMeeting].days[IndexDay];
				//if ( DEBUG ) { console.log(PC+'Current_Day = '+Current_Day,CL); }
				let originalId = 'calendar_class_' + scId + '_' + Original_Day + Original_mTime;
				let currentlId = 'calendar_class_' + scId + '_' + Current_Day + Current_mTime;
				//let currentlId = calendar_class_divs[IndexDay];
				if ( DEBUG ) { console.log(PC+`original id = ${originalId}`,CI); }
				if ( DEBUG ) { console.log(PC+` current id = ${currentlId}`,CI); }
				document.getElementById(currentlId).id = originalId;
			}}
		}
	}} // Loop thru class meetings.
	if ( DEBUG ) { console.log(PE+'Reset div Ids',SE,ST); }
	if ( DEBUG ) { console.log(PC+`SCMnow[${scId}][0].bTime=${SCMnow[scId][0].bTime} SCMold[${scId}][0].bTime=${SCMold[scId][0].bTime}`,CL); }
	// Reset SCMnow.
	SCMnow[scId] = JSON.parse(JSON.stringify(SCMold[scId])); // Restore original.
	EventListeners_Add();
	DisplaySchedule('MoveCLass_Cancel 152');
	if ( DEBUG ) { console.groupEnd(); }
} // END MoveCLass_Cancel.

/** /
									instructors = SCMnow[scId][meetingIndex].instructors;
									if ( instructors.length ) { // Is there an instructor?
										instructorConflict = false;
										for ( instructorIndex=0; instructorIndex<instructors.length; instructorIndex++ ) { // Loop thru 1st instructors.
											instructor = instructors[instructorIndex];
											// Now you have the instructor name.
											
										} // Loop thru 1st instructors.
									} // Is there an instructor?

									rooms = SCMnow[scId][meetingIndex].rooms;
									if ( rooms.length ) { // Is there an room?
										roomConflict = false;
										for ( roomIndex=0; roomIndex<rooms.length; roomIndex++ ) { // Loop thru 1st rooms.
											room = rooms[roomIndex];
											// Now you have the room number.
											
										} // Loop thru 1st rooms.
									} // Is there an room?
/**/

// For use by Tyson Tvinnereim

//alert("schedule6.js has been successfully included in scheduleclassmeetingform!");

// Search_HighlightMeetings()
// Hightlight meetings found by search.
function Search_HighlightMeetings() {
	var DEBUG = DEBUG_OFF;
	if ( DEBUG ) { console.groupCollapsed(`${PC}Search_HighlightMeetings[]`,CG); }//
	if ( DEBUG ) { console.log(`${PC}Search_FindMeetings.idsToHighlight.length=${Search_FindMeetings.idsToHighlight.length}`,CI); }
	if ( Search_FindMeetings.idsToHighlight.length ) { // Are there idsToHighlight?
		for ( let i=0; i<Search_FindMeetings.idsToHighlight.length; i++ ) { // Loop thru idsToHighlight.
			let thisId = Search_FindMeetings.idsToHighlight[i];
			let eToHighlight = document.getElementById(thisId);
			eToHighlight.style.boxShadow = '0 0 10px 8px green';
			eToHighlight.style.zIndex = 20;
			eToHighlight.style.marginRight = '15px';
			eToHighlight.style.outline = 'green solid 4px';
		} // Loop thru idsToHighlight.
	} // Are there idsToHighlight?
	if ( DEBUG ) { console.groupEnd(); }
} // END Search_HighlightMeetings.

// Search_FindMeetings(search)
// Find and highlight class meetings that match search.
function Search_FindMeetings(search) {
	var DEBUG = false;
	if ( DEBUG ) { console.group(`${PC}Search_FindMeetings[search=${search}]`,CG); }//Collapsed
	let i, j, k;
	let newId;
	let courseFiler = [];
	let scId;
	for( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClasses.
		courseFiler.push(ScheduleClass[scId].courseId);
	}} // Loop thru ScheduleClasses.
	Search_FindMeetings.idsToHighlight = [];
	if ( DEBUG ) { console.log(`${PC}Searching for ${search}`,CI); }
	// BEGIN Search thru Courses.
	for ( var courseId in Course ){if(Course.hasOwnProperty(courseId)){ // Loop thru courses.
		//if ( DEBUG ) { console.log(`${PC} Course[${cId}]=${JSON.stringify( Course[courseId])}`,CL); }
		if ( courseFiler.indexOf(courseId) !== -1 ) { // Is this course in the filter?
			// Search the course dept number and title.
			let course = Course[courseId];
			let courseInfo = course.Dept + course.Number + ' ' + course.Title;
			if ( DEBUG ) { console.log(`${PC}courseInfo=${courseInfo} ( courseInfo.indexOf(search) !== -1 )=${( courseInfo.indexOf(search) !== -1 )}`,CL); }
			let classMeetingPushed = false;
			if ( courseInfo.indexOf(search) !== -1 ) { // Is the courseInfo in the search?
				for ( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClasses.
					if ( DEBUG ) { console.log(`${PC}( ScheduleClass[scId].courseId === courseId =${( ScheduleClass[scId].courseId === courseId )}`,CL); }
					if ( ScheduleClass[scId].courseId === courseId ) { // Do the courseIds match?
						for ( i=0; i<SCMnow[scId].length; i++ ) { // Loop thru ClassMeetings.
							let classMeeting = SCMnow[scId][i];
							let mTime = ConvertTimeToMinutes(classMeeting.bTime);
							if ( isNaN(mTime) ) { mTime = 0; }
							if ( DEBUG ) { console.log(`${PC}mTime=${mTime} classMeeting.days.length=${classMeeting.days.length}`,CL); }// classMeeting=${JSON.stringify(classMeeting)}
							if ( classMeeting.days.length > 0  ) { // Does this classMeeting have days?
								// Yes, use the days to build the ids.
								for ( j =-0; j<classMeeting.days.length; j++ ) { // Loop thru the days.
									let day = classMeeting.days[j];
									newId = `calendar_class_${scId}_${day}${mTime}`;
									if ( DEBUG ) { console.log(`${PC}newId=${newId} day=${day}`,CL); }
									Search_FindMeetings.idsToHighlight.push(newId);
									classMeetingPushed = true;
								} // Loop thru the days.
							} else { // Does this classMeeting have days?
								// No, build no-day id.
								newId = `calendar_class_${scId}_${mTime}`;
								if ( DEBUG ) { console.log(`${PC}newId=${newId}`,CL); }
								Search_FindMeetings.idsToHighlight.push(newId);
								classMeetingPushed = true;
							} // Does this classMeeting have days?
						} // Loop thru ClassMeetings.
					} // Do the courseIds match?
				}} // Loop thru ScheduleClasses.
			} // Is the courseInfo in the search?
			if ( !classMeetingPushed ) { //Was the class meeting NOT put in idsToHighlight?
				// Search rooms.
				let roomSearch = search.replace('Room ','');
				if ( DEBUG ) { console.log(`${PC}roomSearch=[${roomSearch}]`,CD); }
				for ( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClass.
					//if ( DEBUG ) { console.log(`${PC}course.Id=${course.Id}  ScheduleClass[${scId}].courseId=${ ScheduleClass[scId].courseId}`,CL); }
					if ( course.Id == ScheduleClass[scId].courseId ) { // Do the courseIds match?
						for ( j=0; j<SCMnow[scId].length;j++ ) { // Loop thru ClassMeetings
							let classMeeting = SCMnow[scId][j];
							if ( DEBUG ) { console.log(`${PC}classMeeting.rooms.length=${classMeeting.rooms.length}`,CL); }
							if ( classMeeting.rooms.length ) { // Are there rooms.
								for ( k=0; k<classMeeting.rooms.length; k++ ) { // Loop thru rooms. 
									let room = classMeeting.rooms[k];
									if ( DEBUG ) { console.log(`${PC}room=[${room}] room.indexOf(${roomSearch}) !== -1 == ${(room.indexOf(roomSearch) !== -1)}`,CI); }
									if ( room.indexOf(roomSearch) !== -1 ) { // Is the room in the search?
										if ( Search_FindMeetings.idsToHighlight.indexOf(room) == -1 ) { // Has the room not been added to idsToHighlight?
											let mTime = ConvertTimeToMinutes(classMeeting.bTime);
											if ( isNaN(mTime) ) { mTime = 0; }
											if ( DEBUG ) { console.log(`${PC}mTime=${mTime} classMeeting.days.length=${classMeeting.days.length}`,CL); }// classMeeting=${JSON.stringify(classMeeting)}
											if ( classMeeting.days.length > 0  ) { // Does this classMeeting have days?
												// Yes, use the days to build the ids.
												for ( j =-0; j<classMeeting.days.length; j++ ) { // Loop thru the days.
													let day = classMeeting.days[j];
													let newId = `calendar_class_${scId}_${day}${mTime}`;
													if ( DEBUG ) { console.log(`${PC}newId=${newId} day=${day}`,CL); }
													Search_FindMeetings.idsToHighlight.push(newId);
													classMeetingPushed = true;
												} // Loop thru the days.
											} else { // Does this classMeeting have days?
												// No, build no-day id.
												newId = `calendar_class_${scId}_${mTime}`;
												if ( DEBUG ) { console.log(`${PC}newId=${newId}`,CL); }
												Search_FindMeetings.idsToHighlight.push(newId);
												classMeetingPushed = true;
											} // Does this classMeeting have days?
										} // Has the room not been added to idsToHighlight?
									} // Is the room in the search?
								} // Loop thru rooms.
							} // Are there rooms.
						} // Loop thru ClassMeetings
					} // Do the courseIds match?
				}} // Loop thru ScheduleClass.
				if ( !classMeetingPushed ) { //Was the class meeting NOT put in idsToHighlight?
					// Search instructors.
					for ( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClass.
						//if ( DEBUG ) { console.log(`${PC}course.Id=${course.Id}  ScheduleClass[${scId}].courseId=${ ScheduleClass[scId].courseId}`,CL); }
						if ( course.Id == ScheduleClass[scId].courseId ) { // Do the courseIds match?
							for ( j=0; j<SCMnow[scId].length;j++ ) { // Loop thru ClassMeetings
								let classMeeting = SCMnow[scId][j];
								if ( DEBUG ) { console.log(`${PC}classMeeting.instructors.length=${classMeeting.instructors.length}`,CL); }
								if ( classMeeting.instructors.length ) { // Are there instructors.
									for ( k=0; k<classMeeting.instructors.length; k++ ) { // Loop thru instructors.
										let instructorName = InstructorLookup[classMeeting.instructors[k]].Name;
										if ( instructorName.indexOf(search) !== -1 ) { // Did we find and instructor name?
											if ( Search_FindMeetings.idsToHighlight.indexOf(instructorName) == -1 ) { // Has the instructorName not been added to idsToHighlight?
												let mTime = ConvertTimeToMinutes(classMeeting.bTime);
												if ( isNaN(mTime) ) { mTime = 0; }
												if ( DEBUG ) { console.log(`${PC}mTime=${mTime} classMeeting.days.length=${classMeeting.days.length}`,CL); }// classMeeting=${JSON.stringify(classMeeting)}
												if ( classMeeting.days.length > 0  ) { // Does this classMeeting have days?
													// Yes, use the days to build the ids.
													for ( j =-0; j<classMeeting.days.length; j++ ) { // Loop thru the days.
														let day = classMeeting.days[j];
														let newId = `calendar_class_${scId}_${day}${mTime}`;
														if ( DEBUG ) { console.log(`${PC}newId=${newId} day=${day}`,CL); }
														Search_FindMeetings.idsToHighlight.push(newId);
														classMeetingPushed = true;
													} // Loop thru the days.
												} else { // Does this classMeeting have days?
													// No, build no-day id.
													newId = `calendar_class_${scId}_${mTime}`;
													if ( DEBUG ) { console.log(`${PC}newId=${newId}`,CL); }
													Search_FindMeetings.idsToHighlight.push(newId);
													classMeetingPushed = true;
												} // Does this classMeeting have days?
											} // Has the instructorName not been added to idsToHighlight?
										} // Did we find and instructor name?
									} // Loop thru instructors.
								} // Are there instructors.
							} // Loop thru ClassMeetings
						} // Do the courseIds match?
					}} // Loop thru ScheduleClass.
				} //Was the class meeting NOT put in idsToHighlight?
			} //Was the class meeting NOT put in idsToHighlight?
			if ( DEBUG ) { console.log(`${PC}.idsToHighlight =${Search_FindMeetings.idsToHighlight}`,CI); }
			if ( classMeetingPushed ) { //Was the class meeting NOT put in idsToHighlight?
				// We have the idsToHighlight here and now need to highlight the Ids.
				Search_HighlightMeetings();
			} //Was the class meeting NOT put in idsToHighlight?
		} // Is this course in the filter?
	}}// Loop thru courses.
	//   END Search thru Courses.		
	if ( DEBUG ) { console.groupEnd(); }
} // END Search_FindMeetings.
Search_FindMeetings.idsToHighlight = [];

// Search_UpdateDatalist(e)
// Populate schedule search datalist from input.
function Search_UpdateDatalist(evt) {
	evt = (evt) ? evt : window.event;
	var DEBUG = false;
	if ( DEBUG ) { console.clear(); console.group(`${PC}Search_UpdateDatalist[evt.target.id=${evt.target.id}]`,CG); }//Collapsed
	// Get the <datalist> and <input> elements.
	var dataList = document.getElementById('datalistSearchSchedule');
	let i;
	let j;
	let k;
	var input = document.getElementById('inpSearchSchedule');
	let inputValue = input.value;
	let scId;
	let searchValue = inputValue.toLowerCase();
	if ( DEBUG ) { console.log(`${PC}searchValue=${searchValue}`,CS); }
	if ( searchValue ) { // Is there something to search for?
		// Yes, Search for it.
		//input.value = '';
		// Build course filter. Include only courses that are on the schedule.
		//ScheduleClass[2343] = { scId:2343, Course:"CST1021", courseId:"3267", Section:"41,42" };
		let courseFiler = [];
		for ( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClasses.
			courseFiler.push(ScheduleClass[scId].courseId);
		}} // Loop thru ScheduleClasses.
		if ( DEBUG ) { console.log(`${PC}courseFiler=${courseFiler}`,CI); }
		//input.placeholder = "Loading options..."; // Update the placeholder text.
		// Clear the datalist
		if ( DEBUG ) { console.log(`${PC}dataList.options.length=${dataList.options.length}`,CL); }
		dataList.innerHTML = '<option>Loading options...</option>';
		let dataListOptions = [];
		let optionAdd = false;
		//let searchWords = searchValue.split(' ');
		let searchWords = [searchValue];
		for ( i=0; i<searchWords.length; i++ ) {
			let search = searchWords[i];
			if ( search ) {
				if ( DEBUG ) { console.log(`${PC}Searching for ${search}`,CI); }
				// BEGIN Search thru Courses.
				for ( var courseId in Course ){if(Course.hasOwnProperty(courseId)){ // Loop thru courses.
					let searchOptions = [];
					//if ( DEBUG ) { console.log(`${PC} Course[${cId}]=${JSON.stringify( Course[courseId])}`,CL); }
					if ( courseFiler.indexOf(courseId) !== -1 ) { // Is this course in the filter?
						// Add the course dept number and title.
						let course = Course[courseId];
						let thisOption = course.Dept + course.Number + ' ' + course.Title;
						searchOptions.push(thisOption);
						// Add rooms.
						for ( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClass.
							//if ( DEBUG ) { console.log(`${PC}course.Id=${course.Id}  ScheduleClass[${scId}].courseId=${ ScheduleClass[scId].courseId}`,CL); }
							if ( course.Id == ScheduleClass[scId].courseId ) { // Do the courseIds match?
								for ( j=0; j<SCMnow[scId].length;j++ ) { // Loop thru ClassMeetings
									let classMeeting = SCMnow[scId][j];
									if ( DEBUG ) { console.log(`${PC}classMeeting.rooms.length=${classMeeting.rooms.length}`,CL); }
									if ( classMeeting.rooms.length ) { // Are there rooms.
										for ( k=0; k<classMeeting.rooms.length; k++ ) { // Loop thru rooms.
											let room = classMeeting.rooms[k];
											if ( searchOptions.indexOf(room) == -1 ) { searchOptions.push(`Room ${room}`); }
										} // Loop thru rooms.
									} // Are there rooms.
								} // Loop thru ClassMeetings
							} // Do the courseIds match?
						}} // Loop thru ScheduleClass.
						// Add instructors.
						for ( scId in ScheduleClass ){if(ScheduleClass.hasOwnProperty(scId)){ // Loop thru ScheduleClass.
							//if ( DEBUG ) { console.log(`${PC}course.Id=${course.Id}  ScheduleClass[${scId}].courseId=${ ScheduleClass[scId].courseId}`,CL); }
							if ( course.Id == ScheduleClass[scId].courseId ) { // Do the courseIds match?
								for ( j=0; j<SCMnow[scId].length;j++ ) { // Loop thru ClassMeetings
									let classMeeting = SCMnow[scId][j];
									if ( DEBUG ) { console.log(`${PC}classMeeting.instructors.length=${classMeeting.instructors.length}`,CL); }
									if ( classMeeting.instructors.length ) { // Are there instructors.
										for ( k=0; k<classMeeting.instructors.length; k++ ) { // Loop thru instructors.
											let instructorName = InstructorLookup[classMeeting.instructors[k]].Name;
											if ( searchOptions.indexOf(instructorName) == -1 ) { searchOptions.push(instructorName); }
										} // Loop thru instructors.
									} // Are there instructors.
								} // Loop thru ClassMeetings
							} // Do the courseIds match?
						}} // Loop thru ScheduleClass.
						// Add searchOptions to dataListOptions.
						if ( DEBUG ) { console.log(`${PC}searchOptions=${searchOptions}`,CL); }
						for ( j=0; j<searchOptions.length; j++ ) { // Loop thru searchOptions.
							let searchOption = searchOptions[j];
							if ( searchOption.toLowerCase().indexOf(search) !== -1 ) { // Was search in searchOptions?
								// Yes, add to dataListOptions.
								if ( dataListOptions.indexOf(searchOption) === -1 ) { // Is it not already in dataListOptions?
									optionAdd = searchOption;
									dataListOptions.push(optionAdd);
								} // Is it not already in dataListOptions?
								if ( DEBUG ) { console.log(`${PC}${search} found in ${searchOption.toLowerCase()}.`,CL); }
							} // Was search in searchOptions?
						} // Loop thru searchOptions.
					} // Is this course in the filter?
				}}// Loop thru courses.
				//   END Search thru Courses.
			}
		}
		dataListOptions.sort(); 
		if ( DEBUG ) {
			console.log(`${PC}dataListOptions.length=${dataListOptions.length}`,CL);
			dataListOptions.forEach(option => {
				if ( DEBUG ) { console.log(`${PC}option=${option}`,CI); }
			});
		}
		// Populate datalist with options.
		let dataListItems = [];
		dataListOptions.forEach(function (item) {
			// Create a new <option> element.
			var option = document.createElement('option');
			// Set the value using the item in the JSON array.
			option.value = item;
			dataListItems.push(item);
			// Add the <option> element to the <datalist>.
			dataList.appendChild(option);
		});
		if ( DEBUG ) { console.log(`${PC}dataListItems=${JSON.stringify(dataListItems)}`,CI); }
		if ( dataListItems.length == 1 ) {
			Search_FindMeetings(dataListItems[0]);
		} else {
			Search_UnhighlightMeetings();
		}
	} else { // Is there something to search for?
		// No, clear any highlighted class meetings.
		Search_UnhighlightMeetings();
	} // Is there something to search for?
	if ( DEBUG ) { console.groupEnd(); }
} // END Search_UpdateDatalist.

// Search_UnhighlightMeetings()
// Unhighlight and clear meetings found by search.
function Search_UnhighlightMeetings() {
	var DEBUG = false;
	if ( DEBUG ) { console.groupCollapsed(`${PC}Search_UnhighlightMeetings[]`,CG); }//
	if ( DEBUG ) { console.log(`${PC}Search_FindMeetings.idsToHighlight.length=${Search_FindMeetings.idsToHighlight.length}`,CI); }
	if ( Search_FindMeetings.idsToHighlight.length ) { // Are there idsToHighlight?
		for ( let i=0; i<Search_FindMeetings.idsToHighlight.length; i++ ) { // Loop thru idsToHighlight.
			let thisId = Search_FindMeetings.idsToHighlight[i];
			let eToHighlight = document.getElementById(thisId);
			eToHighlight.style.boxShadow = '';
			eToHighlight.style.zIndex = 1;
			eToHighlight.style.marginRight = '0';
			eToHighlight.style.outline = '';
		} // Loop thru idsToHighlight.
	} // Are there idsToHighlight?
	Search_FindMeetings.idsToHighlight = [];
	if ( DEBUG ) { console.groupEnd(); }
} // END Search_UnhighlightMeetings.

// SortObject(obj)
// Sort an object by key,
function SortObject(obj) {
	return Object.keys(obj).sort().reduce(function (result, key) {
		result[key] = obj[key];
		return result;
	}, {});
} // END SortObject.

// Element_Highlight()
// Hightlight element.
function Element_Highlight(id='', by='') {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.group(`${PC}Element_Highlight[id=${id}] by=${by}`,CG); }//Collapsed
	if ( DEBUG ) { console.log(`${PC}Element_Highlight.idsToHighlight.length=${Element_Highlight.idsToHighlight.length}`,CI); }
	if ( id ) {
		if ( DEBUG ) { console.log(`${PC}Element_Highlight id=${id}`,CS); }
		Element_Highlight.idsToHighlight.push(id);
		let eToHighlight = document.getElementById(id);
		eToHighlight.classList.add('changeInSC');
	}
	if ( DEBUG ) { console.groupEnd(); }
} // END Element_Highlight.
Element_Highlight.idsToHighlight = [];

// Element_Unhighlight()
// Unhighlight all dialog elements.
function Element_Unhighlight() {
	var DEBUG = DEBUG_ON;
	if ( DEBUG ) { console.group(`${PC}Element_Unhighlight[]`,CG); }//Collapsed
	if ( DEBUG ) { console.log(`${PC}Element_Highlight.idsToHighlight.length=${Element_Highlight.idsToHighlight.length} = ${JSON.stringify(Element_Highlight.idsToHighlight)}`,CI); }
	if ( Element_Highlight.idsToHighlight.length ) { // Are there idsToHighlight?
		for ( let i=0; i<Element_Highlight.idsToHighlight.length; i++ ) { // Loop thru idsToHighlight.
			let thisId = Element_Highlight.idsToHighlight[i];
			if ( DEBUG ) { console.log(`${PC}thisId=${thisId}`,CI); }
			let eToHighlight = document.getElementById(thisId);
			eToHighlight.classList.remove('changeInSC');
		} // Loop thru idsToHighlight.
	} // Are there idsToHighlight?
	Element_Highlight.idsToHighlight = [];
	if ( DEBUG ) { console.groupEnd(); }
} // END Element_Unhighlight.

Anon7 - 2022
AnonSec Team