{"id":20801,"date":"2021-12-01T11:45:45","date_gmt":"2021-12-01T17:45:45","guid":{"rendered":"https:\/\/gigisplayhouse.org\/fargo\/?page_id=20801"},"modified":"2025-10-08T16:19:44","modified_gmt":"2025-10-08T21:19:44","slug":"sfcalendar","status":"publish","type":"page","link":"https:\/\/gigisplayhouse.org\/fargo\/sfcalendar\/","title":{"rendered":"SFcalendar"},"content":{"rendered":"\n\n\t<div class=\"fl-builder-content fl-builder-content-129756 fl-builder-template fl-builder-row-template fl-builder-global-templates-locked\" data-post-id=\"129756\"><div class=\"fl-row fl-row-fixed-width fl-row-bg-none fl-node-6059098fdffb2 fl-row-default-height fl-row-align-center\" data-node=\"6059098fdffb2\">\n\t<div class=\"fl-row-content-wrap\">\n\t\t<div class=\"uabb-row-separator uabb-top-row-separator\" >\n<\/div>\n\t\t\t\t\t\t<div class=\"fl-row-content fl-row-fixed-width fl-node-content\">\n\t\t\n<div class=\"fl-col-group fl-node-6138f896796ad\" data-node=\"6138f896796ad\">\n\t\t\t<div id=\"mygigis-login-message\" class=\"fl-col fl-node-6138f896797d9 fl-col-bg-color\" data-node=\"6138f896797d9\">\n\t<div class=\"fl-col-content fl-node-content\"><div class=\"fl-module fl-module-rich-text fl-node-6138f89679606\" data-node=\"6138f89679606\">\n\t<div class=\"fl-module-content fl-node-content\">\n\t\t<div class=\"fl-rich-text\">\n\t<p style=\"text-align: center;\"><a id=\"login_section\" name=\"login_section\"><\/a><span style=\"font-size: 26px;\"><a href=\"{{site_url}}\/mygigisaccount\">Sign in to your MyGiGi's account<\/a><\/span><\/p>\n<p style=\"text-align: center;\"><em>Don't have a MyGiGi's account yet?\u00a0 <a href=\"https:\/\/gigisplayhouse.tfaforms.net\/4719696?playhouseId={{gigiPlayhouseId}}\" target=\"_blank\" rel=\"noopener\">Register for one now!<\/a><\/em><\/p>\n<p style=\"text-align: center;\"><em>Some of our programs welcome drop-ins. Click a program below to find out!<\/em><\/p>\n<p><script>var isLoggedIn=false<\/script><\/p>\n<\/div>\n\t<\/div>\n<\/div>\n<\/div>\n<\/div>\n\t<\/div>\n\n<div class=\"fl-col-group fl-node-6059098fdffab\" data-node=\"6059098fdffab\">\n\t\t\t<div class=\"fl-col fl-node-6059098fdffb0 fl-col-bg-color\" data-node=\"6059098fdffb0\">\n\t<div class=\"fl-col-content fl-node-content\"><div class=\"fl-module fl-module-html fl-node-6059098fdffb1\" data-node=\"6059098fdffb1\">\n\t<div class=\"fl-module-content fl-node-content\">\n\t\t<div class=\"fl-html\">\n\t<!--<link href='fullcalendar\/core\/main.css' rel='stylesheet' \/>\n<link href='fullcalendar\/daygrid\/main.css' rel='stylesheet' \/>-->\n\n<link rel='stylesheet' id='sforc_calendar-css'  href='https:\/\/gigisplayhouse.org\/wp-content\/plugins\/sawfishconnect\/css\/calendar.css?ver=5.4.2' media='all' \/>\n<link rel='stylesheet' id='bootstrap-4.6-css' href=\"https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@4.6.0\/dist\/css\/bootstrap.min.css\" \/>\n<style>\nbody {\n    font-size: 16px;\n}\n@media print {\n    #mygigis-login-message, #agesServedFilterLegend {\n        display: none;\n    }\n    header {\n        display: none;\n    }\n    #calendar {\n        page-break-inside: avoid;\n    }\n}\n.fc-icon-chevron-left:before {\n\tcontent: \"<\";\n}\n.fc-icon-chevron-right:before {\n\tcontent: \">\";\n}\n.filterLegend {\n\twidth: 100%;\n}\n.filterLegend div {\n\tdisplay: inline-block;\n\tmargin:2px;\n}\n.filterLegend label {\n\tpadding: 2px;\n\tmargin:5px;\n\tborder-radius: 5px;\n\tborder: 1px solid gray;\n\tfont-weight: normal;\n}\n.legendLabel {\n\tfont-weight: bold;\n}\n.legend.Available_Virtually, .legend.Available_In_Person {\n\tbackground-color: white;\n}\n.legend.Available_Virtually img, .legend.Available_In_Person img {\n\tbackground-color: gray;\n\tmargin-left: 5px;\n\tpadding: 5px;\n\tborder-radius: 4px;\n\twidth: 30px;\n}\nimg.Available_Virtually, img.Available_In_Person {\n\tpadding-left: 5px;\n\twidth: 20px;\n}\n.popupEventTitle, .popupLabel {\n\tfont-weight: bold;\n}\n.popupEventDropInMessage {\n}\n.popupField-Description {\n\tmax-height: 300px;\n\toverflow: auto;\n\twhite-space: pre-line;\n\ttext-overflow: ellipsis;\n}\n.fc-day-grid-event .fc-content {\n    white-space: normal;\n    overflow: visible;\n\tpadding: 2px;\n}\n\/*primary locations*\/\n.fc-content, .fc-list-item, #locationFilterLegend label {\n\t\t\tbackground-color:#488ccb;\n\t\tcolor: white;\n}\n.fc-list-item:hover, .Virtual_Playhouse.fc-list-item:hover, .GiGis_at_Home_-_Virtual.fc-list-item:hover{\n\tbackground-color: blue;\n\tcolor: black;\n}\n\t\/*secondary locations*\/\n.Chapel_Hill>.fc-content, .Chapel_Hill.fc-list-item, #locationFilterLegend .Chapel_Hill, .Brooklyn>.fc-content, .Brooklyn.fc-list.item, #locationFilterLegend .Brooklyn, .Hudson>.fc-content, .Hudson.fc-list-item, #locationFilterLegend .Hudson, .Midtown>.fc-content, .Midtown.fc-list-item, #locationFilterLegend .Midtown, .Marshalltown>.fc-content, .Marshalltown.fc-list-item, #locationFilterLegend .Marshalltown, .Gallatin>.fc-content, .Gallatin.fc-list-item, #locationFilterLegend .Gallatin, .Peoria>.fc-content, .Peoria.fc-list-item, #locationFilterLegend .Peoria {\n\tbackground-color: #7ac143;\n\tcolor: white;\n}\n\/*other locations*\/\n.South_Metro>.fc-content, .South_Metro.fc-list-item, #locationFilterLegend .South_Metro, .Main_Playhouse_Demo>.fc-content, .Main_Playhouse_Demo.fc-list-item, #locationFilterLegend .Main_Playhouse_Demo, .Pella>.fc-content, .Pella.fc-content, #locationFilterLegend .Pella, .Clarksville>.fc-content, .Clarksville.fc-list-item, #locationFilterLegend .Clarksville, .Wake_Forest>.fc-content, .Wake_Forest.fc-list-item, #locationFilterLegend .Wake_Forest {\n\tbackground-color: #00a89d;\n\tcolor: white;\n}\n\/*fourth location*\/\n.Clayton>.fc-content, .Clayton.fc-list-item, #locationFilterLegend .Clayton {\n    background-color: #d785b8;\n    color: white;\n}\n\/*fifth location*\/\n.Fayetteville>.fc-content, .Fayetteville.fc-list-item, #locationFilterLegend .Fayetteville {\n    background-color: #ed1c24;\n    color: white;\n}\n\n.Virtual_Playhouse>.fc-content, .Virtual_Playhouse.fc-list-item, #locationFilterLegend .Virtual_Playhouse, .GiGis_at_Home_-_Virtual>.fc-content, .GiGis_at_Home_-_Virtual.fc-list-item, #locationFilterLegend .GiGis_at_Home_-_Virtual {\n\tbackground-color:#f58220;\n\tcolor: white;\n}\n#calendar button {\n\twidth: auto;\n\tbackground-color: lightgray;\n\tcolor: black;\n}\n.fade-scale {\n  transform: scale(0.75);\n  opacity: 0;\n  -webkit-transition: all .25s linear;\n  -o-transition: all .25s linear;\n  transition: all .25s linear;\n}\n\n.fade-scale.show {\n  opacity: 1;\n  transform: scale(1);\n}\n.fade-scale.in {\n  opacity: 1;\n  transform: scale(1);\n}\nbutton.close {\n\twidth: auto;\n}\n.fc-toolbar.fc-header-toolbar {\n\toverflow: hidden;\n}\n.sflink, .sflink a {\n\tposition: fixed;\n\tbottom: 80px;\n\tright: 0;\n\twidth: 75px;\n\theight: 1em;\n\tcolor: #656565;\n}\n.bold-error {\n\tfont-weight: bold;\n\tcolor: #ff0000;\n}\n#status {\n      position: fixed;\n      top: 50%;\n      left: 50%;\n      margin-right: -50%;\n      transform: translate(-50%, -50%);\n      height: 100px;\n      width: 100px;\n}\n<\/style>\n\n<!--<script data-require=\"jquery@*\" data-semver=\"3.1.1\" src=\"https:\/\/ajax.googleapis.com\/ajax\/libs\/jquery\/3.1.1\/jquery.min.js\"><\/script>\n<script src=\"https:\/\/stackpath.bootstrapcdn.com\/bootstrap\/3.4.1\/js\/bootstrap.min.js\" integrity=\"sha384-aJ21OjlMXNL5UyIl\/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd\" crossorigin=\"anonymous\"><\/script>-->\n<script data-require=\"moment.js@*\" data-semver=\"2.14.1\" src=\"https:\/\/cdn.jsdelivr.net\/npm\/moment@2.14.1\/min\/moment.min.js\"><\/script>\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@4.6.0\/dist\/js\/bootstrap.bundle.min.js\" integrity=\"sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns\" crossorigin=\"anonymous\"><\/script>\n<!--<script type=\"text\/javascript\">\nvar jQuery3 = $.noConflict(true);\n<\/script>-->\n<script src='https:\/\/cdn.jsdelivr.net\/npm\/@fullcalendar\/core@4.4.2\/main.js'><\/script>\n<script src='https:\/\/cdn.jsdelivr.net\/npm\/@fullcalendar\/daygrid@4.4.2\/main.js'><\/script>\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/@fullcalendar\/list@4.4.2\/main.min.js\"><\/script>\n<!--<script src=\"https:\/\/stackpath.bootstrapcdn.com\/bootstrap\/3.4.1\/js\/bootstrap.min.js\" integrity=\"sha384-aJ21OjlMXNL5UyIl\/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd\" crossorigin=\"anonymous\"><\/script>-->\n\n   <script>\nvar rawAccount = []   \n\/\/ *******  Everything below this point should come from CodePen. https:\/\/codepen.io\/totremba-gigisplayhouse\/pen\/NWbrQaR?editors=1111 ************\n\n\nvar account = rawAccount[0];\nvar sfEvents = rawEvents;\nvar ppvj = rawPPVJ;\n\/\/ check style of JSON generated by the Sawfish plugin.  Versions prior to 1.5 used an array within an array. Newer versions use an array of objects.\nif (rawEvents.length > 0 && rawEvents[0].length > 0) {\n\taccount = rawAccount.map(convertSawfishToObject)[0];\n\tsfEvents = rawEvents.map(convertSawfishToObject);\n\tvar ppvj = rawPPVJ.map(convertSawfishToObject);\n}\n\nfunction convertSawfishToObject(item) {\n    var eventObject = new Object();\n    \/\/console.debug(item.length);\n    for (var i=0; i<item.length; i++) {\n      var key = Object.keys(item[i])[0];\n\t\t\teventObject[key]=item[i][key];\n\t\t\t\/\/console.debug(key + \":\" + eventObject[key]);\n    }\n    return eventObject;\n  }\n\nfunction getPPVJ(ppvjId) {\n\t\tlet retVal = null;\n\t\tif (typeof ppvjId !== \"undefined\" && ppvjId != null) {\n\t\t\tretVal = ppvj.find(x => x.Id === ppvjId);\n\t\t}\n    return retVal;\n  }\nfunction getPPVJValue(ppvjId, property) {\n\tlet singlePPVJ = getPPVJ(ppvjId);\n\tlet retVal = null;\n\tif (singlePPVJ != null) {\n\t\tretVal = singlePPVJ[property];\n\t}\n\treturn retVal;\n}\nfunction getEvent(eventId) {\n\t\tlet retVal = null;\n\t\tif (typeof eventId !== \"undefined\" && eventId != null) {\n\t\t\tretVal = sfEvents.find(x => x.Id === eventId);\n\t\t}\n    return retVal;\n  }\nfunction getEventValue(eventId, property) {\n\tlet singleEvent = getEvent(eventId);\n\tlet retVal = null;\n\tif (singleEvent != null) {\n\t\tretVal = singleEvent[property];\n\t}\n\treturn retVal;\n}\nfunction setEventValue(eventId, property, value) {\n\tlet singleEvent = getEvent(eventId);\n\tlet retVal = null;\n\tif (singleEvent != null) {\n\t\tsingleEvent[property]=value;\n\t}\n}\nfunction escapeQuotes(initialValue) {\n\tif (initialValue != null) {\n\t\treturn (\"\"+initialValue).replace(\/'\/g, \"\\\\'\");\n\t}else {\n\t\treturn initialValue;\n\t}\n}\n\/\/ loop through registrations and augment the data on the events for items that you've already registered for\nif (typeof rawRegistrations !== \"undefined\" && rawRegistrations != null && rawRegistrations.length > 0) {\n\tfor (var i=0; i<rawRegistrations.length; i++) {\n\t\tlet foundEvent = false;\n\t\tlet singleRegistration = rawRegistrations[i];\n\t\tlet shiftId = singleRegistration.GW_Volunteers__Volunteer_Shift__c;\n\t\tif (shiftId != null) {\n\t\t\tif (getEventValue(shiftId, \"Id\") != null) {\n\t\t\t\tfoundEvent=true;\n\t\t\t}\n\t\t\tlet existingRegistrations = getEventValue(shiftId, \"registeredUsers\");\n\t\t\tif (existingRegistrations != null) {\n\t\t\t\texistingRegistrations += \", \" + singleRegistration.Contact_Full_Name__c;\n\t\t\t}else {\n\t\t\t\texistingRegistrations = singleRegistration.Contact_Full_Name__c;\n\t\t\t}\n\t\t\tsetEventValue(shiftId, \"registeredUsers\", existingRegistrations);\n\n\t\t}\n\t\tif (!foundEvent) {\n\t\t\t\/\/ add it to the list of events for the calendar\n\t\t\tlet singleEvent = {\"Id\": singleRegistration.GW_Volunteers__Volunteer_Shift__c,\n\t\t\t\t\t\t\t\t\"Shift_Title__c\":singleRegistration.Shift_Title__c, \n\t\t\t\t\t\t\t\t\"Prog_Vol_Job_Name__c\":singleRegistration.Volunteer_Job_Name__c,\n\t\t\t\t\t\t\t\t\"GW_Volunteers__Start_Date_Time__c\":singleRegistration.GW_Volunteers__Shift_Start_Date_Time__c,\n\t\t\t\t\t\t\t\t\"GW_Volunteers__Duration__c\":singleRegistration.Shift_Duration__c,\n\t\t\t\t\t\t\t\t\"Program_Ages_Served__c\":\"All Ages\", \/*not fully correct*\/\n\t\t\t\t\t\t\t\t\"Available_Virtually__c\":singleRegistration[\"GW_Volunteers__Volunteer_Shift__r.Available_Virtually__c\"],\n\t\t\t\t\t\t\t\t\"Available_In_Person__c\":singleRegistration[\"GW_Volunteers__Volunteer_Shift__r.Available_In_Person__c\"],\n\t\t\t\t\t\t\t\t\"Playhouse_Location_Name__c\":singleRegistration.Playhouse_Location_Name__c,\n\t\t\t\t\t\t\t\t\"Website_Event_Detail_Link__c\":null \/*not fully correct*\/,\n\t\t\t\t\t\t\t\t\"GW_Volunteers__Description__c\":null \/*not fully correct*\/,\n\t\t\t\t\t\t\t\t\"Description_Formatted__c\":null \/*not fully correct*\/,\n\t\t\t\t\t\t\t\t\"Playhouse_Prog_Vol_Job__c\":singleRegistration[\"GW_Volunteers__Volunteer_Shift__r.Playhouse_Prog_Vol_Job__c\"],\n\t\t\t\t\t\t\t\t\"Allow_RSVP__c\":false,\n\t\t\t\t\t\t\t\t\"Allow_Waitlist__c\":false,\n\t\t\t\t\t\t\t\t\"RSVP_Open_Date__c\":null,\n\t\t\t\t\t\t\t\t\"RSVP_Deadline__c\":null,\n\t\t\t\t\t\t\t\t\"Webinar_link__c\":singleRegistration.Webinar_link__c,\n\t\t\t\t\t\t\t\t\"registeredUsers\": singleRegistration.Contact_Full_Name__c};\n\t\t\tsfEvents.push(singleEvent);\n\t\t}\n\t}\n}\n\n\n\/\/initialize the calendar\n\t\tvar tabIndexCounter = 1;\n\t\tvar calendar;\n\t\tjQuery(document).ready(function() {\n\t\t\t\/\/createEventFilters([{label:\"Location\",eventAttribute:\"location\"},{label:\"Ages Served\", eventAttribute:\"agesServed\"}]);\n\t\t\treinitializeCalendar();\n\t\t\tjQuery('#eventDetailsModal').on('hidden.bs.modal', eventDetailsHidden);\n\t\t});\n\n\t\tfunction stripSpecialChars(value) {\n\t\t\tvar className = \"\";\n\t\t\tif (typeof value !== \"undefined\" && value != null) {\n\t\t\t\t\/\/ The following line is just fine javascript, but beaver builder doesn't seem to like it in their page builder interface\n\t\t\t\t\/\/className = value.replace(\/ \/g,\"_\").replace(\/\\(\/g,\"\").replace(\/\\)\/g,\"\");\n        \/\/console.debug(\"stripSpecialChars:\" + value);\n\t\t\t\tclassName = (\"\" + value).split(\" \").join(\"_\").split(\"(\").join(\"\").split(\")\").join(\"\").split(\"'\").join(\"\").split(\".\").join(\"\");\n\t\t\t}\n\t\t\treturn className;\n\t\t}\n\t\tfunction isEmpty(value) {\n\t\t\treturn (typeof value === \"undefined\" || value == null || (\"\" + value).length == 0);\n\t\t}\n\t\tfunction getConditionalCssClass(isTrue, classNameRoot) {\n\t\t    var className = \"\";\n\t\t    if (isTrue) {\n\t\t        className = classNameRoot + \"_Active\";\n\t\t    }else {\n\t\t        className = classNameRoot + \"_InActive\";\n\t\t    }\n\t\t    return className;\n\t\t}\n\t\tfunction createVirtualImage() {\n\t\t\tlet image = document.createElement('img');\n                    \/\/image.src = \"https:\/\/gigisplayhouse.org\/wp-content\/uploads\/2021\/05\/wireless-white.png\";\n\t\t\t\t\t\t\t\t\t\timage.src = \"https:\/\/gigisplayhouse.org\/form-images\/gigis%20virtual%20calendar%20icon.png\";\n\t\t\t\t\t\t\t\t\t\timage.classList.add(\"Available_Virtually\");\n\t\t\t\t\t\t\t\t\t\t\/\/image.style.width = \"30px\";\n                    \/\/image.style.height = \"15px\";\n                    \/\/image.style.paddingLeft = \"5px\";\n                    image.alt = \"Available Virtually\";\n                    image.title = \"Available Virtually\";\n\t\t\treturn image;\n\t\t}\n\t\tfunction createInPersonImage() {\n\t\t\tlet image = document.createElement('img');\n\t\t\timage.src = \"https:\/\/gigisplayhouse.org\/wp-content\/uploads\/2021\/05\/person_icon.png\";\n\t\t\timage.classList.add(\"Available_In_Person\");  \n\t\t\t\/\/image.style.width = \"30px\";\n\t\t\t\/\/image.height = \"15\";\n\t\t\t\/\/image.style.paddingLeft = \"5px\";\n\t\t\timage.alt = \"Available In Person\";\n\t\t\timage.title = \"Available In Person\";\n\t\t\treturn image;\n\t\t}\n\t\tfunction shouldRenderEventBasedOnFilter(optionListId, eventValue, currentlyVisible) {\n\t\t\tvar isMatch = currentlyVisible;\n\t\t\t\/\/ only check this filter if the item is currently visible\n\t\t\tif (isMatch) {\n\t\t\t\t\/\/ This is the way to do it with option lists\n\t\t\t\t\/*\n\t\t\t\tisMatch = jQuery(\"#\" + optionListId + \" option[value='\" + escapeQuotes(eventValue) + \"']:selected\").length == 1;\n\t\t\t\tif (!isMatch) {\n\t\t\t\t\tisMatch = jQuery(\"#\" + optionListId + \" option[value='']:selected\").length == 1;\n\t\t\t\t}*\/\n\t\t\t\tvar checkboxId = optionListId + '_' + stripSpecialChars(eventValue);\n\t\t\t\tisMatch = Boolean(jQuery(\"#\" + checkboxId).prop('checked'));\n\t\t\t\tif (eventValue == null) {\n\t\t\t\t\t\/\/ check to see if all of the checkboxes are checked in this group and render it if they are\n\t\t\t\t\tvar checkboxes = document.getElementsByName(optionListId);  \n\t\t\t\t\tvar numberOfCheckedItems = 0;  \n\t\t\t\t\tfor(var i = 0; i < checkboxes.length; i++) {  \n\t\t\t\t\t\t\tif(checkboxes[i].checked)  \n\t\t\t\t\t\t\t\t\tnumberOfCheckedItems++;  \n\t\t\t\t\t}  \n\t\t\t\t\tif(numberOfCheckedItems == checkboxes.length)  {\n\t\t\t\t\t\t\/\/ all are checked\n\t\t\t\t\t\tisMatch = true;\n\t\t\t\t\t}  \n\t\t\t\t}\n\t\t\t}\n\t\t\treturn isMatch;\n\t\t}\n\t\tfunction shouldRenderEventBasedOnAvailability(eventAvailableVirtually, eventAvailableInPerson, currentlyVisible) {\n\t\t\tvar isMatch = currentlyVisible;\n\t\t\t\/\/ only check this filter if the item is currently visible\n\t\t\tif (isMatch) {\n\t\t\t\tvar virtualCheckboxId = \"availabilityFilter\" + '_' + stripSpecialChars(\"Available Virtually\");\n\t\t\t\tvar isVirtualChecked = true;\n\t\t\t\t\/\/ only hide things if Available Virtually is an option\n\t\t\t\tif (jQuery(\"#\" + virtualCheckboxId).length > 0) {\n\t\t\t\t\tisVirtualChecked = Boolean(jQuery(\"#\" + virtualCheckboxId).prop('checked'));\n\t\t\t\t}\n\t\t\t\tvar inPersonCheckboxId = \"availabilityFilter\" + '_' + stripSpecialChars(\"Available In Person\");\n\t\t\t\tvar isInPersonChecked = true;\n\t\t\t\tif (jQuery(\"#\" + inPersonCheckboxId).length > 0) {\n\t\t\t\t\tisInPersonChecked = Boolean(jQuery(\"#\" + inPersonCheckboxId).prop('checked'));\n\t\t\t\t}\n\t\t\t\tif ((isVirtualChecked && eventAvailableVirtually) || (isInPersonChecked && eventAvailableInPerson) || (isVirtualChecked && isInPersonChecked)) {\n\t\t\t\t\tisMatch = true;\n\t\t\t\t}else {\n\t\t\t\t\tisMatch = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn isMatch;\n\t\t}\n\t\tfunction addUniqueValueToFilter(optionListId, optionLabel, optionValue) {\n\t\t\tvar optionValueMissing =false;\n\t\t\t\/\/var optionValueMissing = jQuery(\"#\"+optionListId + \" option[value='\" + escapeQuotes(optionValue) + \"']\").length == 0;\n\t\t\tlet checkboxId = optionListId+'_'+stripSpecialChars(optionValue);\n\t\t\tvar optionCheckbox = jQuery(\"#\"+checkboxId);\n\t\t\tvar optionCheckboxMissing = optionCheckbox.length === 0;\n\t\t\tif (optionValue && optionValue !='' && (optionValueMissing || optionCheckboxMissing))\n\t\t\t\t\t  {\n\t\t\t\t\t\t\/\/jQuery(\"#\" + optionListId).append(new Option(optionLabel, optionValue));\n\t\t\t\t\t\tlet storageKey = stripSpecialChars(optionValue);\n\t\t\t\t\t\t\/\/ now add it to the legend\n\t\t\t\t\t\tjQuery(\"#\" + optionListId + \"Legend\").append('<div><input type=\"checkbox\" name=\"' + optionListId + '\" id=\"'+ checkboxId + '\" value=\"' + escapeQuotes(optionValue) + '\" ' + (optionValue==\"All Ages\" || localStorage.getItem(storageKey)==null || localStorage.getItem(storageKey)=='true'?'checked':'') + (optionValue==\"All Ages\"?' disabled':'') + ' \/><label class=\"' + stripSpecialChars(optionValue) + ' legend\" for=\"' + optionListId+'_'+stripSpecialChars(optionValue) + '\"\">' + optionLabel + '<\/label><\/div>');\n\t\t\t\t\t\t\/\/add onclick event handler\n\t\t\t\t\t\tjQuery(\"#\" + optionListId+'_'+stripSpecialChars(optionValue)).on(\"click\", function (){\n\t\t\t\t\t\t\tlocalStorage.setItem(storageKey, jQuery(this).prop('checked'));\n\t\t\t\t\t\t\t\/\/ chrome has a bug and it only gets stored if you read it again.\n\t\t\t\t\t\t\tconst filterTemp = localStorage.getItem(storageKey);\n\t\t\t\t\t\t\tconsole.debug(\"Rerender Events \" + optionValue + ' storage ' + storageKey + \"=\" + filterTemp);\n\t\t\t\t\t\tcalendar.rerenderEvents()});\n\t\t\t};\n\t\t}\n\t\tfunction conditionalPopupContent(label, value, optionalValue2, optionalValue3) {\n\t\t    var content = \"\";\n\t\t\t\/\/see if any of the values have a value and add the label\n\t\t\tif (!isEmpty(value) || !isEmpty(optionalValue2) || !isEmpty(optionalValue3)){\n\t\t\t    content = '<div class=\"popupField-' + label + '\">';\n\t\t\t\t\tcontent = content + '<span class=\"popupLabel\">' + label + ':<\/span> ';\n\t\t\t}\n\t\t\t\/\/ see if the first value has a value\n\t\t\tif (!isEmpty(value)) {\n\t\t\t\tcontent = content + value + \"<br \/>\";\n\t\t\t}\n\t\t\tif (!isEmpty(optionalValue2)) {\n\t\t\t\tcontent = content + optionalValue2 + \"<br \/>\";\n\t\t\t}\n\t\t\tif (!isEmpty(optionalValue3)) {\n\t\t\t\tcontent = content + optionalValue3 + \"<br \/>\";\n\t\t\t}\n\t\t\t\/\/ limit the length to the first 220 characters\n\t\t\tif (content.length >0) {\n\t\t\t\tcontent = content + \"<\/div>\"\n\t\t\t\t\/\/content = content.substring(0, 220) + \"... <br \/>\"\n\t\t\t}\n\t\t\treturn content;\n\t\t}\n\t\tfunction isRSVPOpen(sfEvent) {\n\t\t\tvar isOpen = false;\n\t\t\tif (sfEvent.extendedProps.allowRSVP\n\t\t\t\t\t&& (sfEvent.extendedProps.rsvpDeadline == null || moment(sfEvent.extendedProps.rsvpDeadline) > new Date())\n\t\t\t\t\t&& (sfEvent.extendedProps.rsvpOpenDate == null || moment(sfEvent.extendedProps.rsvpOpenDate) < new Date())\n\t\t\t\t  && sfEvent.start > new Date()) {\n\t\t\t\tvar slotsRemaining = getRemainingSlots(sfEvent);\n\t\t\t\tif (slotsRemaining > 0 || slotsRemaining == null || sfEvent.extendedProps.allowWaitlist) {\n\t\t\t\t\tisOpen = true;\n\t\t\t\t}\n\t\t\t}else {\n\t\t\t\tisOpen = false;\n\t\t\t}\n\t\t\treturn isOpen;\n\t\t}\n\t\tfunction getRemainingSlots(sfEvent) {\n\t\t\tvar slotsRemaining = parseInt(sfEvent.extendedProps.desiredNumberOfVolunteers);\n\t\t\tif (!isNaN(slotsRemaining)) {\n\t\t\t\tvar totalVolunteers = parseInt(sfEvent.extendedProps.totalNumberOfVolunteers);\n\t\t\t\tif (!isNaN(totalVolunteers)){\n\t\t\t\t\tslotsRemaining = slotsRemaining - totalVolunteers;\n\t\t\t\t}\n\t\t\t}else {\n\t\t\t\tslotsRemaining = null;\n\t\t\t}\n\t\t\treturn slotsRemaining;\n\t\t}\n\t\tfunction goToLoginSection() {\n\t\t\tjQuery('#eventDetailsModal').modal('hide');\n\t\t\twindow.scroll({\n\t\t\t\ttop: 0, \n\t\t\t\tleft: 0, \n\t\t\t\tbehavior: 'smooth'\n\t\t\t});\n\t\t\tsessionStorage.setItem('gigi_redirectOnLogin', window.location.href);\n\t\t\treturn false;\n\t\t}\n\t\tfunction generatePopoverContent(eventInfo) {\n\t\t\t\/\/ see if the RSVP is allowed and still open\n\t\t\tif (isRSVPOpen(eventInfo)) {\n\t\t\t\tconsole.debug(\"RSVP allowed for:\" + eventInfo.title + \" on \" + eventInfo.start);\n\t\t\t}\n\t\t\tvar slotsRemainingText = \"\";\n\t\t\tvar slotsRemaining = getRemainingSlots(eventInfo);\n\t\t\tif (slotsRemaining > 0 && slotsRemaining != null && eventInfo.start > new Date()) {\n\t\t\t\tslotsRemainingText = '<div>' + slotsRemaining + ' slot' + (slotsRemaining==1?'':'s') + ' remaining<\/div>';\n\t\t\t}\n\t\t\t\/\/var content = '<span class=\"popupEventTitle\">'+eventInfo.title+'<\/span><br \/>';\n\t\t\tvar content = '';\n\t\t\t\n\t\t\tcontent = content + '<span class=\"popupLabel\">Time:<\/span>';\n\t\t\tif (eventInfo.allDay) {\n\t\t\t\tcontent = content + ' ' + eventInfo.start.toLocaleString([], { year: 'numeric', month: 'numeric', day: 'numeric'}) + '<br \/>';\n\t\t\t}else {\n\t\t\t\tcontent = content + ' ' + eventInfo.start.toLocaleString([], { year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: '2-digit' });\n\t\t\t\tif (eventInfo.extendedProps.duration < 1) {\n\t\t\t\t\tcontent = content + ' (' + (eventInfo.extendedProps.duration*60) + ' minutes)<br \/>';\n\t\t\t\t}else {\n\t\t\t\t\tcontent = content + ' (' + eventInfo.extendedProps.duration + ' hours)<br \/>';\n\t\t\t\t}\n\t\t\t}\n\t\t\tconsole.debug(\"PPVJ:\" + eventInfo.extendedProps.ppvj);\n\t\t\tcontent = content + conditionalPopupContent(\"Playhouse\", eventInfo.extendedProps.location);\n\t\t\tcontent = content + conditionalPopupContent(\"Ages\", eventInfo.extendedProps.agesServed);\n\t\t\tcontent = content + conditionalPopupContent(\"Description\",\n\t\t\t\teventInfo.extendedProps.description,\n\t\t\t\tgetPPVJValue(eventInfo.extendedProps.ppvj, \"Global_Description__c\"),\n\t\t\t\tgetPPVJValue(eventInfo.extendedProps.ppvj, \"Location_Program_Description__c\"),);\n\t\t\t\/\/ for some reason the info.event.url object has strings instead of the actual null value\n\t\t\tif (eventInfo.url != null && eventInfo.url != \"null\" && eventInfo.url.length > 0 && eventInfo.url.indexOf(\"?eventId=\")!=0) {\n\t\t\t    content = content + '<div><a tabindex=\"' + tabIndexCounter++ +'\" href=\"' + eventInfo.url + '\">More details<\/a><\/div>';\n\t\t\t}\n\t\t\t\/\/content += JSON.stringify(eventInfo.extendedProps);\n\t\t\tif (eventInfo.extendedProps.registeredUsers != null && eventInfo.extendedProps.webinarLink != null && eventInfo.start > new Date(new Date().getTime() - 1000*60*60)) {\n\t\t\t\tconsole.debug(\"start compare:\" + (eventInfo.start < new Date(new Date().getTime() + 1000*60*5)) + \" eventInfo.start:\" + eventInfo.start + \" newDate: \" + new Date(new Date().getTime() + 1000*60*5));\n        if (eventInfo.start < new Date(new Date().getTime() + 1000*60*5)) {\n            content = content + ' <a class=\"gigi-event-join-link\" href=\"' + eventInfo.extendedProps.webinarLink + '\" target=\"_blank\" onclick=\"gigiJoinMeetingHandler(this)\">Join Meeting<\/a>';\n        } else {\n            content = content + ' The link to join will appear 5 minutes before the meeting starts';\n        }\n\t\t\t}else {\n\t\t\t\tif (isRSVPOpen(eventInfo)) {\n\t\t\t\t\tcontent = content + slotsRemainingText;\n\t\t\t\t\tif (!isLoggedIn) {\n\t\t\t\t\t\tcontent = content + ' <a href=\"#login_section\" onclick=\"return goToLoginSection()\">Please log in to register<\/a>';\n\t\t\t\t\t\tif (eventInfo.extendedProps.allowGuestRegistration) {\n\t\t\t\t\t\t\tcontent = content + \" or <a target=\\\"_blank\\\" href=\\\"https:\/\/gigisplayhouse.my.site.com\/mygigis\/guest-rsvp?\" + \n\t\t\t\t\t\t\t'shiftId=' +\teventInfo.extendedProps.shiftId + \"&referringPlayhouse={{gigiPlayhouseId}}\\\">register as a guest<\/a>\";\n\t\t\t\t\t\t}\n\t\t\t\t\t}else if (isEmpty(account)) {\n\t\t\t\t\t\tcontent = content + '<div class=\"bold-error\">There is a problem with your My GiGi\\'s Account setup. Please contact your local playhouse with the following error message: We are unable to recognize your My GiGi\\'s Account. <a href=\"https:\/\/gigisplayhouse.org\/wp-login.php \"> <\/a><\/div>';\n\t\t\t\t\t}else {\n\t\t\t\t\t\t\tcontent = content + \" <a href=\\\"https:\/\/gigisplayhouse.my.salesforce-sites.com\/stafftraining\/GIGI_Portal_RSVP?\" + \n\t\t\t\t\t\t\t'shiftId=' +\teventInfo.extendedProps.shiftId +\n\t\t\t\t\t\t\t'&accountId=' + (account.AccountId?account.AccountId:account.Id) +\n\t\t\t\t\t\t\t\"&accountName=\" +\t(encodeURIComponent(account.Account_Household_Name__c?account.Account_Household_Name__c:account.Name)) +\n\t\t\t\t\t\t\t\"\\\" target=\\\"_blank\\\">\" + (eventInfo.extendedProps.allowWaitlist && slotsRemaining<=0 && slotsRemaining!=null?\"Add name to waitlist\":\"Register\") + '<\/a>';\n\t\t\t\t\t}\n\t\t\t\t\tif (eventInfo.extendedProps.allowDropIn) {\n\t\t\t\t\t\t\tcontent = content + \" <div class='popupEventDropInMessage'>Drop ins also welcome<\/div>\";\n\t\t\t\t\t}\n\t\t\t\t}else {\n\t\t\t\t\tif (eventInfo.extendedProps.allowRSVP && eventInfo.start > new Date()) {\n\t\t\t\t\t\tif (eventInfo.extendedProps.rsvpDeadline != null &&\n\t\t\t\t\t\t\t\t\t\tmoment(eventInfo.extendedProps.rsvpDeadline) < new Date()) {\n\t\t\t\t\t\t\tcontent = content + ' - Registration Closed';\n\t\t\t\t\t\t}else if (slotsRemaining<=0 || slotsRemaining==null) {\n\t\t\t\t\t\t\tcontent = content + ' Registration full';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn content;\n\t\t}\n\t\tfunction showEventDetails(eventInfo) {\n\t\t\t\t\tconst url = new URL(window.location);\n\t\t\t\t\turl.searchParams.set('eventId', eventInfo.id);\n\t\t\t\t\twindow.history.replaceState({}, '', url);\n\t\t\t\t\tjQuery('#eventDetailsModalTitle').html(eventInfo.title);\n\t\t\t\t\tjQuery('#eventDetailsModalBody').html(generatePopoverContent(eventInfo));\n\t\t\t\t\tjQuery('#eventDetailsSFLink').html(\"<a href=\\\"https:\/\/gigisplayhouse.lightning.force.com\/\" + eventInfo.id + \"\\\" target=\\\"_blank\\\">Manage<\/a>\");\n\t\t\t\t\tjQuery('#eventDetailsModal').modal();\n\t\t}\n\t\tfunction eventDetailsHidden(e) {\n\t\t    var url = new URL(window.location);\n\t\t\tconsole.log(\"before close event url=\" + url.href);\n\t\t\turl.searchParams.delete('eventId');\n\t\t\tconsole.log(\"New url=\" + url.href);\n\t\t\twindow.history.replaceState({}, '', url.href);\n\t\t}\n\t\tvar scrollToNow = function () {\n\t\t\tconsole.debug('Starting to scroll');\n\t\t\tvar cellDateData = moment().format(\"YYYY-MM-DD\");\n\t\t\tvar maxAttempts = 7;\n\t\t\tvar cell = document.getElementById('calendar').querySelector('td[data-date^=\"' + cellDateData + '\"]');\n\t\t\tif (!cell) {\n\t\t\t\tconsole.debug('Month view date cell not found:' + cellDateData);\n\t\t\t\tfor (var i = 0; !cell && i<maxAttempts; i++) {\n\t\t\t\t\t\/\/ try the list format for small screens multiple times since it doesn't show dates without events\n\t\t\t\t\tcellDateData = moment().subtract(i, 'days').format(\"YYYY-MM-DD\");\n\t\t\t\t\tcell = document.getElementById('calendar').querySelector('tr[data-date^=\"' + cellDateData + '\"]');\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (cell) {\n\t\t\t\tcell.scrollIntoView({ behavior: 'smooth', block: 'center'});\n\t\t\t}else {\n\t\t\t\tconsole.debug('Date cell not found as far back as:' + cellDateData + ' after ' + maxAttempts + ' attempts');\n\t\t\t}\n\t\t}\n\tfunction gigiTransformEvent(myEvents, e) {\n\t\t\t\t\t\n\t\t\t\t\t\t\tvar calculatedEnd = new Date(moment(e.GW_Volunteers__Start_Date_Time__c).add(e.GW_Volunteers__Duration__c, 'hours'));\n\t\t\t\t\t\t\tmyEvents.push({\n\t\t\t\t\t\t\t  id: e.Id,\n\t\t\t\t\t\t\t\tstart: e.GW_Volunteers__Start_Date_Time__c,\n\t\t\t\t\t\t\t  end: calculatedEnd,\n\t\t\t\t\t\t\t  duration: e.GW_Volunteers__Duration__c,\n\t\t\t\t\t\t\t\tallDay: (e.GW_Volunteers__Duration__c >= 24? true: false),\n\t\t\t\t\t\t\t  title: e.Shift_Title__c,\n\t\t\t\t\t\t\t  url: (e.Website_Event_Detail_Link__c == null? '?eventId='+e.Id: e.Website_Event_Detail_Link__c),\n\t\t\t\t\t\t\t  description: (isEmpty(e.Description_Formatted__c)?e.GW_Volunteers__Description__c: e.Description_Formatted__c),\n\t\t\t\t\t\t\t\tppvj: e.Playhouse_Prog_Vol_Job__c,\n\t\t\t\t\t\t\t\tshiftName: e.Name,\n\t\t\t\t\t\t\t  shiftId: e.Id,\n\t\t\t\t\t\t\t  location: e.Playhouse_Location_Name__c,\n\t\t\t\t\t\t\t  agesServed: e.Program_Ages_Served__c,\n\t\t\t\t\t\t\t  availableVirtually: e.Available_Virtually__c,\n\t\t\t\t\t\t\t  availableInPerson: e.Available_In_Person__c,\n\t\t\t\t\t\t\t\tallowRSVP: e.Allow_RSVP__c,\n\t\t\t\t\t\t\t\tallowGuestRegistration: e.Allow_Guest_Registration__c,\n\t\t\t\t\t\t\t\tallowWaitlist: e.Allow_Waitlist__c,\n\t\t\t\t\t\t\t\tallowDropIn: e.Allow_Drop_In__c,\n\t\t\t\t\t\t\t\trsvpOpenDate: e.RSVP_Open_Date__c,\n\t\t\t\t\t\t\t\trsvpDeadline: e.RSVP_Deadline__c,\n\t\t\t\t\t\t\t\twebinarLink: e.Webinar_link__c,\n\t\t\t\t\t\t\t  desiredNumberOfVolunteers: e.GW_Volunteers__Desired_Number_of_Volunteers__c,\n\t\t\t\t\t\t\t  totalNumberOfVolunteers: e.GW_Volunteers__Total_Volunteers__c,\n\t\t\t\t\t\t\t\tregisteredUsers: e.registeredUsers,\n\t\t\t\t\t\t\t  classNames: [stripSpecialChars(e.Playhouse_Location_Name__c), \n\t\t\t\t\t\t\t                stripSpecialChars(e.Program_Ages_Served__c),\n\t\t\t\t\t\t\t                getConditionalCssClass(e.Available_Virtually__c, 'virtual'),\n\t\t\t\t\t\t\t                getConditionalCssClass(e.Available_In_Person__c, 'inPerson')]\n\t\t\t\t\t\t\t  });\n\t\t\t\t\t\t  \/*console.debug(\"adding event '\" + e.Shift_Title__c + \"' on \" + e.GW_Volunteers__Start_Date_Time__c + \" until \" + calculatedEnd);*\/\n\t\t\t\t\t\t  \/\/ add these values to the filters\n\t\t\t\t\t\t  addUniqueValueToFilter(\"locationFilter\", e.Playhouse_Location_Name__c, e.Playhouse_Location_Name__c);\n\t\t\t\t\t\t\tif (e.Available_Virtually__c) {\n\t\t\t\t\t\t\t\taddUniqueValueToFilter(\"availabilityFilter\", \"Available Virtually\", \"Available Virtually\");\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (e.Available_In_Person__c) {\n\t\t\t\t\t\t\t\taddUniqueValueToFilter(\"availabilityFilter\", \"Available In Person\", \"Available In Person\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t  addUniqueValueToFilter(\"agesServedFilter\", e.Program_Ages_Served__c, e.Program_Ages_Served__c);\n\t\t\t\t}\n\n\t\tvar useMobileView = window.innerWidth < 768;\n\t\tfunction reinitializeCalendar(eventArray) {\n\t\t\tvar calendarEl = document.getElementById('calendar');\n\t\t\tcalendar = new FullCalendar.Calendar(calendarEl, {\n\t\t\t\/\/plugins: [ 'dayGrid', 'momentTimezone'],\n\t\t\tplugins: [ 'dayGrid', 'list'],\n\t\t\theader: {\n\t\t\t\tleft: 'title',\n\t\t\t\tcenter: '',\n\t\t\t\tright: 'today, prev,next'\n\t\t\t},\n\t\t\tcolumnHeaderFormat: {weekday:'long'} \/*for better translations*\/,\n\t\t\theight: \"auto\",\n\t\t\t\/\/defaultView: 'listMonth',\n\t\t\tdefaultView: useMobileView? 'listMonth': 'dayGridMonth',\n\t\t\twindowResize: function(view) {\n\t\t\t\t\tuseMobileView = window.innerWidth < 768;\n\t\t\t\t\tif (useMobileView) {\n\t\t\t\t\t\tcalendar.changeView('listMonth');\n\t\t\t\t\t\tconsole.debug(\"Switch to list view\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcalendar.changeView('dayGridMonth');\n\t\t\t\t\t\tconsole.debug(\"Switch to month view\");\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\ttimeZone: 'local',\n\t\t\tfixedWeekCount: false,\n\t\t\teventRender:  function(info) {\n\t\t\t\tlet titleElementSelector = '.fc-content';\n\t\t\t\tif (useMobileView) {\n\t\t\t\t\ttitleElementSelector = '.fc-list-item-title';\n\t\t\t\t}\n\t\t\t\tif (info.event.extendedProps.availableVirtually){\n\t\t\t\t\t\t\tlet contentEl = info.el.querySelector(titleElementSelector);\n\t\t\t\t\t\tif (contentEl != null) {\n                    let image = createVirtualImage();\n                    contentEl.append(image);\n\t\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (info.event.extendedProps.availableInPerson){\n\t\t\t\t\tlet contentEl = info.el.querySelector(titleElementSelector);\n\t\t\t\t\tif (contentEl != null) {\n\t\t\t\t\t\t\tcontentEl.append(createInPersonImage());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvar shouldRender = true;\n\t\t\t\tshouldRender = shouldRenderEventBasedOnFilter(\"locationFilter\", info.event.extendedProps.location, shouldRender);\n\t\t\t\tshouldRender = shouldRenderEventBasedOnFilter(\"agesServedFilter\", info.event.extendedProps.agesServed, shouldRender);\n\t\t\t\tshouldRender = shouldRenderEventBasedOnAvailability(info.event.extendedProps.availableVirtually, info.event.extendedProps.availableInPerson, shouldRender);\n\t\t\t\treturn shouldRender;\n\t\t\t},\n\t\t\teventClick:  function(eventClickInfo) {\n\t\t\t\t\t\/\/use the Bootstrap popover\n\t\t\t\t\teventClickInfo.jsEvent.preventDefault();\n        \tshowEventDetails(eventClickInfo.event);\n\t\t\t\t},\n\t\t\teventSources: [\n\t\t\t\t{\n\t\t\t\t\tevents: function(fetchInfo, successCallback, failureCallback) {\n\t\t\t\t\t\tvar myEvents = [];\n\t\t\t\t\t\tif (typeof sfEvents !== \"undefined\" && sfEvents != null && sfEvents.length > 0) {\n\t\t\t\t\t\t\t\/\/ legacy statid loading of events\n\t\t\t\t\t\t\tjQuery.each(sfEvents, function(idx, e) {\n\t\t\t\t\t\t\t\tgigiTransformEvent(myEvents, e);\n\t\t\t\t\t\t\t\tsuccessCallback(myEvents);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tdocument.getElementById(\"status\").style.display = \"none\";\n\t\t\t\t\t\t}else {\n\t\t\t\t\t\t\t\/\/ use dynamic data by querying for the month that is viewed\n\t\t\t\t\t\t\tvar endDate = new Date(fetchInfo.end);\n  \t\t\t\t\t\t\tendDate.setDate(endDate.getDate() + 30);\n  \t\t\t\t\t\t\t\/\/ remove the \/sfcalendar\/ from the url to eliminate a extra redirect from WordPress\n  \t\t\t\t\t\t\tlet baseUrl = (window.location.href.endsWith(\"\/\")? window.location.href.replace(\"sfcalendar\/\", \"\"): \"\");\n\t\t\t\t\t\t\tlet url = baseUrl + `calendar-data\/?start=${encodeURIComponent(fetchInfo.start.toISOString())}&end=${encodeURIComponent(endDate.toISOString())}&nocache=${Date.now()}`;\n\t\t\t\t\t\t\tconsole.log(\"Fetch calendar:\" + url);\n                    fetch(url)\n                        .then(response => {\n                            if (!response.ok) {\n                                throw new Error(`HTTP error! status: ${response.status}`);\n                            }\n                            return response.json();\n                        })\n                        .then(data => {\n                            \/\/ Process the data returned from the server\n                            jQuery.each(data, function (idx, e) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tgigiTransformEvent(myEvents, e);\n\t\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t\t\tsuccessCallback(myEvents);\n                        })\n                        .catch(error => {\n                            console.error('Error fetching calendar data:', error);\n                            failureCallback(error);\n                        });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t],\n\t\t\t\tloading: function (isLoading) {\n\t\t\t\t\tvar loadingDiv = document.getElementById(\"status\");\n\t\t\t\t\tif (isLoading) {\n\t\t\t\t\t\tloadingDiv.style.display = \"block\";\n\t\t\t\t\t}else {\n\t\t\t\t\t\tloadingDiv.style.display = \"none\";\n\t\t\t\t\t\t\/\/ check for an event id in the URL and popup the details if it exists\n\t\t\t\t\t\tvar url = new URL(window.location.href);\n\t\t\t\t\t\t\/\/url.searchParams.append(\"eventId\", 'a0V2J00000Iam72UAB');\n\t\t\t\t\t\tvar eventIdFromURL = url.searchParams.get(\"eventId\");\n\t\t\t\t\t\tconsole.debug(\"Looking for event:\" + eventIdFromURL);\n\t\t\t\t\t\tif (eventIdFromURL) {\n\t\t\t\t\t\t\tvar eventInfo = calendar.getEventById(eventIdFromURL);\n\t\t\t\t\t\t\t\/\/var eventInfo = calendar.events.find(x => x.shiftId === eventIdFromURL);\n\t\t\t\t\t\t\tif (eventInfo) {\n\t\t\t\t\t\t\t\tshowEventDetails(eventInfo);\n\t\t\t\t\t\t\t}else {\n\t\t\t\t\t\t\t\t\/\/ load the information dynamically\n\t\t\t\t\t\t\t\tcalendar.addEventSource(\n\t\t\t\t\t\t\t\t\tfunction(fetchInfo, successCallback, failureCallback) {\n\t\t\t\t\t\t\t\t\t\tvar myEvents = [];\n\t\t\t\t\t\t\t\t\t\tvar url = `\/calendar-specific-event-data\/?eventId=${encodeURIComponent(eventIdFromURL)}`;\n                                        fetch(url)\n                                            .then(response => {\n                                                if (!response.ok) {\n                                                    throw new Error(`HTTP error! status: ${response.status}`);\n                                                }\n                                                return response.json();\n                                            })\n                                            .then(data => {\n                                                \/\/ Process the data returned from the server\n                                                jQuery.each(data, function (idx, e) {\n                    \t\t\t\t\t\t\t\t\t\t\t\t\t\tgigiTransformEvent(myEvents, e);\n                    \t\t\t\t\t\t\t\t\t\t\t\t\t});\n                    \t\t\t\t\t\t\t\t\t\t\t\t\tsuccessCallback(myEvents);\n                                            })\n                                            .catch(error => {\n                                                console.error('Error fetching calendar data:', error);\n                                                failureCallback(error);\n                                            });\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tcalendar.render();\n\t\t\t\/\/ commented out scrolling since there is something else on the page that is scrolling the window after this\n\t\t\tscrollToNow();\n\t\t\t\n\t\t\tjQuery(\".Available_Virtually.legend\").append(createVirtualImage());\n\t\t\tjQuery(\".Available_In_Person.legend\").append(createInPersonImage());\n\t\t}\n\t\t\n\/\/ **** Keep the closing script tag ********\n    <\/script><\/div>\n\t<\/div>\n<\/div>\n<\/div>\n<\/div>\n\t<\/div>\n\n<div class=\"fl-col-group fl-node-6059098fdffa7\" data-node=\"6059098fdffa7\">\n\t\t\t<div class=\"fl-col fl-node-6059098fdffac fl-col-bg-color\" data-node=\"6059098fdffac\">\n\t<div class=\"fl-col-content fl-node-content\"><div class=\"fl-module fl-module-html fl-node-6059098fdffad\" data-node=\"6059098fdffad\">\n\t<div class=\"fl-module-content fl-node-content\">\n\t\t<div class=\"fl-html\">\n\t<form>\n\t<div id=\"legend\">\n\t\t<div id=\"locationFilterLegend\" class=\"filterLegend\">\n\t\t\t<div class=\"legendLabel\">Playhouse:<\/div>\n\t\t<\/div>\n    <div id=\"availabilityFilterLegend\" class=\"filterLegend\">\n    \t<div class=\"legendLabel\">Availability Options:<\/div>\n    <\/div>\n    <div id=\"agesServedFilterLegend\" class=\"filterLegend\">\n    \t<div class=\"legendLabel\">Ages Served:<\/div>\n    <\/div>\n\t<\/div>\n<\/form>\n<div id='calendar' style=\"width:100%\"><\/div><div id=\"status\"><img decoding=\"async\" src=\"https:\/\/gigisplayhouse.org\/wp-content\/uploads\/2025\/05\/loading.gif\" \/><\/div>\n\n<div class=\"modal fade-scale\" id=\"eventDetailsModal\" tabindex=\"-1\" aria-labelledby=\"Event Details Modal\" aria-hidden=\"true\" modal-fade-transform>\n  <div class=\"modal-dialog modal-dialog-centered modal-dialog-scrollable\">\n    <div class=\"modal-content\">\n      <div class=\"modal-header\">\n        <h5 class=\"modal-title\" id=\"eventDetailsModalTitle\">Modal title<\/h5>\n        <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-label=\"Close\">\n          <span aria-hidden=\"true\">&times;<\/span>\n        <\/button>\n      <\/div>\n      <div class=\"modal-body\" id=\"eventDetailsModalBody\">\n        Details about the event go here\n      <\/div>\n      <!--<div class=\"modal-footer\">\n        <button type=\"button\" class=\"btn btn-secondary\" data-dismiss=\"modal\">Close<\/button>\n      <\/div>-->\n      <div class=\"sflink\" id=\"eventDetailsSFLink\"><\/div>\n    <\/div>\n  <\/div>\n<\/div><\/div>\n\t<\/div>\n<\/div>\n<\/div>\n<\/div>\n\t<\/div>\n\t\t<\/div>\n\t<\/div>\n<\/div>\n<\/div><div class=\"uabb-js-breakpoint\" style=\"display: none;\"><\/div>\n\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-20801","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/gigisplayhouse.org\/fargo\/wp-json\/wp\/v2\/pages\/20801","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gigisplayhouse.org\/fargo\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/gigisplayhouse.org\/fargo\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/gigisplayhouse.org\/fargo\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gigisplayhouse.org\/fargo\/wp-json\/wp\/v2\/comments?post=20801"}],"version-history":[{"count":0,"href":"https:\/\/gigisplayhouse.org\/fargo\/wp-json\/wp\/v2\/pages\/20801\/revisions"}],"wp:attachment":[{"href":"https:\/\/gigisplayhouse.org\/fargo\/wp-json\/wp\/v2\/media?parent=20801"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gigisplayhouse.org\/fargo\/wp-json\/wp\/v2\/categories?post=20801"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gigisplayhouse.org\/fargo\/wp-json\/wp\/v2\/tags?post=20801"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}