@pimaonline/pimaonline-themepack 3.12.1 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +13 -26
- package/dist/css/main.css +1 -1
- package/dist/css/plugins/alt-icons.css +1 -1
- package/dist/css/plugins/dark-mode.css +1 -0
- package/dist/css/plugins/font-awesome.css +1 -1
- package/dist/css/routes.css +1 -1
- package/dist/css/themes/ait/styles.css +1 -1
- package/dist/css/themes/ajs/styles.css +1 -1
- package/dist/css/themes/ant/styles.css +1 -0
- package/dist/css/themes/art/styles.css +1 -1
- package/dist/css/themes/aviation/styles.css +1 -1
- package/dist/css/themes/bct/styles.css +1 -1
- package/dist/css/themes/bio/styles.css +1 -1
- package/dist/css/themes/blobs/styles.css +1 -0
- package/dist/css/themes/business/styles.css +1 -1
- package/dist/css/themes/cad/styles.css +1 -1
- package/dist/css/themes/cards/styles.css +1 -1
- package/dist/css/themes/cas/styles.css +1 -0
- package/dist/css/themes/cda/styles.css +1 -1
- package/dist/css/themes/chm/styles.css +1 -0
- package/dist/css/themes/cis/styles.css +1 -1
- package/dist/css/themes/communication/styles.css +1 -1
- package/dist/css/themes/computer-information-systems/styles.css +1 -1
- package/dist/css/themes/culinary/styles.css +1 -1
- package/dist/css/themes/culinary/versions/black-marble.css +1 -1
- package/dist/css/themes/culinary/versions/stainless.css +1 -1
- package/dist/css/themes/culinary/versions/wood.css +1 -1
- package/dist/css/themes/dental/styles.css +1 -1
- package/dist/css/themes/ece/styles.css +1 -1
- package/dist/css/themes/ecn/styles.css +1 -1
- package/dist/css/themes/eng/styles.css +1 -1
- package/dist/css/themes/fashion/styles.css +1 -1
- package/dist/css/themes/fitness/styles.css +1 -1
- package/dist/css/themes/fsc/styles.css +1 -1
- package/dist/css/themes/geography/styles.css +1 -1
- package/dist/css/themes/geology/styles.css +1 -1
- package/dist/css/themes/health-it/styles.css +1 -1
- package/dist/css/themes/history/styles.css +1 -1
- package/dist/css/themes/hrm/styles.css +1 -1
- package/dist/css/themes/hrs/styles.css +1 -1
- package/dist/css/themes/journalism/styles.css +1 -1
- package/dist/css/themes/lang/styles.css +1 -1
- package/dist/css/themes/lgm/styles.css +1 -1
- package/dist/css/themes/machine/styles.css +1 -1
- package/dist/css/themes/math/styles.css +1 -1
- package/dist/css/themes/mgt/styles.css +1 -1
- package/dist/css/themes/minimalist/styles.css +1 -1
- package/dist/css/themes/mkt/styles.css +1 -0
- package/dist/css/themes/music/styles.css +1 -1
- package/dist/css/themes/nursing/styles.css +1 -0
- package/dist/css/themes/philosophy/styles.css +1 -1
- package/dist/css/themes/pht/styles.css +1 -1
- package/dist/css/themes/phy/styles.css +1 -0
- package/dist/css/themes/pos/styles.css +1 -0
- package/dist/css/themes/psy/styles.css +1 -1
- package/dist/css/themes/reading/styles.css +1 -0
- package/dist/css/themes/resort/styles.css +1 -1
- package/dist/css/themes/soc/styles.css +1 -1
- package/dist/css/themes/ss/styles.css +1 -1
- package/dist/css/themes/tps/styles.css +1 -0
- package/dist/css/themes/university/styles.css +1 -1
- package/dist/css/themes/vet/styles.css +1 -1
- package/dist/css/themes/welding/styles.css +1 -1
- package/dist/css/themes/writing/styles.css +1 -1
- package/dist/img/general/arrow-right-black.svg +1 -0
- package/dist/img/general/arrow-right-primary-blue.svg +1 -0
- package/dist/img/general/arrow-right-white.svg +1 -0
- package/dist/img/general/eye-icon.svg +4 -0
- package/dist/img/general/gear-icon.svg +3 -0
- package/dist/img/general/moon-icon.svg +4 -0
- package/dist/img/general/sliders-icon.svg +1 -0
- package/dist/img/general/text-icon.svg +4 -0
- package/dist/img/general/width-icon.svg +4 -0
- package/dist/img/theme-images/ant/texture.png +0 -0
- package/dist/img/theme-images/cas/city-vector.svg +92 -0
- package/dist/img/theme-images/cas/farm-vector.svg +1 -0
- package/dist/img/theme-images/cas/ocean-vector.svg +1 -0
- package/dist/img/theme-images/cas/recycle-symbol.svg +1 -0
- package/dist/img/theme-images/chm/chem-letters/letter-a.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-b.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-c.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-d.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-e.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-f.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-g.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-h.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-i.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-j.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-k.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-l.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-m.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-n.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-o.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-p.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-q.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-r.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-s.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-t.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-u.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-v.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-w.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-x.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-y.png +0 -0
- package/dist/img/theme-images/chm/chem-letters/letter-z.png +0 -0
- package/dist/img/theme-images/mkt/blue/bluebars.svg +36 -0
- package/dist/img/theme-images/mkt/blue/blueheader.jpg +0 -0
- package/dist/img/theme-images/mkt/blue/bluepie.svg +42 -0
- package/dist/img/theme-images/mkt/green/greenbars.svg +36 -0
- package/dist/img/theme-images/mkt/green/greenheader.jpg +0 -0
- package/dist/img/theme-images/mkt/green/greenpie.svg +42 -0
- package/dist/img/theme-images/mkt/yellow/yellowbars.svg +36 -0
- package/dist/img/theme-images/mkt/yellow/yellowheader.jpg +0 -0
- package/dist/img/theme-images/mkt/yellow/yellowpie.svg +42 -0
- package/dist/img/theme-images/nursing/blue/bottomright-blue.svg +95 -0
- package/dist/img/theme-images/nursing/blue/topleft-blue.svg +111 -0
- package/dist/img/theme-images/nursing/green/bottomright-green.svg +95 -0
- package/dist/img/theme-images/nursing/green/topleft-green.svg +111 -0
- package/dist/img/theme-images/nursing/purple/bottomright-purple.svg +95 -0
- package/dist/img/theme-images/nursing/purple/topleft-purple.svg +111 -0
- package/dist/img/theme-images/nursing/teal/bottomright-teal.svg +95 -0
- package/dist/img/theme-images/nursing/teal/topleft-teal.svg +111 -0
- package/dist/img/theme-images/phy/background.svg +150 -0
- package/dist/img/theme-images/phy/tape-style1.svg +8 -0
- package/dist/img/theme-images/reading/bg10.jpg +0 -0
- package/dist/js/scripts2.js +1 -1552
- package/dist/js/themes/blobs.js +1 -0
- package/dist/js/themes/cas.js +1 -0
- package/dist/js/themes/chm.js +1 -0
- package/dist/js/themes/ecn.js +1 -13
- package/dist/js/themes/hrs.js +1 -19
- package/dist/plugins/fancybox/fancybox-example.html +1 -1
- package/dist/plugins/fancybox/helpers/jquery.fancybox-buttons.js +2 -122
- package/dist/plugins/fancybox/helpers/jquery.fancybox-media.js +2 -201
- package/dist/plugins/fancybox/helpers/jquery.fancybox-thumbs.js +2 -165
- package/dist/plugins/fancybox/jquery.fancybox.js +2 -2018
- package/dist/plugins/fancybox/jquery.fancybox.pack.js +2 -46
- package/dist/plugins/flashcards/flashcards-example.html +1 -1
- package/dist/plugins/flashcards/js/flash_cards.min.js +1 -12
- package/dist/plugins/flashcards/js/plugins/flash_cards.js +1 -62
- package/dist/plugins/flashcards/js/plugins/jquery.cycle.js +2 -1148
- package/dist/plugins/flashcards/js/vendor/jquery-1.7.2.js +2 -9404
- package/dist/plugins/flashcards/js/vendor/jquery-1.7.2.min.js +2 -4
- package/dist/plugins/flashcards/js/vendor/modernizr-2.5.3.min.js +1 -4
- package/dist/plugins/floating-particles/floating-particles.js +1 -68
- package/dist/plugins/global-homepage-overrides/global-homepage-overrides.js +1 -53
- package/dist/plugins/preview-banner/preview-banner.js +1 -57
- package/package.json +12 -16
- package/dist/js/jumpTo.js +0 -4
- package/dist/js/scripts-ts.js +0 -1
- package/dist/js/scripts.js +0 -327
- package/dist/js/themes/ss.js +0 -197
package/dist/js/scripts2.js
CHANGED
@@ -1,1552 +1 @@
|
|
1
|
-
const columnWidget = document.querySelector("#column-widget");
|
2
|
-
const contentLockWidgets = document.querySelectorAll(".content-lock-widget");
|
3
|
-
const contentLockInstructions = document.querySelectorAll(".instructions");
|
4
|
-
const contentLockQuizzes = document.querySelectorAll(".quiz");
|
5
|
-
const contentWrapper = document.querySelector("#content-wrapper");
|
6
|
-
const courseBody = document.querySelector("body");
|
7
|
-
const docHead = document.querySelector("head");
|
8
|
-
const flipCards = document.querySelectorAll(".flip-card-group");
|
9
|
-
const focusReaderTooltipText = "Highlight text as you scroll";
|
10
|
-
const galleryWrappers = document.querySelectorAll(".gallery-wrapper");
|
11
|
-
const h5pIframes = document.querySelectorAll("iframe");
|
12
|
-
const h5pResizer = document.createElement("script");
|
13
|
-
const h5pResizerExists = docHead.querySelector("script[src='https://pima.h5p.com/js/h5p-resizer.js']");
|
14
|
-
// This array contains CDNs for Bootstrap and Remix icon libraries stored as objects
|
15
|
-
const iconClasses = [
|
16
|
-
{ class: "bi-", cdn: "https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" },
|
17
|
-
{ class: "ri-", cdn: "https://cdn.jsdelivr.net/npm/remixicon@4.0.1/fonts/remixicon.css" }
|
18
|
-
];
|
19
|
-
const imageGallery = document.querySelector(".image-gallery");
|
20
|
-
const imgBoxes = document.querySelectorAll(".image-box");
|
21
|
-
const imgGalleries = document.querySelectorAll(".image-gallery");
|
22
|
-
const lockedContent = document.querySelectorAll(".locked-content");
|
23
|
-
const mediaContainers = document.querySelectorAll(".media-container");
|
24
|
-
const rolePres = document.querySelectorAll('[role="presentation"]');
|
25
|
-
const secondColumn = document.querySelector("#second-column");
|
26
|
-
const tables = document.querySelectorAll(".display, .display-lg")
|
27
|
-
const tabsWidgets = document.querySelectorAll(".tabs");
|
28
|
-
const thirdColumn = document.querySelector("#third-column");
|
29
|
-
const vocabCloseBtns = document.querySelectorAll("dl.vocab-list button");
|
30
|
-
const vocabDefs = document.querySelectorAll("dl.vocab-list dd");
|
31
|
-
const vocabListWidget = document.querySelector("dl.vocab-list");
|
32
|
-
const vocabLists = document.querySelectorAll("dl[class^='vocab-list']");
|
33
|
-
const vocabTerms = document.querySelectorAll("dl.vocab-list dt");
|
34
|
-
const videoWrapper = document.querySelector("#video-wrapper");
|
35
|
-
// JS to add role and aria-label to content-wrapper, second-column, and third-column
|
36
|
-
const addAria = () => {
|
37
|
-
if (contentWrapper) {
|
38
|
-
contentWrapper.setAttribute("role", "main");
|
39
|
-
} else if (!contentWrapper) {
|
40
|
-
console.log("Document error: does not contain #content-wrapper.");
|
41
|
-
}
|
42
|
-
if (secondColumn) {
|
43
|
-
secondColumn.setAttribute("role", "region");
|
44
|
-
secondColumn.setAttribute("aria-label", "Second column");
|
45
|
-
}
|
46
|
-
if (thirdColumn) {
|
47
|
-
thirdColumn.setAttribute("role", "region");
|
48
|
-
thirdColumn.setAttribute("aria-label", "Third column");
|
49
|
-
}
|
50
|
-
};
|
51
|
-
addAria();
|
52
|
-
const addGrid = () => {
|
53
|
-
if (contentWrapper && secondColumn && thirdColumn) {
|
54
|
-
courseBody.id = "three-column";
|
55
|
-
} else if (contentWrapper && secondColumn && !columnWidget) {
|
56
|
-
courseBody.id = "two-column";
|
57
|
-
} else if (contentWrapper && secondColumn && columnWidget) {
|
58
|
-
courseBody.id = "two-col-widget";
|
59
|
-
} else if ((contentWrapper && videoWrapper)) {
|
60
|
-
courseBody.id = "video-grid";
|
61
|
-
} else if (contentWrapper && !secondColumn && !thirdColumn && !columnWidget && !videoWrapper) {
|
62
|
-
courseBody.id = "one-column";
|
63
|
-
} else if (contentWrapper && !secondColumn && (thirdColumn || columnWidget)) {
|
64
|
-
console.log("Document error: <body> is missing id because #second-column doesn't exist.");
|
65
|
-
} else {
|
66
|
-
console.log("Document error: unable to determine the page layout for setting <body> id.");
|
67
|
-
}
|
68
|
-
|
69
|
-
const topLevelElements = document.body.children;
|
70
|
-
let foundNestedElement = false;
|
71
|
-
|
72
|
-
// Check for additional content outside #content-wrapper, #second-column, #third-column, or footer
|
73
|
-
for (let i = 0; i < topLevelElements.length; i++) {
|
74
|
-
const element = topLevelElements[i];
|
75
|
-
|
76
|
-
if (
|
77
|
-
element.id !== "content-wrapper" &&
|
78
|
-
element.id !== "second-column" &&
|
79
|
-
element.id !== "third-column" &&
|
80
|
-
element.id !== "column-widget" &&
|
81
|
-
element.tagName !== "HEADER" &&
|
82
|
-
element.tagName !== "FOOTER" &&
|
83
|
-
element.tagName !== "SCRIPT" &&
|
84
|
-
element.id !== "loom-companion-mv3" &&
|
85
|
-
element.className !== "focus-reader-switches"
|
86
|
-
) {
|
87
|
-
foundNestedElement = true;
|
88
|
-
break;
|
89
|
-
}
|
90
|
-
}
|
91
|
-
|
92
|
-
if (foundNestedElement) {
|
93
|
-
console.log("Document error: Additional content outside #content-wrapper, #second-column, #third-column, or footer.");
|
94
|
-
}
|
95
|
-
};
|
96
|
-
addGrid();
|
97
|
-
// Media Container
|
98
|
-
const addMediaContainersAria = () => {
|
99
|
-
mediaContainers.forEach((eachContainer, index) => {
|
100
|
-
// loopID: find the current index value, convert it to its letter equivalent, then convert to lowercase
|
101
|
-
let loopId = String.fromCharCode(index + 65).toLowerCase();
|
102
|
-
let mediaObject = eachContainer.querySelector(".media-object");
|
103
|
-
let iframe = eachContainer.querySelector("iframe");
|
104
|
-
let mediaInfo = eachContainer.querySelector(".media-info");
|
105
|
-
|
106
|
-
// Check if media container items are present
|
107
|
-
if (!iframe) {
|
108
|
-
console.log("Document error: no iframe found for media container");
|
109
|
-
}
|
110
|
-
if (!mediaObject) {
|
111
|
-
console.log("Document error: no media object found for media container");
|
112
|
-
}
|
113
|
-
|
114
|
-
// If element DOES NOT have "aria-describedby" && it DOES have a sibling element.
|
115
|
-
if (!iframe.hasAttribute("aria-describedby") && mediaInfo != null) {
|
116
|
-
iframe.setAttribute("aria-describedby", `${loopId}`);
|
117
|
-
mediaInfo.id = `${[loopId]}`;
|
118
|
-
}
|
119
|
-
});
|
120
|
-
}
|
121
|
-
if (mediaContainers) { addMediaContainersAria(); }
|
122
|
-
// -------- Add CDNs for Bootstrap and Remix icon libraries ---------
|
123
|
-
|
124
|
-
// The respective CDN will be added to <head> only if a page contains an icon with a prefix specific to that library. We use forEach to loop through iconClasses because that's more efficient than using multiple if statements to make sure only the necessary CDNs are added.
|
125
|
-
|
126
|
-
iconClasses.forEach(icon => {
|
127
|
-
const iconElement = document.querySelector(`[class*='${icon.class}']`);
|
128
|
-
if (iconElement) {
|
129
|
-
const metaTagRef = docHead.querySelector("meta[name='viewport']");
|
130
|
-
//Check if viewport meta tag exists
|
131
|
-
if (!metaTagRef) {
|
132
|
-
console.log("Document error: could not find viewport meta tag");
|
133
|
-
}
|
134
|
-
|
135
|
-
const iconCDN = document.createElement("link");
|
136
|
-
iconCDN.setAttribute("href", icon.cdn);
|
137
|
-
iconCDN.setAttribute("rel", "stylesheet");
|
138
|
-
|
139
|
-
// Stylesheets are added after meta tag and before themepack stylesheets and scripts to ensure proper styling override
|
140
|
-
docHead.insertBefore(iconCDN, metaTagRef.nextSibling);
|
141
|
-
}
|
142
|
-
});
|
143
|
-
// Check if parent of .gallery-wrapper has .image-gallery class
|
144
|
-
const checkGalleryWrapperParent = () => {
|
145
|
-
galleryWrappers.forEach((galleryWrapper) => {
|
146
|
-
if (!galleryWrapper.parentNode.classList.contains("image-gallery")) {
|
147
|
-
console.log(`Document error: parent of .gallery-wrapper does not have the .image-gallery class.`);
|
148
|
-
}
|
149
|
-
});
|
150
|
-
};
|
151
|
-
checkGalleryWrapperParent();
|
152
|
-
|
153
|
-
// Check if parent of .image-box has .gallery-wrapper class
|
154
|
-
const checkImageBoxParent = () => {
|
155
|
-
imgBoxes.forEach((imgBox) => {
|
156
|
-
if (!imgBox.parentNode.classList.contains("gallery-wrapper")) {
|
157
|
-
console.log(`Document error: parent of .image-box does not have the .gallery-wrapper class.`);
|
158
|
-
}
|
159
|
-
});
|
160
|
-
};
|
161
|
-
checkImageBoxParent();
|
162
|
-
|
163
|
-
// Check if direct children of .gallery-wrapper have .image-box class
|
164
|
-
const checkGalleryWrapperChildren = () => {
|
165
|
-
galleryWrappers.forEach((galleryWrapper) => {
|
166
|
-
let directChildren = Array.from(galleryWrapper.children).every(child => child.classList.contains("image-box"));
|
167
|
-
|
168
|
-
if (!directChildren) {
|
169
|
-
console.log(`Document error: not all direct children of .gallery-wrapper have the .image-box class.`);
|
170
|
-
}
|
171
|
-
});
|
172
|
-
};
|
173
|
-
checkGalleryWrapperChildren();
|
174
|
-
|
175
|
-
// Function to add Font Awesome CDN to the head
|
176
|
-
const addFontAwesomeCdn = () => {
|
177
|
-
const fontAwesomeCdn = document.createElement("link");
|
178
|
-
fontAwesomeCdn.rel = "stylesheet";
|
179
|
-
fontAwesomeCdn.href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css";
|
180
|
-
docHead.appendChild(fontAwesomeCdn);
|
181
|
-
};
|
182
|
-
|
183
|
-
// Function to create modal box HTML string
|
184
|
-
const createModalBox = () => {
|
185
|
-
return `<div class="modal-box invisible">
|
186
|
-
<div class="gallery-overlay"></div>
|
187
|
-
<figure class="modal-box--image"><i class="fa-solid fa-x close-img"></i> <img src="#" alt="image here" /><figcaption class="img-caption"></figcaption></figure>
|
188
|
-
</div>
|
189
|
-
<button class="hide-gallery">Hide</button>`;
|
190
|
-
};
|
191
|
-
|
192
|
-
// Function to initialize the image gallery
|
193
|
-
const callImageGallery = () => {
|
194
|
-
// Insert modal box HTML at the beginning of each image gallery
|
195
|
-
imgGalleries.forEach((gallery) => {
|
196
|
-
gallery.insertAdjacentHTML("afterbegin", createModalBox());
|
197
|
-
});
|
198
|
-
|
199
|
-
// Select necessary elements for later use
|
200
|
-
const overlay = document.querySelector(".gallery-overlay"),
|
201
|
-
modalBox = document.querySelector(".modal-box"),
|
202
|
-
modalImg = document.querySelector(".modal-box--image img"),
|
203
|
-
modalCaption = document.querySelector(".img-caption"),
|
204
|
-
closeImg = document.querySelector(".close-img"),
|
205
|
-
hideGalleries = document.querySelectorAll(".hide-gallery");
|
206
|
-
|
207
|
-
// Function to show modal with specified image source and caption
|
208
|
-
const showModal = (imgSrc, imgCaption) => {
|
209
|
-
modalBox.classList.remove("invisible");
|
210
|
-
modalImg.src = imgSrc;
|
211
|
-
modalCaption.innerHTML = imgCaption;
|
212
|
-
};
|
213
|
-
|
214
|
-
// Function to hide the modal
|
215
|
-
const hideModal = () => {
|
216
|
-
modalBox.classList.add("invisible");
|
217
|
-
};
|
218
|
-
|
219
|
-
// Attach event listeners to each image box
|
220
|
-
imgBoxes.forEach((imgBox) => {
|
221
|
-
// Show modal on click
|
222
|
-
imgBox.addEventListener("click", function () {
|
223
|
-
showModal(this.querySelector("img").src, this.querySelector("img").alt);
|
224
|
-
});
|
225
|
-
|
226
|
-
// Make images tab-able and show modal on Enter key press
|
227
|
-
imgBox.setAttribute("tabindex", "0");
|
228
|
-
imgBox.addEventListener("keydown", function (event) {
|
229
|
-
if (event.key === "Enter") {
|
230
|
-
showModal(this.querySelector("img").src, this.querySelector("img").alt);
|
231
|
-
}
|
232
|
-
});
|
233
|
-
});
|
234
|
-
|
235
|
-
// Attach event listeners for overlay, Escape key, and close button to hide the modal
|
236
|
-
overlay.onclick = hideModal;
|
237
|
-
window.onkeydown = (event) => {
|
238
|
-
if (event.keyCode === 27) {
|
239
|
-
hideModal();
|
240
|
-
}
|
241
|
-
};
|
242
|
-
closeImg.onclick = hideModal;
|
243
|
-
|
244
|
-
// Attach event listeners for "Hide/Show" button to toggle gallery visibility
|
245
|
-
hideGalleries.forEach((hideGallery) => {
|
246
|
-
hideGallery.addEventListener("click", () => {
|
247
|
-
hideGallery.nextElementSibling.classList.toggle("invisible");
|
248
|
-
hideGallery.innerHTML = hideGallery.innerHTML === "Hide" ? "Show" : "Hide";
|
249
|
-
});
|
250
|
-
});
|
251
|
-
};
|
252
|
-
|
253
|
-
// Check if imageGallery exists before initializing the image gallery
|
254
|
-
if (imageGallery) {
|
255
|
-
// Add Font Awesome CDN and initialize the image gallery
|
256
|
-
addFontAwesomeCdn();
|
257
|
-
callImageGallery();
|
258
|
-
}
|
259
|
-
//Tabs Widget
|
260
|
-
const callTabsWidget = () => {
|
261
|
-
|
262
|
-
let tabsWidgetsNum = 0;
|
263
|
-
|
264
|
-
tabsWidgets.forEach((tab, index) => {
|
265
|
-
let tabInputs = tab.querySelectorAll("input");
|
266
|
-
let tabLabels = tab.querySelectorAll("label");
|
267
|
-
let tabDivs = tab.querySelectorAll("div");
|
268
|
-
|
269
|
-
//Check that there are more than just one tab
|
270
|
-
if (tabInputs.length < 2 || tabLabels.length < 2 || tabDivs.length < 2) {
|
271
|
-
console.log("Document error: please add more than just one tab for tabs widget");
|
272
|
-
}
|
273
|
-
|
274
|
-
// Check amount of tab elements present
|
275
|
-
if (tabInputs.length < tabLabels.length || tabInputs.length < tabDivs.length) {
|
276
|
-
console.log("Document error: missing tab input(s) in tab widget");
|
277
|
-
}
|
278
|
-
|
279
|
-
if (tabLabels.length < tabInputs.length || tabLabels.length < tabDivs.length) {
|
280
|
-
console.log("Document error: missing tab label(s) in tab widget");
|
281
|
-
}
|
282
|
-
|
283
|
-
let groupNum = index + 1;
|
284
|
-
|
285
|
-
//Add region and aria-label to parent div
|
286
|
-
tab.setAttribute("role", "region");
|
287
|
-
tab.setAttribute("aria-label", `tab group ${groupNum}`)
|
288
|
-
|
289
|
-
// Iterate over the entries of the tabInputs NodeList using a for loop. Inside the loop, tabIndex is the index of the current tab input element. tabInput is the actual input element itself.
|
290
|
-
for (tabIndex = 0; tabIndex < tabInputs.length; tabIndex++) {
|
291
|
-
|
292
|
-
// Add the hide-tab class to the "Hide" label
|
293
|
-
if (tabLabels[tabIndex].textContent.trim() === "Hide") {
|
294
|
-
tabLabels[tabIndex].classList.add("hide-tab");
|
295
|
-
}
|
296
|
-
|
297
|
-
let tabNum = tabsWidgetsNum + 1;
|
298
|
-
|
299
|
-
// Check on present variables
|
300
|
-
if (tabInputs === null) {
|
301
|
-
console.log("Document error: no inputs found for tabs widget");
|
302
|
-
console.log("Document error: no divs (tab panels) found for tabs widget");
|
303
|
-
}
|
304
|
-
|
305
|
-
if (tabLabels === null) {
|
306
|
-
console.log("Document error: no labels found for tabs widget");
|
307
|
-
}
|
308
|
-
|
309
|
-
//Add class, id, name, and aria-described by for inputs
|
310
|
-
tabInputs[tabIndex].classList.add("tab-input");
|
311
|
-
tabInputs[tabIndex].setAttribute("type", "radio")
|
312
|
-
tabInputs[tabIndex].setAttribute("id", `tab${tabNum}`);
|
313
|
-
tabInputs[tabIndex].setAttribute("name", `hint-group-${groupNum}`);
|
314
|
-
tabInputs[tabIndex].setAttribute("aria-describedby", `tabHeading${tabNum}`);
|
315
|
-
|
316
|
-
//Add class and for for labels
|
317
|
-
tabLabels[tabIndex].classList.add("tab-header");
|
318
|
-
tabLabels[tabIndex].setAttribute("for", `tab${tabNum}`);
|
319
|
-
|
320
|
-
//Add class, tabindex, and id for divs
|
321
|
-
if (tabDivs[tabIndex]) {
|
322
|
-
tabDivs[tabIndex].classList.add("tab-panel");
|
323
|
-
tabDivs[tabIndex].setAttribute("tabindex", 0);
|
324
|
-
tabDivs[tabIndex].setAttribute("id", `tabHeading${tabNum}`);
|
325
|
-
}
|
326
|
-
|
327
|
-
//Add attributes for hide tab
|
328
|
-
if (tabIndex === 0) { // Change this condition to check the first tab
|
329
|
-
tabLabels[tabIndex].classList.remove("hide-tab"); // Remove the hide-tab class
|
330
|
-
tabInputs[tabIndex].checked = true; // Check the first tab input
|
331
|
-
if (tabDivs[tabIndex]) {
|
332
|
-
tabDivs[tabIndex].classList.remove("hide-panel"); // Remove the hide-panel class
|
333
|
-
}
|
334
|
-
} else {
|
335
|
-
tabInputs[tabIndex].checked = false;
|
336
|
-
if (tabDivs[tabIndex]) {
|
337
|
-
tabDivs[tabIndex].classList.add("hide-panel");
|
338
|
-
}
|
339
|
-
}
|
340
|
-
|
341
|
-
// Add click event listener to each tab label
|
342
|
-
tabLabels[tabIndex].addEventListener("click", ((index) => {
|
343
|
-
return () => {
|
344
|
-
// Check if the clicked label is the "Hide" label
|
345
|
-
if (tabLabels[index].textContent.trim() === "Hide") {
|
346
|
-
// Hide all tab panels
|
347
|
-
tabDivs.forEach(div => div.classList.add("hide-panel"));
|
348
|
-
} else {
|
349
|
-
// Uncheck all tab inputs
|
350
|
-
tabInputs.forEach(input => input.checked = false);
|
351
|
-
// Check the clicked tab input
|
352
|
-
tabInputs[index].checked = true;
|
353
|
-
// Show the clicked tab panel
|
354
|
-
if (tabDivs[index]) {
|
355
|
-
tabDivs[index].classList.remove("hide-panel");
|
356
|
-
}
|
357
|
-
}
|
358
|
-
};
|
359
|
-
})(tabIndex)); // Immediately invoke the function with the current tabIndex
|
360
|
-
|
361
|
-
tabsWidgetsNum++;
|
362
|
-
}
|
363
|
-
})
|
364
|
-
}
|
365
|
-
if (tabsWidgets) { callTabsWidget(); }
|
366
|
-
// Vocab list widget
|
367
|
-
const callVocabList = () => {
|
368
|
-
|
369
|
-
const handleVocabClose = (vocabItem) => {
|
370
|
-
if (vocabItem) {
|
371
|
-
let listDefinitions = vocabItem.querySelectorAll("dd");
|
372
|
-
let listTerms = vocabItem.querySelectorAll("dt");
|
373
|
-
|
374
|
-
// If the button is clicked and it is the DD - then hide it
|
375
|
-
listDefinitions.forEach((definition) => {
|
376
|
-
definition.style.display = "none";
|
377
|
-
})
|
378
|
-
|
379
|
-
// If the button is clicked and it is the DT - then remove active class
|
380
|
-
listTerms.forEach((term) => {
|
381
|
-
term.classList.remove("active");
|
382
|
-
})
|
383
|
-
}
|
384
|
-
}
|
385
|
-
|
386
|
-
// Check if the vocab list has one or multiple items within
|
387
|
-
vocabLists.forEach((list) => {
|
388
|
-
|
389
|
-
//Count and ensure it has more than 1 term and definition
|
390
|
-
let terms = 0;
|
391
|
-
let definitions = 0;
|
392
|
-
let closeBtnPresent = false;
|
393
|
-
|
394
|
-
// If the list contains more than one set of <dt> and <dd> tags then add a close button
|
395
|
-
for (let listIndex = 0; listIndex < list.children.length; listIndex++) {
|
396
|
-
// Count terms
|
397
|
-
if (list.children[listIndex].tagName == "DT") {
|
398
|
-
list.children[listIndex].setAttribute("tabindex", "0");
|
399
|
-
terms++;
|
400
|
-
}
|
401
|
-
// Count definitions
|
402
|
-
if (list.children[listIndex].tagName == "DD") {
|
403
|
-
definitions++;
|
404
|
-
}
|
405
|
-
|
406
|
-
//Check for close all button
|
407
|
-
if (list.children[listIndex].tagName == "BUTTON") {
|
408
|
-
closeBtnPresent = true;
|
409
|
-
}
|
410
|
-
}
|
411
|
-
|
412
|
-
// Check for terms and definitions in the vocab list
|
413
|
-
if (terms < 1) {
|
414
|
-
console.log("Document error: no terms found in vocab list");
|
415
|
-
}
|
416
|
-
|
417
|
-
if (definitions < 1) {
|
418
|
-
console.log("Document error: no definitions found in vocab list");
|
419
|
-
}
|
420
|
-
|
421
|
-
if (terms > definitions) {
|
422
|
-
console.log("Document error: more terms than definitions in vocab list")
|
423
|
-
}
|
424
|
-
|
425
|
-
// If there are more than 2 terms and 2 definitions, then check for a button
|
426
|
-
if (terms >= 2 && definitions >= 2) {
|
427
|
-
|
428
|
-
// If there isn't a close button then add one
|
429
|
-
if (!closeBtnPresent) {
|
430
|
-
// Add a close button
|
431
|
-
const closeButton = document.createElement("button");
|
432
|
-
closeButton.textContent = "Close All"; // Set the button text as needed
|
433
|
-
// Add click event listener for button
|
434
|
-
closeButton.addEventListener("click", () => handleVocabClose(list))
|
435
|
-
|
436
|
-
// Add keydown event listener for button
|
437
|
-
closeButton.addEventListener("keydown", (event) => {
|
438
|
-
if (event.key == "Enter") {
|
439
|
-
handleVocabClose(list);
|
440
|
-
}
|
441
|
-
})
|
442
|
-
// Append the button to the end of the list
|
443
|
-
list.appendChild(closeButton);
|
444
|
-
}
|
445
|
-
// If button is present, remove it
|
446
|
-
else {
|
447
|
-
let closeBtn = list.querySelector("button");
|
448
|
-
|
449
|
-
// Add the same event listeners as if you were to add a new button
|
450
|
-
closeBtn.addEventListener("click", () => handleVocabClose(list))
|
451
|
-
|
452
|
-
closeBtn.addEventListener("keydown", (event) => {
|
453
|
-
if (event.key == "Enter") {
|
454
|
-
handleVocabClose(list);
|
455
|
-
}
|
456
|
-
})
|
457
|
-
|
458
|
-
}
|
459
|
-
} else {
|
460
|
-
|
461
|
-
// List does not have more than 2 pairs of terms and definitions
|
462
|
-
|
463
|
-
// Don't add a close button since there is only one term, but remove the button if it is present
|
464
|
-
for (let listIndex = 0; listIndex < list.children.length; listIndex++) {
|
465
|
-
|
466
|
-
//Check for close all button
|
467
|
-
if (list.children[listIndex].tagName == "BUTTON") {
|
468
|
-
closeBtnPresent = true;
|
469
|
-
}
|
470
|
-
}
|
471
|
-
|
472
|
-
if (closeBtnPresent) {
|
473
|
-
let closeBtn = list.querySelector("button");
|
474
|
-
closeBtn.style.display = "none";
|
475
|
-
}
|
476
|
-
}
|
477
|
-
})
|
478
|
-
|
479
|
-
// Loop through all the terms and apply click and keydown event
|
480
|
-
for (let activeTerm = 0; activeTerm < vocabTerms.length; activeTerm++) {
|
481
|
-
// Add click event for toggling vocab terms
|
482
|
-
vocabTerms[activeTerm].addEventListener("click", function () {
|
483
|
-
// When clicked, toggle the active class
|
484
|
-
this.classList.toggle("active");
|
485
|
-
|
486
|
-
// Target the definition <dd> element
|
487
|
-
let termPanel = this.nextElementSibling;
|
488
|
-
|
489
|
-
// Toggle the display from none to block
|
490
|
-
if (termPanel.style.display === "block") {
|
491
|
-
termPanel.style.display = "none";
|
492
|
-
} else {
|
493
|
-
termPanel.style.display = "block";
|
494
|
-
}
|
495
|
-
|
496
|
-
// Start a while loop to continue through the DOM
|
497
|
-
while (termPanel.nextElementSibling) {
|
498
|
-
// Move to the next sibling element
|
499
|
-
termPanel = termPanel.nextElementSibling;
|
500
|
-
|
501
|
-
// Check if the current element is a <dd>
|
502
|
-
if (termPanel.tagName === "DD") {
|
503
|
-
// Toggle the display from none to block
|
504
|
-
if (termPanel.style.display === "block") {
|
505
|
-
termPanel.style.display = "none";
|
506
|
-
} else {
|
507
|
-
termPanel.style.display = "block";
|
508
|
-
}
|
509
|
-
} else {
|
510
|
-
// Stop the loop if the current element is not a <dd>
|
511
|
-
break;
|
512
|
-
}
|
513
|
-
}
|
514
|
-
});
|
515
|
-
|
516
|
-
|
517
|
-
// Add keydown event for toggling vocab terms
|
518
|
-
vocabTerms[activeTerm].addEventListener("keydown", function (e) {
|
519
|
-
|
520
|
-
// When user hits enter, toggle the active class
|
521
|
-
if (e.key === "Enter") {
|
522
|
-
// When clicked, toggle the active class
|
523
|
-
this.classList.toggle("active");
|
524
|
-
|
525
|
-
// Target the definition <dd> element
|
526
|
-
let termPanel = this.nextElementSibling;
|
527
|
-
|
528
|
-
// Toggle the display from none to block
|
529
|
-
if (termPanel.style.display === "block") {
|
530
|
-
termPanel.style.display = "none";
|
531
|
-
} else {
|
532
|
-
termPanel.style.display = "block";
|
533
|
-
}
|
534
|
-
// Start a while loop to continue through the DOM
|
535
|
-
while (termPanel.nextElementSibling) {
|
536
|
-
// Move to the next sibling element
|
537
|
-
termPanel = termPanel.nextElementSibling;
|
538
|
-
|
539
|
-
// Check if the current element is a <dd>
|
540
|
-
if (termPanel.tagName === "DD") {
|
541
|
-
// Toggle the display from none to block
|
542
|
-
if (termPanel.style.display === "block") {
|
543
|
-
termPanel.style.display = "none";
|
544
|
-
} else {
|
545
|
-
termPanel.style.display = "block";
|
546
|
-
}
|
547
|
-
} else {
|
548
|
-
// Stop the loop if the current element is not a <dd>
|
549
|
-
break;
|
550
|
-
}
|
551
|
-
}
|
552
|
-
}
|
553
|
-
});
|
554
|
-
}
|
555
|
-
}
|
556
|
-
if (vocabListWidget) { callVocabList(); }
|
557
|
-
// Clean up HTML
|
558
|
-
const cleanMarkup = () => {
|
559
|
-
// Remove role="presentation" attr from any element that has it
|
560
|
-
if (rolePres) {
|
561
|
-
rolePres.forEach((roleElem) => roleElem.removeAttribute("role"));
|
562
|
-
}
|
563
|
-
// Set functino to remove atrributes from elements
|
564
|
-
const discardAttributes = (element, ...attributes) => {
|
565
|
-
attributes.forEach((attribute) => element.removeAttribute(attribute));
|
566
|
-
}
|
567
|
-
// Remove attributes from tables
|
568
|
-
const tableElems = document.querySelectorAll("table, thead, tbody, tr, th, td");
|
569
|
-
tableElems.forEach((elem) => {
|
570
|
-
discardAttributes(elem, "cellspacing", "cellpadding", "width", "style");
|
571
|
-
});
|
572
|
-
};
|
573
|
-
cleanMarkup();
|
574
|
-
const handleContentLockWidget = (contentLockWidgets) => {
|
575
|
-
|
576
|
-
const lockedContentQuizIncorrectAnswer = "Incorrect response. Please try again."; // Error response for quizzes
|
577
|
-
const lockedContentQuizEmptyResponse = "Please select an option before submitting."; // Error response for quizzes
|
578
|
-
const unlockBtnContent = []; // Save text content of unlock button
|
579
|
-
|
580
|
-
// ––––––––– Functions –––––––––
|
581
|
-
|
582
|
-
// Function to run when local storage is updated
|
583
|
-
const handleContentLockLocalStorageUpdate = (event, courseNumber) => {
|
584
|
-
if (event && event.key === "contentLockData" && event.newValue) {
|
585
|
-
// Update contentLockData variable
|
586
|
-
contentLockData = JSON.parse(event.newValue);
|
587
|
-
// Run your code here
|
588
|
-
checkHiddenContent(courseNumber);
|
589
|
-
}
|
590
|
-
}
|
591
|
-
|
592
|
-
// Function that checks key status, toggles classes, and updates local storage, and checks for other content areas
|
593
|
-
const unlockCheck = (contentLockKeyNum, courseNumber, buttonIndex) => {
|
594
|
-
|
595
|
-
// Toggle the key status to true to unlock the content
|
596
|
-
contentLockData[courseNumber].keys[contentLockKeyNum] = true;
|
597
|
-
|
598
|
-
// Toggle classes based on key status
|
599
|
-
if (contentLockData[courseNumber].keys[contentLockKeyNum]) {
|
600
|
-
lockedContent[buttonIndex].classList.add("open");
|
601
|
-
contentLockInstructions[buttonIndex].classList.add("complete");
|
602
|
-
} else {
|
603
|
-
lockedContent[buttonIndex].classList.remove("open");
|
604
|
-
contentLockInstructions[buttonIndex].classList.remove("complete");
|
605
|
-
}
|
606
|
-
|
607
|
-
// Save the updated contentLockData object to local storage
|
608
|
-
localStorage.setItem("contentLockData", JSON.stringify(contentLockData));
|
609
|
-
|
610
|
-
// Update the hidden content based on the key status
|
611
|
-
checkHiddenContent(courseNumber);
|
612
|
-
}
|
613
|
-
|
614
|
-
// Function to display the error message from the form
|
615
|
-
const displayError = (quizForm, contentLockErrorMessage) => {
|
616
|
-
|
617
|
-
// Create a new paragraph element for the error message
|
618
|
-
let contentLockerrorContainer = quizForm.querySelector(".error-container");
|
619
|
-
let errorMessage = document.createElement("span");
|
620
|
-
|
621
|
-
// Clear any previous error messages
|
622
|
-
contentLockerrorContainer.innerHTML = "";
|
623
|
-
|
624
|
-
// Clear error message
|
625
|
-
errorMessage.textContent = "";
|
626
|
-
|
627
|
-
// Append the blank text message to the container
|
628
|
-
contentLockerrorContainer.appendChild(errorMessage);
|
629
|
-
|
630
|
-
// Add a timer to apply the new error message to ensure the user understands it is a new error message
|
631
|
-
setTimeout(function () {
|
632
|
-
|
633
|
-
// Clear error message
|
634
|
-
errorMessage.textContent = contentLockErrorMessage;
|
635
|
-
|
636
|
-
// Append the new error message to the container
|
637
|
-
contentLockerrorContainer.appendChild(errorMessage);
|
638
|
-
|
639
|
-
}, 200); // 200 milliseconds = .2 seconds
|
640
|
-
}
|
641
|
-
|
642
|
-
// Quiz checking function
|
643
|
-
const submitContentLockQuiz = (contentLockKeyNum) => {
|
644
|
-
let contentLockQuizForm = document.getElementById(`quiz${contentLockKeyNum}`);
|
645
|
-
|
646
|
-
// This selects the option that the user selected
|
647
|
-
let selectedOption = contentLockQuizForm.querySelector("input[name='options']:checked");
|
648
|
-
|
649
|
-
// This finds the input option that had the correct answer
|
650
|
-
let contentLockQuizcorrectAnswer = contentLockQuizForm.querySelector("input.correct-answer");
|
651
|
-
|
652
|
-
// Initialize a variable for error message, that can changed based on which error
|
653
|
-
let contentLockErrorMessage = "";
|
654
|
-
|
655
|
-
// If there is a selected option, run the logic to see if it matches
|
656
|
-
if (selectedOption) {
|
657
|
-
// If selected option matches correct answer
|
658
|
-
if (selectedOption.value === contentLockQuizcorrectAnswer.value) {
|
659
|
-
|
660
|
-
// Tells the user they selected the correct response
|
661
|
-
alert("Correct response");
|
662
|
-
return true;
|
663
|
-
} else {
|
664
|
-
|
665
|
-
// Sets the error message for the user
|
666
|
-
contentLockErrorMessage = lockedContentQuizIncorrectAnswer;
|
667
|
-
displayError(contentLockQuizForm, contentLockErrorMessage)
|
668
|
-
return false;
|
669
|
-
}
|
670
|
-
} else {
|
671
|
-
contentLockErrorMessage = lockedContentQuizEmptyResponse;
|
672
|
-
displayError(contentLockQuizForm, contentLockErrorMessage)
|
673
|
-
return false;
|
674
|
-
}
|
675
|
-
}
|
676
|
-
|
677
|
-
/* This function loops through each content area on the page
|
678
|
-
* and checks the status of the data-key to see if it should
|
679
|
-
* be unlocked or not
|
680
|
-
*/
|
681
|
-
const checkHiddenContent = (courseNumber) => {
|
682
|
-
|
683
|
-
// Get data-key number for each content area
|
684
|
-
lockedContent.forEach((contentArea, contentAreaIndex) => {
|
685
|
-
let contentLockKeyNum = contentArea.getAttribute("data-key");
|
686
|
-
|
687
|
-
// Toggle classes based on key status
|
688
|
-
if (contentLockData[courseNumber].keys[contentLockKeyNum]) {
|
689
|
-
lockedContent[contentAreaIndex].classList.add("open");
|
690
|
-
contentLockInstructions[contentAreaIndex].classList.add("complete");
|
691
|
-
} else {
|
692
|
-
lockedContent[contentAreaIndex].classList.remove("open");
|
693
|
-
contentLockInstructions[contentAreaIndex].classList.remove("complete");
|
694
|
-
}
|
695
|
-
});
|
696
|
-
}
|
697
|
-
|
698
|
-
/* This function is when a user clicks or keysdown to unlock
|
699
|
-
* a content area. This function is the same wether clicked on
|
700
|
-
* or if it is through a keyboard
|
701
|
-
*/
|
702
|
-
const handleContentUnlock = (unlockButton, buttonIndex, unlockBtnContent, courseNumber) => {
|
703
|
-
|
704
|
-
/* This variable acts as a flag, for determining if a content unlock button is related to a quiz
|
705
|
-
* or if the content related to this button is supposed to use a confirmation window.
|
706
|
-
*/
|
707
|
-
let quizElement = false;
|
708
|
-
|
709
|
-
// Loop through all the contentUnlockBtns and add an event listener
|
710
|
-
|
711
|
-
let contentLockKeyNum = lockedContent[buttonIndex].getAttribute("data-key");
|
712
|
-
|
713
|
-
// This is used as a flag. Needs to be set to true in order to unlock the content
|
714
|
-
let contentLockAnswerConfirmed = false;
|
715
|
-
|
716
|
-
//Query Selector to see if there is a quiz option or not
|
717
|
-
if (unlockButton.tagName === "INPUT") {
|
718
|
-
quizElement = true;
|
719
|
-
}
|
720
|
-
|
721
|
-
// If quiz exists for this data key number, otherwise, do the confirmation window
|
722
|
-
if (quizElement) {
|
723
|
-
|
724
|
-
// Show the html for the quiz. The html will handle the quiz functionality. Returns true or false.
|
725
|
-
contentLockAnswerConfirmed = submitContentLockQuiz(contentLockKeyNum)
|
726
|
-
if (contentLockAnswerConfirmed) {
|
727
|
-
|
728
|
-
// Unlock the content and perform other related actions (see function for more)
|
729
|
-
unlockCheck(contentLockKeyNum, courseNumber, buttonIndex)
|
730
|
-
}
|
731
|
-
} else {
|
732
|
-
|
733
|
-
/* Add a confirmation window that pops up and waits for the user to confirm
|
734
|
-
* the instructions were followed to unlock the content(if no quiz is available)
|
735
|
-
*/
|
736
|
-
contentLockAnswerConfirmed = window.confirm(`Please confirm: ${unlockBtnContent[buttonIndex]}`)
|
737
|
-
|
738
|
-
if (contentLockAnswerConfirmed) {
|
739
|
-
unlockCheck(contentLockKeyNum, courseNumber, buttonIndex)
|
740
|
-
}
|
741
|
-
}
|
742
|
-
}
|
743
|
-
|
744
|
-
// –––––––––––––––– End of Functions ––––––––––––––––
|
745
|
-
|
746
|
-
// Checks the URL for the course number
|
747
|
-
const currentURL = window.parent.location.href;
|
748
|
-
const match = currentURL.match(/\/content\/(\d+)/);
|
749
|
-
const courseNumber = match ? match[1] : null;
|
750
|
-
|
751
|
-
// Error Checking - course number exists
|
752
|
-
if (!courseNumber) {
|
753
|
-
console.log("Document Error: course number does not exist");
|
754
|
-
}
|
755
|
-
|
756
|
-
// Letters are used in inputs as values. Each letter represents an input option.
|
757
|
-
const optionLetters = ["a", "b", "c", "d", "e", "f", "g", "h", "i"];
|
758
|
-
|
759
|
-
// Create an object that keeps track of keys and their statuses
|
760
|
-
const contentLockData = JSON.parse(localStorage.getItem("contentLockData")) || {};
|
761
|
-
|
762
|
-
// Add event listener for storage changes
|
763
|
-
window.addEventListener("storage", (event) => {
|
764
|
-
if (courseNumber) {
|
765
|
-
handleContentLockLocalStorageUpdate(event, courseNumber);
|
766
|
-
}
|
767
|
-
});
|
768
|
-
|
769
|
-
// Apply the quiz IDs and search if quizzes are being used
|
770
|
-
contentLockWidgets.forEach((contentLockWidget, contentLockWidgetIndex) => {
|
771
|
-
|
772
|
-
let contentLockForm = contentLockWidget.querySelector(".quiz form");
|
773
|
-
|
774
|
-
/* If a quiz is present in content lock widget, then go through the page
|
775
|
-
* and assign the quiz ID based on the data-key for the corresponding
|
776
|
-
* locked-content.
|
777
|
-
*/
|
778
|
-
if (contentLockForm) {
|
779
|
-
let lockedContent = contentLockWidget.querySelector(".locked-content");
|
780
|
-
let contentLockKeyNum = lockedContent.getAttribute("data-key");
|
781
|
-
let contentLockQuizcorrectAnswer = contentLockWidget.querySelector(".quiz .correct-answer");
|
782
|
-
|
783
|
-
// Error checking - locked-content class
|
784
|
-
if (!lockedContent) {
|
785
|
-
console.log(`Document Error: missing the locked-content class for widget number ${contentLockWidgetIndex + 1} on this page`)
|
786
|
-
}
|
787
|
-
|
788
|
-
// Error checking - data key
|
789
|
-
if (!contentLockKeyNum) {
|
790
|
-
console.log(`Document Error: missing data-key for locked content for widget number ${contentLockWidgetIndex + 1} on this page`)
|
791
|
-
}
|
792
|
-
|
793
|
-
// Error Check - correct-answer class for the quiz
|
794
|
-
if (!contentLockQuizcorrectAnswer) {
|
795
|
-
console.log(`Document Error: missing correct-answer for content lock quiz for widget number ${contentLockWidgetIndex + 1} on this page`)
|
796
|
-
}
|
797
|
-
|
798
|
-
// Assign each form an ID
|
799
|
-
contentLockForm.id = `quiz${contentLockKeyNum}`;
|
800
|
-
|
801
|
-
// Search for error container in the widget
|
802
|
-
let errorContainerExists = contentLockWidget.querySelector(".error-container");
|
803
|
-
|
804
|
-
// If the error container doesn't exist, add it via HTML
|
805
|
-
if (!errorContainerExists) {
|
806
|
-
let errorContainer = document.createElement("div");
|
807
|
-
errorContainer.classList.add("error-container");
|
808
|
-
let contentLockSubmitBtn = contentLockWidget.querySelector("input[value='Submit']");
|
809
|
-
if (contentLockSubmitBtn) {
|
810
|
-
// Add the error container above the submit button in the quiz
|
811
|
-
contentLockSubmitBtn.insertAdjacentHTML("beforebegin", errorContainer.outerHTML)
|
812
|
-
} else {
|
813
|
-
console.log(`Document Error: quiz is missing an input with value 'Submit' for widget number ${contentLockWidgetIndex + 1} on this page.`)
|
814
|
-
}
|
815
|
-
}
|
816
|
-
}
|
817
|
-
// If the content lock widget does not use a form and uses a confirmation window instead
|
818
|
-
else {
|
819
|
-
// Error checking - ensure it has an unlock button in the HTML
|
820
|
-
let unlockBtn = contentLockWidget.querySelector(".unlock-btn");
|
821
|
-
if (!unlockBtn) {
|
822
|
-
console.log(`Document Error: locked content area (that is not using a quiz) is missing <a> with .unlock-btn for widget number ${contentLockWidgetIndex + 1} on this page.`)
|
823
|
-
}
|
824
|
-
}
|
825
|
-
})
|
826
|
-
|
827
|
-
/* Function to apply attributes to quiz elements. This function uses
|
828
|
-
* an asynchronous function to ensure that the JS doesn't run until
|
829
|
-
* after this function is complete and the promise has been returned.
|
830
|
-
* This helps ensure that no other querySelectors are broken.
|
831
|
-
*/
|
832
|
-
const applyAttributesToQuiz = () => {
|
833
|
-
|
834
|
-
// Returns the resolve value or reject value depending on if the promise is successful or fails
|
835
|
-
return new Promise((resolve, reject) => {
|
836
|
-
let contentLockQuizForms = document.querySelectorAll(".quiz form");
|
837
|
-
|
838
|
-
// If there are forms, then apply the specific attributes to the inputs
|
839
|
-
if (contentLockQuizForms) {
|
840
|
-
contentLockQuizForms.forEach((quizForm) => {
|
841
|
-
let quizInputs = quizForm.querySelectorAll("input");
|
842
|
-
|
843
|
-
// Loop through all the inputs and apply the correct attributes
|
844
|
-
quizInputs.forEach((quizInput, InputIndex) => {
|
845
|
-
|
846
|
-
// If the values are null, then populate it with the right attributes
|
847
|
-
if (!quizInput.getAttribute("value")) {
|
848
|
-
quizInput.setAttribute("value", optionLetters[InputIndex]);
|
849
|
-
quizInput.setAttribute("name", "options");
|
850
|
-
quizInput.setAttribute("type", "radio");
|
851
|
-
}
|
852
|
-
|
853
|
-
// If the input has the value "submit" then apply different attributes for submit button
|
854
|
-
else if (quizInput.getAttribute("value") == "Submit") {
|
855
|
-
quizInput.setAttribute("type", "button");
|
856
|
-
quizInput.classList.add("unlock-btn");
|
857
|
-
}
|
858
|
-
})
|
859
|
-
})
|
860
|
-
}
|
861
|
-
resolve(); // Resolve the Promise once attributes are applied
|
862
|
-
});
|
863
|
-
}
|
864
|
-
applyAttributesToQuiz().then(() => {
|
865
|
-
|
866
|
-
/* This query selector relies on the dynamically added attributes above, so do not put this
|
867
|
-
* variable with the other ones at the top of the file
|
868
|
-
*/
|
869
|
-
const contentUnlockBtns = document.querySelectorAll(".unlock-btn");
|
870
|
-
|
871
|
-
/* Check if the course data object has the course number. If not, then add it.
|
872
|
-
* The contentLockData object that lives in local storage stores the course number and keys.
|
873
|
-
*/
|
874
|
-
if (!contentLockData.hasOwnProperty(courseNumber)) {
|
875
|
-
contentLockData[courseNumber] = {
|
876
|
-
keys: {},
|
877
|
-
};
|
878
|
-
}
|
879
|
-
|
880
|
-
// Get key number for each content area
|
881
|
-
lockedContent.forEach((contentArea, contentAreaIndex) => {
|
882
|
-
let contentLockKeyNum = contentArea.getAttribute("data-key");
|
883
|
-
|
884
|
-
// Error check - ensure it is wrapped in parent container
|
885
|
-
let contentLockWrapper = contentArea.parentElement;
|
886
|
-
if (contentLockWrapper) {
|
887
|
-
let hasContentLockWrapper = contentLockWrapper.classList.contains("content-lock-widget");
|
888
|
-
if (!hasContentLockWrapper) {
|
889
|
-
console.log(`Document Error: content lock widget wrapper is missing .content-lock-widget class for widget number ${contentAreaIndex + 1} on this page`);
|
890
|
-
}
|
891
|
-
} else {
|
892
|
-
console.log(`Document Error: content lock widget is missing parent container for widget number ${contentAreaIndex + 1} on this page`);
|
893
|
-
}
|
894
|
-
|
895
|
-
// Error check - ensure it has an instructions <div> as sibling element
|
896
|
-
let lockedContentSibling = contentArea.nextElementSibling;
|
897
|
-
if (lockedContentSibling) {
|
898
|
-
let hasInstructions = lockedContentSibling.classList.contains("instructions");
|
899
|
-
if (!hasInstructions) {
|
900
|
-
console.log(`Document Error: instructions <div> is missing .instructions class for widget number ${contentAreaIndex + 1} on this page`);
|
901
|
-
}
|
902
|
-
} else {
|
903
|
-
console.log(`Document Error: locked content area is missing <div> with instructions for widget number ${contentAreaIndex + 1} on this page`);
|
904
|
-
}
|
905
|
-
|
906
|
-
// Check if key already exists within the course, if it doesn't, add the key
|
907
|
-
if (!contentLockData[courseNumber].keys[contentLockKeyNum]) {
|
908
|
-
// Add the key to the course keys and set it equal to false by default
|
909
|
-
contentLockData[courseNumber].keys[contentLockKeyNum] = false;
|
910
|
-
}
|
911
|
-
});
|
912
|
-
|
913
|
-
// Go through each show/hide button and add click listener
|
914
|
-
contentUnlockBtns.forEach((unlockButton, buttonIndex) => {
|
915
|
-
|
916
|
-
// For each unlock-btn take the text and put the text content into an array for the confirmation window to use
|
917
|
-
unlockBtnContent.push(unlockButton.textContent);
|
918
|
-
|
919
|
-
// Add tab index to each unlock button
|
920
|
-
unlockButton.setAttribute("tabIndex", "0");
|
921
|
-
|
922
|
-
// Applies click event listener (and by default in HTML the keydown event will fire this function) to unlock the content
|
923
|
-
unlockButton.addEventListener("click", () => {
|
924
|
-
handleContentUnlock(unlockButton, buttonIndex, unlockBtnContent, courseNumber)
|
925
|
-
});
|
926
|
-
|
927
|
-
// Apply initial classes based on key status
|
928
|
-
let contentLockKeyNum = lockedContent[buttonIndex].getAttribute("data-key");
|
929
|
-
|
930
|
-
// Make sure contentLockData[courseNumber] is initialized
|
931
|
-
if (!contentLockData[courseNumber]) {
|
932
|
-
contentLockData[courseNumber] = {
|
933
|
-
keys: {},
|
934
|
-
id: 0
|
935
|
-
};
|
936
|
-
}
|
937
|
-
|
938
|
-
if (contentLockData[courseNumber].keys[contentLockKeyNum]) {
|
939
|
-
lockedContent[buttonIndex].classList.add("open");
|
940
|
-
contentLockInstructions[buttonIndex].classList.add("complete");
|
941
|
-
}
|
942
|
-
});
|
943
|
-
|
944
|
-
// Call the checkHiddenContent function initially
|
945
|
-
checkHiddenContent(courseNumber);
|
946
|
-
|
947
|
-
// Save the updated contentLockData object to local storage
|
948
|
-
localStorage.setItem("contentLockData", JSON.stringify(contentLockData));
|
949
|
-
|
950
|
-
}).catch(error => {
|
951
|
-
// Handle the error if needed
|
952
|
-
console.log("Error occurred during applyAttributesToQuiz:", error);
|
953
|
-
});
|
954
|
-
}
|
955
|
-
|
956
|
-
document.addEventListener('DOMContentLoaded', () => {
|
957
|
-
// Your script code here
|
958
|
-
if (contentLockWidgets) { handleContentLockWidget(contentLockWidgets) }
|
959
|
-
});
|
960
|
-
// Flip Card Widget
|
961
|
-
function callFlipCardWidget() {
|
962
|
-
// Loop through each card
|
963
|
-
flipCards.forEach((flipCardGroup) => {
|
964
|
-
|
965
|
-
let flipCard = flipCardGroup.querySelectorAll(".flip-card");
|
966
|
-
let innerFlipCard = flipCardGroup.querySelectorAll(".inner-card");
|
967
|
-
let numOfCardsInGroup = flipCardGroup.children.length;
|
968
|
-
|
969
|
-
// Check to ensure each card has the .flip-card class
|
970
|
-
if (numOfCardsInGroup !== flipCard.length) {
|
971
|
-
console.log("Document error: missing .flip-card class for flip card widget");
|
972
|
-
}
|
973
|
-
// Check to ensure each card has the .inner-card class
|
974
|
-
if (numOfCardsInGroup !== innerFlipCard.length) {
|
975
|
-
console.log("Document error: missing .inner-card class for flip card widget");
|
976
|
-
}
|
977
|
-
|
978
|
-
flipCard.forEach((card) => {
|
979
|
-
let innerFlipCard = card.querySelectorAll(".inner-card");
|
980
|
-
|
981
|
-
innerFlipCard.forEach((innerCard) => {
|
982
|
-
innerCard.setAttribute("tabindex", 0); // Add tab index to allow flip cards to be tabbable
|
983
|
-
innerCard.addEventListener("click", () => {
|
984
|
-
innerCard.offsetHeight; // Force reflow by accessing the offsetHeight property
|
985
|
-
innerCard.classList.toggle("flip");
|
986
|
-
})
|
987
|
-
|
988
|
-
|
989
|
-
// Add a keydownevent event to each card
|
990
|
-
innerCard.addEventListener("keydown", (event) => {
|
991
|
-
if (event.key === "Enter") {
|
992
|
-
// Force reflow by accessing the offsetHeight property
|
993
|
-
innerCard.offsetHeight;
|
994
|
-
innerCard.classList.toggle("flip");
|
995
|
-
}
|
996
|
-
})
|
997
|
-
})
|
998
|
-
})
|
999
|
-
})
|
1000
|
-
}
|
1001
|
-
|
1002
|
-
// If flip cards are present in the file, run this code
|
1003
|
-
if (flipCards) { callFlipCardWidget() }
|
1004
|
-
if (document.querySelector("body[focus-reader]")) {
|
1005
|
-
|
1006
|
-
// Initializations
|
1007
|
-
let focusOn = false;
|
1008
|
-
|
1009
|
-
const fr_contentWrapper = document.querySelector("#content-wrapper");
|
1010
|
-
const fr_thisBody = document.querySelector("body[focus-reader]");
|
1011
|
-
|
1012
|
-
// Add fontAwesome to header
|
1013
|
-
const fr_pageHead = document.querySelector("head");
|
1014
|
-
const fontAweLink = document.createElement("link");
|
1015
|
-
fontAweLink.rel = "stylesheet";
|
1016
|
-
fontAweLink.href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css";
|
1017
|
-
fr_pageHead.append(fontAweLink);
|
1018
|
-
|
1019
|
-
// add intersection observer to head tag
|
1020
|
-
const observerScript = document.createElement("script");
|
1021
|
-
observerScript.setAttribute("src", "https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver");
|
1022
|
-
fr_pageHead.append(observerScript);
|
1023
|
-
|
1024
|
-
// Create Switches container
|
1025
|
-
const fr_switchesContainer = document.createElement("div");
|
1026
|
-
fr_switchesContainer.className = "focus-reader-switches";
|
1027
|
-
fr_thisBody.append(fr_switchesContainer);
|
1028
|
-
|
1029
|
-
// Focus-text container
|
1030
|
-
const fr_focusTextContainer = document.createElement("div");
|
1031
|
-
fr_switchesContainer.append(fr_focusTextContainer);
|
1032
|
-
|
1033
|
-
// Focus-text Icon
|
1034
|
-
const fr_focusTextIcon = document.createElement("p");
|
1035
|
-
fr_focusTextIcon.innerHTML = "Focus Text"
|
1036
|
-
fr_focusTextContainer.append(fr_focusTextIcon);
|
1037
|
-
|
1038
|
-
// info icon
|
1039
|
-
const fr_infoIcon = document.createElement("i");
|
1040
|
-
fr_infoIcon.classList.add("fa-solid");
|
1041
|
-
fr_infoIcon.classList.add("fa-circle-info");
|
1042
|
-
fr_focusTextContainer.append(fr_infoIcon);
|
1043
|
-
|
1044
|
-
// info tooltip
|
1045
|
-
const fr_infoTooltip = document.createElement("span");
|
1046
|
-
const focusReaderTooltipText = "Highlight text as you scroll";
|
1047
|
-
fr_infoTooltip.classList.add("info-tooltip");
|
1048
|
-
fr_infoTooltip.innerHTML = focusReaderTooltipText;
|
1049
|
-
fr_infoIcon.append(fr_infoTooltip);
|
1050
|
-
|
1051
|
-
// Focus-text switch button
|
1052
|
-
const fr_focusTextSwitch = document.createElement("button");
|
1053
|
-
fr_focusTextSwitch.id = "focus-text";
|
1054
|
-
fr_focusTextSwitch.innerHTML = (focusOn) ? `<i class="fas fa-toggle-on"></i>` : `<i class="fas fa-toggle-off"></i>`;
|
1055
|
-
fr_focusTextContainer.append(fr_focusTextSwitch);
|
1056
|
-
|
1057
|
-
// Focus-text logic
|
1058
|
-
fr_focusTextSwitch.addEventListener("click", () => {
|
1059
|
-
if (focusOn) {
|
1060
|
-
focusOn = !focusOn;
|
1061
|
-
fr_contentWrapper.removeAttribute("on");
|
1062
|
-
fr_focusTextSwitch.innerHTML = (focusOn) ? `<i class="fas fa-toggle-on"></i>` : `<i class="fas fa-toggle-off"></i>`;
|
1063
|
-
removeSpans(fr_contentWrapper);
|
1064
|
-
} else {
|
1065
|
-
focusOn = !focusOn;
|
1066
|
-
fr_contentWrapper.setAttribute("on", "");
|
1067
|
-
fr_focusTextSwitch.innerHTML = (focusOn) ? `<i class="fas fa-toggle-on"></i>` : `<i class="fas fa-toggle-off"></i>`;
|
1068
|
-
const elements = document.querySelectorAll("#content-wrapper .content-body :is(p, li, dd, dt, blockquote)");
|
1069
|
-
elements.forEach(element => {
|
1070
|
-
traverseAndWrapTextInSpans(element, focusText);
|
1071
|
-
});
|
1072
|
-
}
|
1073
|
-
});
|
1074
|
-
|
1075
|
-
const options = {
|
1076
|
-
root: null,
|
1077
|
-
rootMargin: '-48.9% 0px',
|
1078
|
-
threshold: 0.00
|
1079
|
-
};
|
1080
|
-
|
1081
|
-
const focusText = new IntersectionObserver(entries => {
|
1082
|
-
entries.forEach(entry => {
|
1083
|
-
if (entry.isIntersecting) {
|
1084
|
-
entry.target.closest("span").classList.add("focus-text");
|
1085
|
-
} else {
|
1086
|
-
entry.target.closest("span").classList.remove("focus-text");
|
1087
|
-
}
|
1088
|
-
});
|
1089
|
-
}, options);
|
1090
|
-
|
1091
|
-
|
1092
|
-
}
|
1093
|
-
|
1094
|
-
function traverseAndWrapTextInSpans(node, focusText) {
|
1095
|
-
if (node.nodeType === Node.TEXT_NODE && node.textContent.trim() !== '') {
|
1096
|
-
// Split the text into words
|
1097
|
-
const words = node.textContent.split(' ');
|
1098
|
-
|
1099
|
-
// Wrap each word in a span
|
1100
|
-
words.forEach(word => {
|
1101
|
-
if (word !== '') {
|
1102
|
-
const span = document.createElement("span");
|
1103
|
-
span.textContent = word + ' '; // Add a space after the word to preserve spacing
|
1104
|
-
|
1105
|
-
// Observe the span
|
1106
|
-
focusText.observe(span);
|
1107
|
-
|
1108
|
-
// Insert the span before the text node
|
1109
|
-
node.parentNode.insertBefore(span, node);
|
1110
|
-
}
|
1111
|
-
});
|
1112
|
-
|
1113
|
-
// Remove the original text node
|
1114
|
-
node.parentNode.removeChild(node);
|
1115
|
-
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
1116
|
-
// Recursively process child nodes
|
1117
|
-
Array.from(node.childNodes).forEach(childNode => {
|
1118
|
-
traverseAndWrapTextInSpans(childNode, focusText);
|
1119
|
-
});
|
1120
|
-
}
|
1121
|
-
}
|
1122
|
-
|
1123
|
-
function removeSpans(node) {
|
1124
|
-
if (node.nodeType === Node.ELEMENT_NODE) {
|
1125
|
-
// If the node is a span with the class 'focus-text', an empty class attribute, is empty, or has no attributes, replace it with a text node
|
1126
|
-
if (node.tagName === 'SPAN' && (node.className === 'focus-text' || node.className === '' || node.textContent.trim() === '' || node.attributes.length === 0)) {
|
1127
|
-
const textNode = document.createTextNode(node.textContent);
|
1128
|
-
node.parentNode.insertBefore(textNode, node);
|
1129
|
-
node.parentNode.removeChild(node);
|
1130
|
-
} else {
|
1131
|
-
// Recursively process child nodes
|
1132
|
-
Array.from(node.childNodes).forEach(childNode => {
|
1133
|
-
removeSpans(childNode);
|
1134
|
-
});
|
1135
|
-
}
|
1136
|
-
}
|
1137
|
-
}
|
1138
|
-
// Change footnotes from 'show' to 'hide'
|
1139
|
-
const footnotes = document.querySelector(".toggle-footnotes");
|
1140
|
-
|
1141
|
-
if (footnotes) {
|
1142
|
-
footnotes.addEventListener("click", () => {
|
1143
|
-
footnotes.innerHTML = (footnotes.innerHTML === "[Show Footnotes]") ? "[Hide Footnotes]" : "[Show Footnotes]";
|
1144
|
-
})
|
1145
|
-
}
|
1146
|
-
// Add h5p resizer dynamically
|
1147
|
-
h5pResizer.setAttribute("src", "https://pima.h5p.com/js/h5p-resizer.js");
|
1148
|
-
h5pResizer.setAttribute("charset", "UTF-8");
|
1149
|
-
h5pResizer.setAttribute("defer", "");
|
1150
|
-
|
1151
|
-
// If any iframes are detected run this function
|
1152
|
-
function checkIframes() {
|
1153
|
-
h5pIframes.forEach(function (h5pIframe) {
|
1154
|
-
const src = h5pIframe.getAttribute("src");
|
1155
|
-
if (src.includes("/d2l/common/dialogs/quickLink") || src.includes("https://pima.h5p.com/content") || src.includes("h5p") && !h5pResizerExists) {
|
1156
|
-
docHead.appendChild(h5pResizer);
|
1157
|
-
}
|
1158
|
-
});
|
1159
|
-
}
|
1160
|
-
|
1161
|
-
// Call function if iframes exist
|
1162
|
-
if (h5pIframes) { checkIframes() }
|
1163
|
-
|
1164
|
-
|
1165
|
-
// Helper JS for Responsive Tables
|
1166
|
-
const initResponsiveTables = () => {
|
1167
|
-
for (let table = 0; table < tables.length; table++) {
|
1168
|
-
let headertext = [],
|
1169
|
-
headers = tables[table].querySelectorAll(".display table th, table.display th, .display-lg table th, table.display-lg th"),
|
1170
|
-
tablebody = tables[table].querySelector(".display table tbody, table.display tbody, .display-lg table tbody, table.display-lg tbody");
|
1171
|
-
for (let header = 0; header < headers.length; header++) {
|
1172
|
-
let current = headers[header];
|
1173
|
-
headertext.push(current.textContent.replace(/\r?\n|\r/, ""));
|
1174
|
-
}
|
1175
|
-
for (let y = 0, row; row = tablebody.rows[y]; y++) {
|
1176
|
-
for (let j = 0, col; col = row.cells[j]; j++) {
|
1177
|
-
col.setAttribute("data-th", headertext[j]);
|
1178
|
-
}
|
1179
|
-
}
|
1180
|
-
}
|
1181
|
-
}
|
1182
|
-
if (tables) {
|
1183
|
-
initResponsiveTables();
|
1184
|
-
}
|
1185
|
-
// Call function with jQuery scripts
|
1186
|
-
const callJquery = () => {
|
1187
|
-
// Toggle Button's Arrow Right Points Down on Click
|
1188
|
-
$('.arrow-right').on('click', function () {
|
1189
|
-
$(this).toggleClass('arrow-down');
|
1190
|
-
});
|
1191
|
-
// TOOLTIP
|
1192
|
-
// Allows Screen readers to toggle a tooltip on click and to say if the tooltip is collapsed or expanded.
|
1193
|
-
$(".tooltip").click(function () {
|
1194
|
-
$(this).children(".tip-hover").toggle();
|
1195
|
-
if ($(this).children(".tip-hover").is(':visible')) {
|
1196
|
-
$(this).attr('aria-expanded', 'true');
|
1197
|
-
$(this).removeClass('hidden');
|
1198
|
-
} else {
|
1199
|
-
$(this).attr('aria-expanded', 'false');
|
1200
|
-
$(this).addClass('hidden');
|
1201
|
-
}
|
1202
|
-
});
|
1203
|
-
let start = 999;
|
1204
|
-
$('.tooltip').each(function (i) {
|
1205
|
-
$(this).css('z-index', start--);
|
1206
|
-
});
|
1207
|
-
$(".tooltip .video-container").parent().css("width", "450px");
|
1208
|
-
}
|
1209
|
-
callJquery();
|
1210
|
-
// This is called by anchor links via onlick="" in the HTML
|
1211
|
-
// Added because default anchor links don't work on all browsers using D2L
|
1212
|
-
const jumpTo = (anchor) => {
|
1213
|
-
document.getElementById(anchor).scrollIntoView();
|
1214
|
-
}
|
1215
|
-
const sliderWidgets = document.querySelectorAll(".slider-widget");
|
1216
|
-
const slideHeight = 300;
|
1217
|
-
|
1218
|
-
// Function to check if all direct children of each slider have the 'slider-item' class
|
1219
|
-
const checkSliderChildren = () => {
|
1220
|
-
[...sliderWidgets].forEach((slider) => {
|
1221
|
-
// Check if every direct child of the slider has the 'slider-item' class
|
1222
|
-
let sliderChildren = [...slider.children].every(child => child.classList.contains("slider-item"));
|
1223
|
-
|
1224
|
-
// Log an error message if any direct child does not have the 'slider-item' class
|
1225
|
-
if (!sliderChildren) {
|
1226
|
-
console.log(`Document error: not all direct children of .slider have the .slider-item class.`);
|
1227
|
-
}
|
1228
|
-
});
|
1229
|
-
};
|
1230
|
-
checkSliderChildren();
|
1231
|
-
|
1232
|
-
// Function to hide all slides except the active one and deactivate all dots except the active one
|
1233
|
-
const hideSlidesAndDots = (sliderItems, sliderDots, newIndex) => {
|
1234
|
-
// Iterate over each slider item
|
1235
|
-
sliderItems.forEach((item, index) => {
|
1236
|
-
// Set the display style based on whether the item is the active slide
|
1237
|
-
item.style.display = index === newIndex ? "block" : "none";
|
1238
|
-
});
|
1239
|
-
// Iterate over each dot
|
1240
|
-
sliderDots.forEach((sliderDot, index) => {
|
1241
|
-
// Toggle the 'active' class based on whether the dot corresponds to the active slide
|
1242
|
-
sliderDot.classList.toggle("active", index === newIndex);
|
1243
|
-
});
|
1244
|
-
};
|
1245
|
-
|
1246
|
-
// Function to update the display of slides and dots when a new slide is selected
|
1247
|
-
const updateSlide = (sliderItems, sliderDots, newIndex) => {
|
1248
|
-
// Call the function to hide all slides and deactivate all dots except for the active ones
|
1249
|
-
hideSlidesAndDots(sliderItems, sliderDots, newIndex);
|
1250
|
-
};
|
1251
|
-
|
1252
|
-
// Function to create a button element with the specified class name
|
1253
|
-
const createSliderButton = (className) => {
|
1254
|
-
// Create a new button element
|
1255
|
-
const sliderButton = document.createElement("button");
|
1256
|
-
// Set the class name of the button
|
1257
|
-
sliderButton.className = className;
|
1258
|
-
// Set tabindex to -1 to skip when tabbing
|
1259
|
-
sliderButton.setAttribute("tabindex", "-1");
|
1260
|
-
// Return the created button
|
1261
|
-
return sliderButton;
|
1262
|
-
};
|
1263
|
-
|
1264
|
-
// Function to vertically center the content of a slide if it is short and does not contain videos
|
1265
|
-
const totalSlideContentHeight = (sliderItem) => {
|
1266
|
-
// Initialize a variable to keep track of the total height of the content
|
1267
|
-
let totalContentHeight = 0;
|
1268
|
-
// Iterate over each child element of the slider item
|
1269
|
-
for (let child of sliderItem.children) {
|
1270
|
-
// Add the height of the child to the total content height
|
1271
|
-
totalContentHeight += child.offsetHeight;
|
1272
|
-
}
|
1273
|
-
// Check if the total content height is less than 300px and the item does not contain a video
|
1274
|
-
if (totalContentHeight < slideHeight && !sliderItem.querySelector(".media-container")) {
|
1275
|
-
// Create a wrapper div to contain the content
|
1276
|
-
const sliderWrapper = document.createElement("div");
|
1277
|
-
// Move each child of the slider item into the wrapper
|
1278
|
-
while (sliderItem.firstChild) {
|
1279
|
-
sliderWrapper.appendChild(sliderItem.firstChild);
|
1280
|
-
}
|
1281
|
-
// Append the wrapper to the slider item
|
1282
|
-
sliderItem.appendChild(sliderWrapper);
|
1283
|
-
// Add the 'short-content' class to the slider item to apply vertical centering
|
1284
|
-
sliderItem.classList.add("short-content");
|
1285
|
-
}
|
1286
|
-
};
|
1287
|
-
|
1288
|
-
// Initialize each slider with navigation buttons, dots, and keyboard navigation
|
1289
|
-
[...sliderWidgets].forEach((slider, index) => {
|
1290
|
-
// Set accessibility attributes for the slider
|
1291
|
-
slider.setAttribute("tabindex", "0");
|
1292
|
-
slider.setAttribute("role", "group");
|
1293
|
-
|
1294
|
-
// Create a hidden label for the slider for screen readers
|
1295
|
-
const sliderLabel = document.createElement("span");
|
1296
|
-
sliderLabel.id = `slider-label-${index + 1}`;
|
1297
|
-
sliderLabel.textContent = "Interactive Slider";
|
1298
|
-
sliderLabel.hidden = true;
|
1299
|
-
// Insert the label at the beginning of the slider
|
1300
|
-
slider.prepend(sliderLabel);
|
1301
|
-
|
1302
|
-
// Associate the label with the slider for screen readers
|
1303
|
-
slider.setAttribute("aria-labelledby", `slider-label-${index + 1}`);
|
1304
|
-
|
1305
|
-
// Initialize the current index for the slider
|
1306
|
-
let currentSlide = 0;
|
1307
|
-
// Select all slider items within the current slider
|
1308
|
-
const sliderItems = [...slider.querySelectorAll(".slider-item")];
|
1309
|
-
// Create a div to contain the dots for navigation
|
1310
|
-
const sliderDotsBar = document.createElement("div");
|
1311
|
-
sliderDotsBar.className = "slider-dots-bar";
|
1312
|
-
// Append the dots bar to the slider
|
1313
|
-
slider.appendChild(sliderDotsBar);
|
1314
|
-
// Initialize an array to keep track of the dots
|
1315
|
-
let sliderDots = [];
|
1316
|
-
|
1317
|
-
// Create dots for each slide and set up click events to navigate to the slide
|
1318
|
-
sliderItems.forEach((sliderItem, i) => {
|
1319
|
-
// Create a span element to represent a dot
|
1320
|
-
const sliderDot = document.createElement("span");
|
1321
|
-
sliderDot.className = "slider-dot";
|
1322
|
-
// Add a click event listener to the dot
|
1323
|
-
sliderDot.addEventListener("click", () => {
|
1324
|
-
// Update the current index to the index of the clicked dot
|
1325
|
-
currentSlide = i;
|
1326
|
-
// Call the function to update the slide display
|
1327
|
-
hideSlidesAndDots(sliderItems, sliderDots, currentSlide);
|
1328
|
-
// Ensure the current slide is displayed
|
1329
|
-
sliderItems[currentSlide].style.display = "block";
|
1330
|
-
// Add the 'active' class to the current dot
|
1331
|
-
sliderDot.classList.add("active");
|
1332
|
-
// Call the function to align the slide content if necessary
|
1333
|
-
totalSlideContentHeight(sliderItems[currentSlide]);
|
1334
|
-
});
|
1335
|
-
// Append the dot to the dots bar
|
1336
|
-
sliderDotsBar.appendChild(sliderDot);
|
1337
|
-
// Add the dot to the array of dots
|
1338
|
-
sliderDots.push(sliderDot);
|
1339
|
-
|
1340
|
-
// Hide the slide if it's not the current one
|
1341
|
-
sliderItem.style.display = i !== currentSlide ? "none" : "block";
|
1342
|
-
// If it's the current slide, add the 'active' class to the corresponding dot
|
1343
|
-
if (i === currentSlide) {
|
1344
|
-
sliderDot.classList.add("active");
|
1345
|
-
}
|
1346
|
-
});
|
1347
|
-
|
1348
|
-
// Create navigation buttons and set up click events to navigate between slides
|
1349
|
-
const sliderLeftArrow = createSliderButton("slider-arrow icon-chevron-left");
|
1350
|
-
const sliderRightArrow = createSliderButton("slider-arrow icon-chevron-right");
|
1351
|
-
// Append the navigation buttons to the slider
|
1352
|
-
slider.appendChild(sliderLeftArrow);
|
1353
|
-
slider.appendChild(sliderRightArrow);
|
1354
|
-
|
1355
|
-
// Add a click event listener to the left arrow button
|
1356
|
-
sliderLeftArrow.addEventListener("click", () => {
|
1357
|
-
// Update the current index to the previous slide, wrapping around if necessary
|
1358
|
-
currentSlide = currentSlide > 0 ? currentSlide - 1 : sliderItems.length - 1;
|
1359
|
-
// Call the function to update the slide display
|
1360
|
-
updateSlide(sliderItems, sliderDots, currentSlide);
|
1361
|
-
// Call the function to align the slide content if necessary
|
1362
|
-
totalSlideContentHeight(sliderItems[currentSlide]);
|
1363
|
-
});
|
1364
|
-
|
1365
|
-
// Add a click event listener to the right arrow button
|
1366
|
-
sliderRightArrow.addEventListener("click", () => {
|
1367
|
-
// Update the current index to the next slide, wrapping around if necessary
|
1368
|
-
currentSlide = currentSlide < sliderItems.length - 1 ? currentSlide + 1 : 0;
|
1369
|
-
// Call the function to update the slide display
|
1370
|
-
updateSlide(sliderItems, sliderDots, currentSlide);
|
1371
|
-
// Call the function to align the slide content if necessary
|
1372
|
-
totalSlideContentHeight(sliderItems[currentSlide]);
|
1373
|
-
});
|
1374
|
-
|
1375
|
-
// Function to update the label text when the slide changes
|
1376
|
-
function updateSliderLabel() {
|
1377
|
-
// Update the text content of the label to reflect the current slide number
|
1378
|
-
sliderLabel.textContent = `Interactive Slide: slide ${currentSlide + 1} of ${sliderItems.length}`;
|
1379
|
-
}
|
1380
|
-
|
1381
|
-
// Set up keyboard navigation for the slider
|
1382
|
-
slider.addEventListener("keydown", (event) => {
|
1383
|
-
// Handle the left and right arrow keys
|
1384
|
-
switch (event.key) {
|
1385
|
-
case "ArrowLeft":
|
1386
|
-
// Update the current index to the previous slide, wrapping around if necessary
|
1387
|
-
currentSlide = currentSlide > 0 ? currentSlide - 1 : sliderItems.length - 1;
|
1388
|
-
break;
|
1389
|
-
case "ArrowRight":
|
1390
|
-
// Update the current index to the next slide, wrapping around if necessary
|
1391
|
-
currentSlide = currentSlide < sliderItems.length - 1 ? currentSlide + 1 : 0;
|
1392
|
-
break;
|
1393
|
-
default:
|
1394
|
-
// If any other key is pressed, do nothing and return
|
1395
|
-
return;
|
1396
|
-
}
|
1397
|
-
// Call the function to update the slide display
|
1398
|
-
updateSlide(sliderItems, sliderDots, currentSlide);
|
1399
|
-
// Call the function to align the slide content if necessary
|
1400
|
-
totalSlideContentHeight(sliderItems[currentSlide]);
|
1401
|
-
// Prevent the default action for the keydown event
|
1402
|
-
event.preventDefault();
|
1403
|
-
// Call the function to update the label text
|
1404
|
-
updateSliderLabel();
|
1405
|
-
// Focus the slider widget
|
1406
|
-
slider.focus();
|
1407
|
-
});
|
1408
|
-
|
1409
|
-
// Variables to store the starting and ending X coordinates of a touch event
|
1410
|
-
let touchStartX = 0;
|
1411
|
-
let touchEndX = 0;
|
1412
|
-
|
1413
|
-
// Event listener for the 'touchstart' event, which fires when a touch point is placed on the touch surface
|
1414
|
-
slider.addEventListener("touchstart", (e) => {
|
1415
|
-
// Store the X coordinate of the touch point when the touch starts
|
1416
|
-
touchStartX = e.changedTouches[0].screenX;
|
1417
|
-
}, false);
|
1418
|
-
|
1419
|
-
// Event listener for the 'touchend' event, which fires when a touch point is removed from the touch surface
|
1420
|
-
slider.addEventListener("touchend", (e) => {
|
1421
|
-
// Store the X coordinate of the touch point when the touch ends
|
1422
|
-
touchEndX = e.changedTouches[0].screenX;
|
1423
|
-
// Call the function to handle the swipe gesture
|
1424
|
-
sliderSwipe();
|
1425
|
-
}, false);
|
1426
|
-
|
1427
|
-
// Function to handle the swipe gesture
|
1428
|
-
const sliderSwipe = () => {
|
1429
|
-
// Calculate the difference between the starting and ending X coordinates
|
1430
|
-
let diffX = touchEndX - touchStartX;
|
1431
|
-
|
1432
|
-
// Check if the absolute value of the difference is greater than a minimum threshold (50 pixels)
|
1433
|
-
if (Math.abs(diffX) > 50) { // Minimum distance for a swipe
|
1434
|
-
// Determine the direction of the swipe based on the sign of the difference
|
1435
|
-
if (diffX > 0) {
|
1436
|
-
// If the difference is positive, the user swiped to the left
|
1437
|
-
// Update the current slide index to the previous slide, wrapping around if necessary
|
1438
|
-
currentSlide = currentSlide > 0 ? currentSlide - 1 : sliderItems.length - 1;
|
1439
|
-
} else {
|
1440
|
-
// If the difference is negative, the user swiped to the right
|
1441
|
-
// Update the current slide index to the next slide, wrapping around if necessary
|
1442
|
-
currentSlide = currentSlide < sliderItems.length - 1 ? currentSlide + 1 : 0;
|
1443
|
-
}
|
1444
|
-
// Call the function to update the slide display
|
1445
|
-
updateSlide(sliderItems, sliderDots, currentSlide);
|
1446
|
-
// Call the function to align the slide content if necessary
|
1447
|
-
totalSlideContentHeight(sliderItems[currentSlide]);
|
1448
|
-
// Refocus the slider widget to maintain accessibility
|
1449
|
-
slider.focus();
|
1450
|
-
}
|
1451
|
-
}
|
1452
|
-
});
|
1453
|
-
|
1454
|
-
// Function to check if the slider contains all required elements for navigation
|
1455
|
-
const checkSliderNavs = (slider, index) => {
|
1456
|
-
// Select the navigation controls within the context of the current slider
|
1457
|
-
const sliderNextButton = slider.querySelector(".icon-chevron-right");
|
1458
|
-
const sliderPrevButton = slider.querySelector(".icon-chevron-left");
|
1459
|
-
const sliderDotsBar = slider.querySelector(".slider-dots-bar");
|
1460
|
-
|
1461
|
-
// Check if the navigation controls are present
|
1462
|
-
if (!sliderNextButton) {
|
1463
|
-
console.log(`Document error: next button is missing for slider ${index + 1}.`);
|
1464
|
-
}
|
1465
|
-
if (!sliderPrevButton) {
|
1466
|
-
console.log(`Document error: previous button is missing for slider ${index + 1}.`);
|
1467
|
-
}
|
1468
|
-
if (!sliderDotsBar) {
|
1469
|
-
console.log(`Document error: dots bar is missing for slider ${index + 1}.`);
|
1470
|
-
}
|
1471
|
-
};
|
1472
|
-
|
1473
|
-
// Call the function for each slider to perform the check
|
1474
|
-
[...sliderWidgets].forEach((slider, index) => {
|
1475
|
-
checkSliderNavs(slider, index);
|
1476
|
-
});
|
1477
|
-
|
1478
|
-
// Check if slider items are empty
|
1479
|
-
const checkEmptySliderItems = () => {
|
1480
|
-
[...sliderWidgets].forEach((slider, sliderIndex) => {
|
1481
|
-
// Get all .slider-item children of the current slider
|
1482
|
-
let sliderItems = [...slider.querySelectorAll(".slider-item")];
|
1483
|
-
|
1484
|
-
// Check each .slider-item to see if it is empty
|
1485
|
-
sliderItems.forEach((item, itemIndex) => {
|
1486
|
-
// An element is considered empty if it has no children, or all its children are either comment nodes or text nodes with only whitespace
|
1487
|
-
const isEmpty = [...item.childNodes].every(node => {
|
1488
|
-
return node.nodeType === Node.COMMENT_NODE || (node.nodeType === Node.TEXT_NODE && !node.textContent.trim());
|
1489
|
-
});
|
1490
|
-
|
1491
|
-
// Log an error message if the .slider-item is empty
|
1492
|
-
if (isEmpty) {
|
1493
|
-
console.log(`Document error: .slider-item at index ${itemIndex} in slider ${sliderIndex + 1} is empty.`);
|
1494
|
-
}
|
1495
|
-
});
|
1496
|
-
});
|
1497
|
-
};
|
1498
|
-
checkEmptySliderItems();
|
1499
|
-
// Array for all themes that require theme specific js
|
1500
|
-
const customJsThemes = ["ecn", "hrs", "ss"];
|
1501
|
-
|
1502
|
-
//Search links for theme styles
|
1503
|
-
const themeJsCheck = () => {
|
1504
|
-
|
1505
|
-
const links = document.querySelectorAll("link");
|
1506
|
-
|
1507
|
-
links.forEach((link) => {
|
1508
|
-
const href = link.getAttribute("href");
|
1509
|
-
customJsThemes.forEach((theme) => {
|
1510
|
-
// If theme requires custom js, run addThemeScript()
|
1511
|
-
if (href && href.includes(`/${theme}/styles.css`)) {
|
1512
|
-
addThemeScript(theme);
|
1513
|
-
}
|
1514
|
-
});
|
1515
|
-
});
|
1516
|
-
|
1517
|
-
// Adds a script to the head for that particular theme
|
1518
|
-
function addThemeScript(theme) {
|
1519
|
-
let themeScript = document.createElement("script");
|
1520
|
-
// URL references theme-specific js module from CDN
|
1521
|
-
themeScript.src = `https://cdn.jsdelivr.net/npm/@pimaonline/pimaonline-themepack/dist/js/themes/${theme}.js`;
|
1522
|
-
document.head.appendChild(themeScript);
|
1523
|
-
}
|
1524
|
-
}
|
1525
|
-
|
1526
|
-
themeJsCheck()
|
1527
|
-
// Toggle footnotes
|
1528
|
-
const toggleBtns = document.querySelectorAll(".toggle-btn, .toggle-footnotes");
|
1529
|
-
|
1530
|
-
if (toggleBtns) {
|
1531
|
-
if (document.querySelector(".toggle-btn") || document.querySelector(".toggle-footnotes")) {
|
1532
|
-
for (let toggleBtn = 0; toggleBtn < toggleBtns.length; toggleBtn++) {
|
1533
|
-
// Add tabindex
|
1534
|
-
toggleBtns[toggleBtn].setAttribute("tabindex", "0");
|
1535
|
-
// Show/hide on click
|
1536
|
-
toggleBtns[toggleBtn].addEventListener("click", () => {
|
1537
|
-
if (toggleBtns[toggleBtn].nextElementSibling) {
|
1538
|
-
toggleBtns[toggleBtn].nextElementSibling.classList.toggle("show");
|
1539
|
-
}
|
1540
|
-
})
|
1541
|
-
|
1542
|
-
// Show/hide on enter for users who use tab
|
1543
|
-
toggleBtns[toggleBtn].addEventListener("keydown", (enter) => {
|
1544
|
-
if (enter.keyCode === 13) {
|
1545
|
-
if (toggleBtns[toggleBtn].nextElementSibling) {
|
1546
|
-
toggleBtns[toggleBtn].nextElementSibling.classList.toggle("show");
|
1547
|
-
}
|
1548
|
-
}
|
1549
|
-
})
|
1550
|
-
}
|
1551
|
-
}
|
1552
|
-
}
|
1
|
+
(()=>{"use strict";var e={2152:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.discardAttributes=void 0,t.discardAttributes=(e,...t)=>{t.forEach((t=>e.removeAttribute(t)))}},7080:(e,t,o)=>{o(3271),o(6381),o(1034),o(1645),o(71),o(4e3),o(161),o(3982),o(8795),o(9308),o(7721),o(7121),o(81),o(4786),o(4407),o(1952),o(7174),o(6433),o(4709),o(4393),o(4019),o(4262),o(3258),o(2692),o(9191),o(1424),o(3966)},3271:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(6079),r=[{class:"bi-",cdn:new URL("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css")},{class:"ri-",cdn:new URL("https://cdn.jsdelivr.net/npm/remixicon@4.0.1/fonts/remixicon.css")}];document.querySelectorAll(r.map((e=>`[class*='${e.class}']`)).join(", ")).length>0&&r.forEach((e=>{var t;if(document.querySelector(`[class*='${e.class}']`)){const o=null!==(t=null===n.docHead||void 0===n.docHead?void 0:n.docHead.querySelector("meta[name='viewport']"))&&void 0!==t?t:null;o||console.warn("Document error: could not find viewport meta tag");const r=document.createElement("link");r.setAttribute("href",e.cdn.toString()),r.setAttribute("rel","stylesheet"),o&&(null===n.docHead||void 0===n.docHead||n.docHead.insertBefore(r,o.nextSibling))}}))},6381:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(6079);n.contentWrapper?n.contentWrapper.setAttribute("role","main"):n.contentWrapper||console.log("Document error: does not contain #content-wrapper."),n.secondColumn&&(n.secondColumn.setAttribute("role","region"),n.secondColumn.setAttribute("aria-label","Second column")),n.thirdColumn&&(n.thirdColumn.setAttribute("role","region"),n.thirdColumn.setAttribute("aria-label","Third column"))},1034:()=>{const e=document.querySelectorAll(".arrow-right");e.length>0&&e.forEach((e=>{(e=>{e.addEventListener("click",(t=>{e.classList.toggle("arrow-down")})),e.addEventListener("keydown",(t=>{"Enter"!==t.key&&" "!==t.key||e.classList.toggle("arrow-down")}))})(e)}))},1645:()=>{const e=document.querySelectorAll("dl.vocab-list dt"),t=(document.querySelectorAll("dl.vocab-list dd"),document.querySelectorAll("dl.vocab-list")),o=(document.querySelectorAll("dl.vocab-list button"),e=>{e.classList.toggle("active");let t=e.nextElementSibling instanceof HTMLElement?e.nextElementSibling:null;for(t&&"block"===t.style.display?t.style.display="none":t&&(t.style.display="block");t&&t.nextElementSibling;){const e=t.nextElementSibling;if(e instanceof HTMLElement){if(t=e,!t||"DD"!==t.tagName)break;"block"===t.style.display?t.style.display="none":t.style.display="block"}}}),n=e=>{if(e){let t=e.querySelectorAll("dd"),o=e.querySelectorAll("dt");t.forEach((e=>{e.style.display="none"})),o.forEach((e=>{e.classList.remove("active")}))}};t.length>0&&(()=>{t.forEach((e=>{let t=0,o=0,r=!1;for(let n=0;n<e.children.length;n++)"DT"==e.children[n].tagName&&(e.children[n].setAttribute("tabindex","0"),t++),"DD"==e.children[n].tagName&&o++,"BUTTON"==e.children[n].tagName&&(r=!0);if(t<1&&console.warn("Document error: no terms found in vocab list"),o<1&&console.warn("Document error: no definitions found in vocab list"),t>o&&console.warn("Document error: more terms than definitions in vocab list"),t>=2&&o>=2)if(r){let t=e.querySelector("button");null==t||t.addEventListener("click",(()=>n(e)))}else{const t=document.createElement("button");t.textContent="Close All",t.addEventListener("click",(()=>n(e))),e.appendChild(t)}else{for(let t=0;t<e.children.length;t++)"BUTTON"==e.children[t].tagName&&(r=!0);if(r){let t=e.querySelector("button");t&&(t.style.display="none")}}}));for(let t=0;t<e.length;t++)e[t].addEventListener("click",(n=>{o(e[t])})),e[t].addEventListener("keydown",(n=>{"Enter"===n.key&&o(e[t])}))})()},71:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.cleanMarkup=void 0;const n=o(6079),r=o(2152);t.cleanMarkup=()=>{n.rolePres&&n.rolePres.forEach((e=>e.removeAttribute("role"))),document.querySelectorAll(l.join(",")).forEach((e=>{(0,r.discardAttributes)(e,...i)})),n.jqueryScript&&n.jqueryScript.remove()};const l=["table","thead","tbody","tr","th","td"],i=["cellspacing","cellpadding","width","style"];var c;(n.rolePres&&n.rolePres.length>0||(c=i,l.some((e=>c.some((t=>null!==document.querySelector(`${e}[${t}]`))))))||n.jqueryScript)&&(0,t.cleanMarkup)()},4e3:()=>{const e=document.querySelectorAll(".content-lock-widget"),t=document.querySelectorAll(".locked-content"),o=document.querySelectorAll(".instructions"),n=[],r=e=>{const r=(e,n,r)=>{u[n].keys[e]=!0,u[n].keys[e]?(t[r].classList.add("open"),o[r].classList.add("complete")):(t[r].classList.remove("open"),o[r].classList.remove("complete")),localStorage.setItem("contentLockData",JSON.stringify(u)),i(n)},l=(e,t)=>{let o=e.querySelector(".error-container"),n=document.createElement("span");o&&(o.innerHTML="",o.appendChild(n)),n.textContent="",setTimeout((function(){n.textContent=t,o&&o.appendChild(n)}),200)},i=e=>{t.forEach(((n,r)=>{let l=n.getAttribute("data-key");if(l){let n=parseInt(l,10);u[e].keys[n]?(t[r].classList.add("open"),o[r].classList.add("complete")):(t[r].classList.remove("open"),o[r].classList.remove("complete"))}}))},c=window.parent.location.href.match(/\/content\/(\d+)/),s=c?c[1]:null,a=["a","b","c","d","e","f","g","h","i"],d=localStorage.getItem("contentLockData");let u=d?JSON.parse(d):{};if(s){const c=parseInt(s,10);window.addEventListener("storage",(e=>{s&&((e,t)=>{e&&"contentLockData"===e.key&&e.newValue&&(u=JSON.parse(e.newValue),i(t))})(e,c)}));let d=1;e.forEach(((e,o)=>{let n=e.querySelector(".quiz form");if(t){if(n){let t=e.querySelector(".locked-content"),r=e.querySelector(".quiz .correct-answer");if(r&&(t||console.warn(`Document error: missing the locked-content class for widget number ${o+1} on this page`),r||console.warn(`Document error: missing correct-answer for content lock quiz for widget number ${o+1} on this page`),n.id=`quiz${d}`,!e.querySelector(".error-container"))){let t=document.createElement("div");t.classList.add("error-container");let n=e.querySelector("input[value='Submit']");n?n.insertAdjacentHTML("beforebegin",t.outerHTML):console.warn(`Document error: quiz is missing an input with value 'Submit' for widget number ${o+1} on this page.`)}}d++}else e.querySelector(".unlock-btn")||console.warn(`Document error: locked content area (that is not using a quiz) is missing <a> with .unlock-btn for widget number ${o+1} on this page.`)})),new Promise(((e,t)=>{let o=document.querySelectorAll(".quiz form");o&&o.forEach((e=>{e.querySelectorAll("input").forEach(((e,t)=>{e.getAttribute("value")?"Submit"==e.getAttribute("value")&&(e.setAttribute("type","button"),e.classList.add("unlock-btn")):(e.setAttribute("value",a[t]),e.setAttribute("name","options"),e.setAttribute("type","radio"))}))})),e()})).then((()=>{(()=>{const e=new Map;t.forEach((t=>{const o=t.getAttribute("data-key");if(o)if(e.has(o)){const t=e.get(o)||0;e.set(o,t+1)}else e.set(o,1)}));let o=!1;e.forEach(((e,t)=>{e>1&&(console.warn(`Document error: multiple quizzes found with the same data key (${t})`),o=!0)}))})();const e=document.querySelectorAll(".unlock-btn");u.hasOwnProperty(s)||(u[c]={keys:{}}),t.forEach(((e,t)=>{let o=e.getAttribute("data-key");if(o){let n=parseInt(o,10),r=e.parentElement;r?r.classList.contains("content-lock-widget")||console.warn(`Document error: content lock widget wrapper is missing .content-lock-widget class for widget number ${t+1} on this page`):console.warn(`Document error: content lock widget is missing parent container for widget number ${t+1} on this page`);let l=e.nextElementSibling;if(l)if(l.classList.contains("instructions")&&"DIV"===l.tagName){if(!l.querySelector(".unlock-btn")){let e=l.nextElementSibling;e?e.classList.contains("quiz")||console.warn(`Document error: missing .quiz class after locked-content ${t+1} on this page`):console.warn(`Document error: missing .unlock-btn class inside instructions ${t+1} on this page`)}}else console.warn(`Document error: instructions <div> is missing .instructions class for widget number ${t+1} on this page`);else console.warn(`Document error: locked content area is missing <div> with instructions for widget number ${t+1} on this page`);u[c].keys[n]||(u[c].keys[n]=!1)}else o||console.warn(`Document error: missing data-key for locked content for widget number ${t+1} on this page`)})),e.forEach(((e,i)=>{let s=t[i].getAttribute("data-key");if(s){let a=parseInt(s,10);null!==e.textContent&&n.push(e.textContent),e.setAttribute("tabIndex","0"),e.addEventListener("click",(()=>((e,t,o,n,i)=>{let c=!1,s=!1;"INPUT"===t.tagName&&(c=!0),c?(s=(e=>{let t=document.getElementById(`quiz${e}`);if(t){let e=t.querySelector("input[name='options']:checked"),o=t.querySelector("input.correct-answer"),n="";return e?o?e.value===o.value?(alert("Correct response"),!0):(n="Incorrect response. Please try again.",l(t,n),!1):(console.warn("Document error: no .correct-answer class applied"),!1):(n="Please select an option before submitting.",l(t,n),!1)}return console.warn("Document error: quiz id for content lock quiz, not being applied"),!1})(e),s&&r(e,i,o)):(s=window.confirm(`Please confirm: ${n[o]}`),s&&r(e,i,o))})(a,e,i,n,c))),u[c]||(u[c]={keys:{},id:0}),u[c].keys[a]&&(t[i].classList.add("open"),o[i].classList.add("complete"))}})),i(c),localStorage.setItem("contentLockData",JSON.stringify(u))})).catch((e=>{console.warn("Document error: error occurred during applyAttributesToQuiz:",e)}))}else console.warn("Document error: No course number found")};document.addEventListener("DOMContentLoaded",(()=>{e.length>0&&r(e)}))},161:()=>{const e=document.querySelectorAll(".flip-card-widget, .flip-card-group");e.length>0&&e.forEach((e=>{let t=e.querySelectorAll(".flip-card"),o=e.querySelectorAll(".inner-card"),n=e.children.length;n!==t.length&&console.warn("Document error: missing .flip-card class for flip card widget"),n!==o.length&&console.warn("Document error: missing .inner-card class for flip card widget"),t.forEach((e=>{e.querySelectorAll(".inner-card").forEach((e=>{e.setAttribute("tabindex","0"),e.addEventListener("click",(()=>{e.offsetHeight,e.classList.toggle("flip")})),e.addEventListener("keydown",(t=>{"Enter"===t.key&&(e.offsetHeight,e.classList.toggle("flip"))}))}))}))}))},3982:()=>{if(document.querySelector("body[focus-reader]")){let o=!1;const n=document.querySelector("#content-wrapper"),r=document.querySelector("body[focus-reader]"),l=document.querySelector("head"),i=document.createElement("link");i.rel="stylesheet",i.href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css",l&&l.append(i);const c=document.createElement("script");c.src="https://www.jsdelivr.com/package/npm/intersection-observer",l&&l.append(c);const s=document.createElement("div");s.className="focus-reader-switches",r&&r.append(s);const a=document.createElement("div");s.append(a);const d=document.createElement("p");d.innerHTML="Focus Text",a.append(d);const u=document.createElement("i");u.classList.add("fa-solid"),u.classList.add("fa-circle-info"),a.append(u);const m=document.createElement("span");m.classList.add("info-tooltip"),m.innerHTML="Highlight text as you scroll",u.append(m);const p=document.createElement("button");p.id="focus-text",p.innerHTML=o?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>',a.append(p),p.addEventListener("click",(()=>{o?(o=!o,n&&(n.removeAttribute("on"),p.innerHTML=o?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>',t(n))):(o=!o,n&&(n.setAttribute("on",""),p.innerHTML=o?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>',document.querySelectorAll("#content-wrapper .content-body :is(p, li, dd, dt, blockquote)").forEach((t=>{e({node:t,focusText:g})}))))}));const g=new IntersectionObserver((e=>{e.forEach((e=>{var t,o;e.isIntersecting?null===(t=e.target.closest("span"))||void 0===t||t.classList.add("focus-text"):null===(o=e.target.closest("span"))||void 0===o||o.classList.remove("focus-text")}))}),{root:null,rootMargin:"-48.9% 0px",threshold:0})}function e({node:t,focusText:o}){var n,r;t.nodeType===Node.TEXT_NODE&&""!==(null===(n=t.textContent)||void 0===n?void 0:n.trim())?(t.textContent.split(" ").forEach((e=>{var n;if(""!==e){const r=document.createElement("span");r.textContent=e+" ",o.observe(r),null===(n=t.parentNode)||void 0===n||n.insertBefore(r,t)}})),null===(r=t.parentNode)||void 0===r||r.removeChild(t)):t.nodeType===Node.ELEMENT_NODE&&Array.from(t.childNodes).forEach((t=>{e({node:t,focusText:o})}))}function t(e){var o,n,r;if(e.nodeType===Node.ELEMENT_NODE){const l=e;if(l instanceof HTMLElement&&"SPAN"===l.tagName&&("focus-text"===l.className||""===l.className||!(null===(o=l.textContent)||void 0===o?void 0:o.trim())||0===l.attributes.length)){const e=document.createTextNode(l.textContent||"");null===(n=l.parentNode)||void 0===n||n.insertBefore(e,l),null===(r=l.parentNode)||void 0===r||r.removeChild(l)}else Array.from(l.childNodes).forEach((e=>{t(e)}))}}},8795:()=>{const e=document.querySelector(".toggle-footnotes");e&&(e=>{var t;const o=document.createElement("button");o.classList.add("toggle-footnotes"),o.textContent="[Show Footnotes]",null===(t=e.parentNode)||void 0===t||t.replaceChild(o,e),o.addEventListener("click",(()=>{o.textContent="[Show Footnotes]"===o.textContent?"[Hide Footnotes]":"[Show Footnotes]";const e=o.nextElementSibling;e&&e.classList.toggle("show")}))})(e)},9308:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(6079);(()=>{if(null!==n.courseBody){n.contentWrapper&&n.secondColumn&&n.thirdColumn?n.courseBody.id="three-column":n.contentWrapper&&n.secondColumn&&!n.columnWidget?n.courseBody.id="two-column":n.contentWrapper&&n.secondColumn&&n.columnWidget?n.courseBody.id="two-col-widget":n.contentWrapper&&n.videoWrapper?n.courseBody.id="video-grid":!n.contentWrapper||n.secondColumn||n.thirdColumn||n.columnWidget||n.videoWrapper?n.contentWrapper&&!n.secondColumn&&(n.thirdColumn||n.columnWidget)?console.log("Document error: <body> is missing id because #second-column doesn't exist."):console.log("Document error: unable to determine the page layout for setting <body> id."):n.courseBody.id="one-column";const e=document.body.children;let t=!1;for(let o=0;o<e.length;o++){const n=e[o];if("content-wrapper"!==n.id&&"second-column"!==n.id&&"third-column"!==n.id&&"column-widget"!==n.id&&"HEADER"!==n.tagName&&"FOOTER"!==n.tagName&&"SCRIPT"!==n.tagName&&"loom-companion-mv3"!==n.id&&"focus-reader-switches"!==n.className&&"view-options-switches"!==n.className){t=!0;break}}t&&console.log("Document error: Additional content outside #content-wrapper, #second-column, #third-column, or footer.")}else console.log("Document error: no <body> element found.")})()},7721:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(6079),r=document.createElement("script");r.setAttribute("src","https://pima.h5p.com/js/h5p-resizer.js"),r.setAttribute("charset","UTF-8"),r.setAttribute("defer","");const l=document.querySelectorAll("iframe"),i=null===n.docHead||void 0===n.docHead?void 0:n.docHead.querySelector("script[src='https://pima.h5p.com/js/h5p-resizer.js']");l.length>0&&l.forEach((e=>{const t=e.getAttribute("src");t&&(t.includes("/d2l/common/dialogs/quickLink")||t.includes("https://pima.h5p.com/content")||t.includes("h5p"))&&!i&&n.docHead&&n.docHead.appendChild(r)}))},7121:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(6079),r=document.querySelectorAll(".gallery-wrapper"),l=document.querySelectorAll(".image-box"),i=document.querySelectorAll(".image-gallery");r.length>0&&r.forEach((e=>{const t=e.parentNode;t instanceof Element&&t.classList.contains("image-gallery")||console.warn("Document error: parent of .gallery-wrapper does not have the .image-gallery class.")})),l.length>0&&l.forEach((e=>{const t=e.parentNode;t instanceof Element&&t.classList.contains("gallery-wrapper")||console.log("Document error: parent of .image-box does not have the .gallery-wrapper class.")})),r.length>0&&r.forEach((e=>{Array.from(e.children).every((e=>e instanceof HTMLElement&&e.classList.contains("image-box")))||console.warn("Document error: not all direct children of .gallery-wrapper have the .image-box class.")}));i.length>0&&((()=>{const e=document.createElement("link");e.rel="stylesheet",e.href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css",null===n.docHead||void 0===n.docHead||n.docHead.appendChild(e)})(),(()=>{i.forEach((e=>{e.insertAdjacentHTML("afterbegin",'<div class="modal-box invisible">\n <div class="gallery-overlay"></div>\n <figure class="modal-box--image"><i class="fa-solid fa-x close-img"></i> <img src="#" alt="image here" /><figcaption class="img-caption"></figcaption></figure>\n </div>\n <button class="hide-gallery">Hide</button>')}));const e=document.querySelector(".gallery-overlay"),t=document.querySelector(".modal-box"),o=document.querySelector(".modal-box--image img"),n=document.querySelector(".img-caption"),r=document.querySelector(".close-img"),c=document.querySelectorAll(".hide-gallery"),s=e=>{null==t||t.classList.remove("invisible"),o&&(o.src=e.imgSrc),n&&(n.innerHTML=e.imgCaption)},a=()=>{null==t||t.classList.add("invisible")};l.forEach((e=>{e.addEventListener("click",(function(){var e,t;s({imgSrc:(null===(e=this.querySelector("img"))||void 0===e?void 0:e.src)||"",imgCaption:(null===(t=this.querySelector("img"))||void 0===t?void 0:t.alt)||""})})),e.setAttribute("tabindex","0"),e.addEventListener("keydown",(function(e){var t,o;"Enter"===e.key&&s({imgSrc:(null===(t=this.querySelector("img"))||void 0===t?void 0:t.src)||"",imgCaption:(null===(o=this.querySelector("img"))||void 0===o?void 0:o.alt)||""})}))})),e&&(e.onclick=a),window.onkeydown=e=>{"Escape"===e.key&&a()},r&&(r.onclick=a),c.forEach((e=>{e.addEventListener("click",(()=>{var t;null===(t=e.nextElementSibling)||void 0===t||t.classList.toggle("invisible"),e.innerHTML="Hide"===e.innerHTML?"Show":"Hide"}))}))})())},81:()=>{document.addEventListener("DOMContentLoaded",(()=>{document.querySelectorAll("a[href^='#']").forEach((e=>{var t;const o=null===(t=e.getAttribute("href"))||void 0===t?void 0:t.substring(1);o&&e.setAttribute("onclick",`jumpTo("${o}")`)}))}))},4786:()=>{const e=document.querySelectorAll(".media-container");e.length>0&&e.forEach(((e,t)=>{let o=String.fromCharCode(t+65).toLowerCase(),n=e.querySelector(".media-object"),r=e.querySelector("iframe"),l=e.querySelector(".media-info");r||console.warn("Document error: no iframe found for media container"),n||console.warn("Document error: no media object found for media container"),r&&!r.hasAttribute("aria-describedby")&&l&&(r.setAttribute("aria-describedby",`${o}`),l.id=`${[o]}`)}))},4407:()=>{const e=document.querySelectorAll(".display, .display-lg");e.length>0&&[...e].forEach((e=>{const t=e.querySelectorAll(".display table th, table.display th, .display-lg table th, table.display-lg th"),o=e.querySelector(".display table tbody, table.display tbody, .display-lg table tbody, table.display-lg tbody");if(t.length>0){const e=[...t].map((e=>{var t;return(null===(t=e.textContent)||void 0===t?void 0:t.replace(/\r?\n|\r/,""))||""}));o?[...o.rows].forEach((t=>{[...t.cells].forEach(((t,o)=>{t.setAttribute("data-th",e[o])}))})):console.warn("Document error: no table <tbody> found")}else console.warn("Document error: no table headers <th> found")}))},4393:()=>{const e=document.querySelectorAll(".slider-widget");e.length>0&&(()=>{[...e].forEach((e=>{[...e.children].every((e=>e.classList.contains("slider-item")))||console.warn("Document error: not all direct children of .slider have the .slider-item class.")}));const t=(e,t,o)=>{e.forEach(((e,t)=>{e.style.display=t===o?"block":"none"})),t.forEach(((e,t)=>{e.classList.toggle("active",t===o)}))},o=(e,o,n)=>{t(e,o,n)},n=e=>{const t=document.createElement("button");return t.className=e,t.setAttribute("tabindex","-1"),t},r=e=>{let t=0;for(let o=0;o<e.children.length;o++){const n=e.children[o];n instanceof HTMLElement&&(t+=n.offsetHeight)}if(t<300&&!e.querySelector(".media-container")){const t=document.createElement("div");for(;e.firstChild;)t.appendChild(e.firstChild);e.appendChild(t),e.classList.add("short-content")}};document.querySelectorAll(".slider-widget").forEach(((e,l)=>{e.setAttribute("tabindex","0"),e.setAttribute("role","group");const i=document.createElement("span");i.id=`slider-label-${l+1}`,i.textContent="Interactive Slider",i.hidden=!0,e.prepend(i),e.setAttribute("aria-labelledby",`slider-label-${l+1}`);let c=0;const s=Array.from(e.querySelectorAll(".slider-item")),a=document.createElement("div");a.className="slider-dots-bar",e.appendChild(a);let d=[];s.forEach(((e,o)=>{const n=document.createElement("span");n.className="slider-dot",n.addEventListener("click",(()=>{c=o,t(s,d,c),s[c].style.display="block",n.classList.add("active"),r(s[c])})),a.appendChild(n),d.push(n),e.style.display=o!==c?"none":"block",o===c&&n.classList.add("active")}));const u=n("slider-arrow icon-chevron-left"),m=n("slider-arrow icon-chevron-right");e.appendChild(u),e.appendChild(m),u.addEventListener("click",(()=>{c=c>0?c-1:s.length-1,o(s,d,c),r(s[c])})),m.addEventListener("click",(()=>{c=c<s.length-1?c+1:0,o(s,d,c),r(s[c])})),e.addEventListener("keydown",(t=>{switch(t.key){case"ArrowLeft":c=c>0?c-1:s.length-1;break;case"ArrowRight":c=c<s.length-1?c+1:0;break;default:return}o(s,d,c),r(s[c]),t.preventDefault(),i.textContent=`Interactive Slide: slide ${c+1} of ${s.length}`,e.focus()}));let p=0,g=0;e.addEventListener("touchstart",(e=>{p=e.changedTouches[0].screenX}),!1),e.addEventListener("touchend",(e=>{g=e.changedTouches[0].screenX,h()}),!1);const h=()=>{let t=g-p;Math.abs(t)>50&&(c=t>0?c>0?c-1:s.length-1:c<s.length-1?c+1:0,o(s,d,c),r(s[c]),e.focus())}})),e.forEach(((e,t)=>{((e,t)=>{const o=e.querySelector(".icon-chevron-right"),n=e.querySelector(".icon-chevron-left"),r=e.querySelector(".slider-dots-bar");o||console.warn(`Document error: next button is missing for slider ${t+1}.`),n||console.warn(`Document error: previous button is missing for slider ${t+1}.`),r||console.warn(`Document error: dots bar is missing for slider ${t+1}.`)})(e,t)})),e.forEach(((e,t)=>{Array.from(e.querySelectorAll(".slider-item")).forEach(((e,o)=>{Array.from(e.childNodes).every((e=>e.nodeType===Node.COMMENT_NODE||e.nodeType===Node.TEXT_NODE&&!e.textContent.trim()))&&console.warn(`Document error: .slider-item at index ${o} in slider ${t+1} is empty.`)}))}))})()},1952:()=>{const e=document.querySelectorAll(".tabs, .tabs-widget");e.length>0&&(()=>{let t=0;e.forEach(((e,o)=>{var n,r,l,i,c,s,a,d,u,m,p,g;let h=e.querySelectorAll("input"),b=e.querySelectorAll("label"),f=e.querySelectorAll("div");if((h.length<2||b.length<2||f.length<2)&&console.warn("Document error: add more than just one tab for tabs widget"),h.length<3||b.length<3||f.length<3){let e=b[1].querySelector("span");e&&("Hide"!==e.textContent&&""!==e.textContent||console.warn("Document error: add more tabs, than just 1 tab and the hide tab"))}let v=b[b.length-1].querySelector("span");v&&"Hide"!==v.textContent&&console.warn("Document error: ensure last tab is a hide tab and label text is 'Hide'"),(h.length<b.length||h.length<f.length)&&console.warn("Document error: missing tab input(s) in tab widget"),(b.length<h.length||b.length<f.length)&&console.warn("Document error: missing tab label(s) in tab widget");let y=o+1;e.setAttribute("role","region"),e.setAttribute("aria-label",`tab group ${y}`);for(let e=0;e<h.length;e++){"Hide"===(null===(r=null===(n=b[e])||void 0===n?void 0:n.textContent)||void 0===r?void 0:r.trim())&&b[e].classList.add("hide-tab");let o=t+1;h&&f||(console.warn("Document error: no inputs found for tabs widget"),console.warn("Document error: no divs (tab panels) found for tabs widget")),b||console.warn("Document error: no labels found for tabs widget"),null===(l=h[e])||void 0===l||l.classList.add("tab-input"),null===(i=h[e])||void 0===i||i.setAttribute("type","radio"),null===(c=h[e])||void 0===c||c.setAttribute("id",`tab${o}`),null===(s=h[e])||void 0===s||s.setAttribute("name",`hint-group-${y}`),null===(a=h[e])||void 0===a||a.setAttribute("aria-describedby",`tabHeading${o}`),null===(d=b[e])||void 0===d||d.classList.add("tab-header"),null===(u=b[e])||void 0===u||u.setAttribute("for",`tab${o}`),f[e]&&(null===(m=f[e])||void 0===m||m.classList.add("tab-panel"),null===(p=f[e])||void 0===p||p.setAttribute("tabindex","0"),null===(g=f[e])||void 0===g||g.setAttribute("id",`tabHeading${o}`)),h[e].checked=0===e,e+1==h.length&&(b[e].classList.add("hide-tab"),f[e]&&f[e].classList.add("hide-panel")),t++}}))})()},7174:()=>{const e=["cas","ecn","hrs","chm","blobs"];document.querySelectorAll("link").forEach((t=>{const o=t.getAttribute("href");e.forEach((e=>{o&&o.includes(`/${e}/styles.css`)&&function(e){let t=document.createElement("script");t.src=`https://cdn.jsdelivr.net/npm/@pimaonline/pimaonline-themepack/dist/js/themes/${e}.js`,document.head.appendChild(t)}(e)}))}))},6433:()=>{const e=document.querySelectorAll(".toggle-btn");e.length>0&&(()=>{if(document.querySelector(".toggle-btn"))for(let t=0;t<e.length;t++)e[t].setAttribute("tabindex","0"),e[t].addEventListener("click",(()=>{const o=e[t].nextElementSibling;o&&o.classList.toggle("show")})),e[t].addEventListener("keydown",(o=>{if("Enter"===o.key){const o=e[t].nextElementSibling;o&&o.classList.toggle("show")}}))})()},4709:()=>{const e="toolTip",t="toolTipHover",o=document.querySelectorAll(".tooltip");o.length>0&&(()=>{const n=(e,t)=>{t.style.display="block",e.classList.toggle("hidden",!1)},r=(e,t)=>{t.style.display="none",e.setAttribute("aria-expanded","false"),e.classList.toggle("hidden",!0)};o.forEach(((o,l)=>{let i=l+1;o.id=`${e}${i}`,o.role="tooltip",o.tabIndex=0,o.setAttribute("aria-expanded","false"),o.setAttribute("aria-controls",`${t}${i.toString()}`);const c=o.querySelector(".tip-hover");c?(c.id=`${t}${i}`,c.setAttribute("aria-describedby",`${e}${i.toString()}`),o.addEventListener("mouseover",(()=>n(o,c))),o.addEventListener("mouseout",(()=>r(o,c))),o.addEventListener("focus",(()=>n(o,c))),o.addEventListener("blur",(()=>r(o,c))),o.addEventListener("touchstart",(()=>n(o,c))),o.addEventListener("touchend",(()=>r(o,c)))):console.warn("Document error: tooltip is missing .tip-hover class");let s=30-i;o.style.zIndex=s.toString()})),document.querySelectorAll(".tooltip .video-container, .tooltip .video-container").forEach((e=>{const t=e.parentElement;t&&(t.style.width="450px")}))})()},6079:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.jqueryScript=t.videoWrapper=t.rolePres=t.thirdColumn=t.secondColumn=t.docHead=t.courseBody=t.contentWrapper=t.columnWidget=void 0,t.columnWidget=document.querySelector("#column-widget"),t.contentWrapper=document.querySelector("#content-wrapper"),t.courseBody=document.querySelector("body"),t.docHead=document.querySelector("head"),t.secondColumn=document.querySelector("#second-column"),t.thirdColumn=document.querySelector("#third-column"),t.rolePres=document.querySelectorAll('[role="presentation"]'),t.videoWrapper=document.querySelector("#video-wrapper"),t.jqueryScript=document.querySelector('script[src="https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js"]')},4019:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(3258),r=o(2692),l=o(4996),i=o(9191),c=o(3966),s=document.querySelector("body");s&&["view-options","focus-text","dark-mode","large-text","narrow-width"].some((e=>s.hasAttribute(e)))&&((0,n.callViewOptionsDrawer)(),(0,r.callFocusText)(),(0,l.callDarkMode)(),(0,i.callLargeText)(),(0,c.callNarrowWidth)())},4262:()=>{const e=document.querySelectorAll(".vocab-cards"),t=document.querySelectorAll(".vocab-cards .vocab");e.length>0&&(e.forEach((e=>{e.setAttribute("role","region"),e.setAttribute("aria-label","vocabulary list")})),t.length>0&&t.forEach((e=>{e.setAttribute("role","group")})))},7261:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528),l=o(5528),i=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("#CompletionTaskForm d2l-button-subtle");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${i.viewOptions}='activity-details']`);(0,n.darkModeCheck)(e,i.activityDetailsTabCss,t,"activity-details");let o=r.parentWindow.document.querySelector("#CompletionTaskForm d2l-button-subtle .d2l-image");o&&(l.darkOn?o.src="/shared/images/svg/chevron-down-solid-white.svg":o.src="https://s.brightspace.com/lib/bsi/2024.4.218/images/tier1/chevron-down.svg")}}}},7471:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528),l=o(5528);t.default=()=>{r.parentWindow.document.querySelectorAll("d2l-button-icon, d2l-button-icon").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${l.viewOptions}='button']`);(0,n.darkModeCheck)(e,l.buttonGroupStyle2Css,t,"button");const o=t.querySelector("d2l-icon");if(o){const e=o.shadowRoot;if(e){const t=e.querySelector(`style[${l.viewOptions}='button']`);(0,n.darkModeCheck)(t,l.buttonGroupStyle2Css,e,"button")}}}}))}},8338:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("#d2l_btn_bar");if(e){const t=e.querySelectorAll("button");if(t.length>0){let e=`\n\t#d2l_btn_bar button.d2l-button:hover {\n\t\tbackground-color: ${r.colors.colorDp1};\n\t}`;if(t.forEach((t=>{if(t.textContent){if("Edit HTML"===t.textContent.trim()){let o=t.id;o&&(e+=`\n #${o} span.d2l-icon-custom::before {\n content: url("/shared/images/svg/pencil-solid-white.svg");\n\t\t\t\twidth: 18px;\n\t\t\t\theight: 18px;\n\t\t\t\tdisplay: inline-block;\n }\n `)}if("Download"===t.textContent.trim()){let o=t.id;o&&(e+=`\n #${o} span.d2l-icon-custom::before {\n content: url("/shared/images/svg/cloud-arrow-down-solid.svg");\n\t\t\t\twidth: 18px;\n\t\t\t\theight: 18px;\n\t\t\t\tdisplay: inline-block;\n }\n `)}if("Print"===t.textContent.trim()){let o=t.id;o&&(e+=`\n #${o} span.d2l-icon-custom::before {\n content: url("/shared/images/svg/print-solid.svg");\n\t\t\t\twidth: 18px;\n\t\t\t\theight: 18px;\n\t\t\t\tdisplay: inline-block;\n }\n `)}if(t.classList.contains("ally-d2l-button")){let o=t.querySelector("img"),n=document.createElement("span");if(o)if(r.darkOn)o.style.width="0px",o.style.height="0px",n&&(n.classList.add("d2l-icon-custom"),t.prepend(n));else{o.style.width="22px",o.style.height="13px";let e=t.querySelector("span.d2l-icon-custom");e&&e.remove()}e+='\n button.ally-d2l-button span.d2l-icon-custom::before {\n content: url("/shared/images/svg/file-arrow-down-solid.svg");\n\t\t\t\t width: 14px;\n\t\t\t\t height: 18px;\n\t\t\t\t display: inline-block;\n }'}}})),r.d2lBodyElement){const t=r.d2lBodyElement.querySelector(`style[${r.viewOptions}='bottom-buttons']`);(0,n.darkModeCheck)(t,e,r.d2lBodyElement,"bottom-buttons")}}}}},8039:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(5528),r=o(8256);t.default=()=>{n.parentWindow.document.querySelectorAll("d2l-breadcrumbs > d2l-breadcrumb").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${n.viewOptions}='breadcrumb']`);(0,r.darkModeCheck)(e,n.breadcrumbsCss,t,"breadcrumb");const o=t.querySelector("d2l-icon");if(o){const e=o.shadowRoot;if(e){const t=e.querySelector(`style[${n.viewOptions}='breadcrumb-icon']`);(0,r.darkModeCheck)(t,n.whiteIconCss,e,"breadcrumb-icon")}}}}))}},3167:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(5528),r=o(8256);t.default=()=>{const e=()=>{(()=>{const e=n.parentWindow.document.querySelectorAll(".d2l-draghandle-content img.d2l-image");n.darkOn?e.forEach((e=>{e.src="/shared/images/svg/check-solid-white.svg"})):e.forEach((e=>{e.src="https://s.brightspace.com/lib/bsi/2024.4.218/images/tier1/check.svg"}))})();const t=n.parentWindow.document.querySelector("#ContentNavigator");if(t){const o=t.querySelector("d2l-button-icon[icon='tier1:chevron-left']");if(o){const l=t.querySelector("d2l-button-icon[icon='tier1:chevron-right']");if(l){const t=o.shadowRoot;if(t){const o=t.querySelector("d2l-icon");if(o){const i=o.shadowRoot;if(i){const o=l.shadowRoot;if(o){const l=o.querySelector("d2l-icon");if(l){const e=l.shadowRoot;if(e){const l=t.querySelector(`style[${n.viewOptions}='chevron']`),c=o.querySelector(`style[${n.viewOptions}='chevron']`),s=i.querySelector(`style[${n.viewOptions}='chevron']`),a=e.querySelector(`style[${n.viewOptions}='chevron']`);(0,r.darkModeCheck)(l,n.buttonGroupCss,t,"chevron"),(0,r.darkModeCheck)(c,n.buttonGroupCss,o,"chevron"),(0,r.darkModeCheck)(s,n.buttonGroupCss,i,"chevron"),(0,r.darkModeCheck)(a,n.buttonGroupCss,e,"chevron")}}const c=t.querySelector("button[title='Previous module']"),s=o.querySelector("button[title='Next module']");c&&(c.addEventListener("click",(()=>{setTimeout(e,500)})),c.addEventListener("keydown",(t=>{"Enter"===t.key&&setTimeout(e,500)}))),s&&(s.addEventListener("click",(()=>{setTimeout(e,500)})),s.addEventListener("keydown",(t=>{"Enter"===t.key&&setTimeout(e,500)})))}}}}}}}},t=n.parentWindow.document.querySelector(".d2l-page-collapsepane-shadow");t&&(t.addEventListener("click",(()=>{setTimeout(e,500)})),t.addEventListener("keydown",(t=>{"Enter"===t.key&&e()})))}},1179:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("d2l-navigation-button-icon[icon='tier1:chevron-left']");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector("d2l-icon");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='chevron-back']`);(0,n.darkModeCheck)(e,r.whiteIconCss,t,"chevron-back")}}}}const t=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:classes']"),o=()=>{r.parentWindow.document.querySelectorAll(".d2l-datalist-item .d2l-course-selector-item span d2l-button-icon").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='pin']`),o=t.querySelector("d2l-icon");if(o){const l=o.shadowRoot;if(l){const o=l.querySelector(`style[${r.viewOptions}='pin']`);(0,n.darkModeCheck)(o,r.whiteIconCss,l,"pin"),(0,n.darkModeCheck)(e,r.pinBtnStylesCss,t,"pin")}}}}))};t&&(t.addEventListener("click",(()=>{setTimeout(o,1e3)})),t.addEventListener("keydown",(e=>{"Enter"===e.key&&setTimeout(o,1e3)})));const l=r.parentWindow.document.querySelector("d2l-navigation-button-icon[icon='tier3:classes']");if(l){const e=l.shadowRoot;if(e){const t=e.querySelector("d2l-icon");if(t){const e=t.shadowRoot;if(e){const t=e.querySelector(`style[${r.viewOptions}='waffle-icon']`);(0,n.darkModeCheck)(t,r.whiteIconCss,e,"waffle-icon"),l.addEventListener("click",(()=>{setTimeout(o,1e3)})),l.addEventListener("keydown",(e=>{"Enter"===e.key&&setTimeout(o,1e3)}))}}}}}},4387:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(5528);t.default=()=>{const e=document.querySelector("head"),t=document.querySelector("body");if(e&&t){const o=e.querySelector("link[href='darkmode.css']");if(n.darkOn){if(t.setAttribute("dark-mode-on",""),!o){const t=document.createElement("link");t.setAttribute("rel","stylesheet"),t.setAttribute("href","darkmode.css"),e.append(t)}}else t.hasAttribute("dark-mode-on")&&t.removeAttribute("dark-mode-on"),o&&e.removeChild(o)}}},7338:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("d2l-dropdown-context-menu");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector("d2l-button-icon");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector("d2l-icon");if(e){const o=e.shadowRoot;if(o){const e=o.querySelector(`style[${r.viewOptions}='chevron']`),l=o.querySelector(`style[${r.viewOptions}='chevron']`);(0,n.darkModeCheck)(e,r.buttonGroupCss,t,"chevron"),(0,n.darkModeCheck)(l,r.buttonGroupCss,o,"chevron")}}}}}}const t=r.parentWindow.document.querySelector("d2l-dropdown-context-menu"),o=()=>{const e=r.parentWindow.document.querySelector(".d2l-dropdown-menu-contextmenu");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='dropdown-menu']`);(0,n.darkModeCheck)(e,r.dropdownDarkBackgroundCss,t,"dropdown-menu")}}};t&&t.addEventListener("click",(()=>{setTimeout(o,250)}))}},2209:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("d2l-navigation-button-icon[icon='tier3:menu-hamburger']");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector("d2l-icon[icon='tier3:menu-hamburger']");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='hamburger']`);(0,n.darkModeCheck)(e,r.buttonGroupCss,t,"hamburger")}}}}}},7383:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{r.parentWindow.document.querySelectorAll("d2l-icon").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='svg']`);(0,n.darkModeCheck)(e,r.whiteIconCss,t,"svg")}}))}},630:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(5528),r=o(8256);t.default=()=>{n.parentWindow.document.querySelectorAll("d2l-navigation-link-image").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(".d2l-navigation-link-image-container");if(e){const o=t.querySelectorAll(`style[${n.viewOptions}='logo-img']`);if(n.darkOn){let l=e.querySelector("img");l&&l.remove(),0===o.length&&(0,r.injectCSS)(n.logoCss,t,"logo-img");const i=document.createElement("img");i.classList.add("logo-img-white"),i.src="/shared/images/svg/pima-logo-white.svg",i.alt="My Home",e.append(i)}else{let t=e.querySelector("img");t&&t.remove(),o.length>1&&o[0].remove();const n=document.createElement("img");n.classList.add("logo-img"),n.src="/d2l/lp/navbars/6606/theme/viewimage/2389656/view?v=20.24.4.19097",e.append(n)}}}}))}},2:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("d2l-menu-item-link");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='hamburger']`);(0,n.darkModeCheck)(e,r.buttonGroupCss,t,"hamburger")}}r.parentWindow.document.querySelectorAll(".d2l-navigation-s-mobile-menu-nav > d2l-menu > d2l-menu-item").forEach((e=>{(e=>{const t=e.shadowRoot;if(t){const o=t.querySelector("d2l-icon");if(o){const t=o.shadowRoot;if(t){const o=t.querySelector(`style[${r.viewOptions}='chevron']`),l=e.querySelector("d2l-menu");if(l){const e=l.shadowRoot;if(e){const l=e.querySelector("d2l-menu-item-return");if(l){const i=t.querySelector(`style[${r.viewOptions}='return-item-one']`),c=l.shadowRoot;if(c){const l=c.querySelector("d2l-icon");if(l){const c=l.shadowRoot;if(c){const l=c.querySelector(`style[${r.viewOptions}='chevron']`);(0,n.darkModeCheck)(o,r.whiteIconCss,t,"chevron"),(0,n.darkModeCheck)(i,r.returnMenuCss,e,"return-item-one"),(0,n.darkModeCheck)(l,r.whiteIconCss,c,"chevron")}}}}}}}}}})(e),e.querySelectorAll("d2l-menu>d2l-menu-item").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelectorAll("d2l-icon");e.length>0&&e.forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='chevron']`);(0,n.darkModeCheck)(e,r.whiteIconCss,t,"chevron")}}))}const o=e.querySelector("d2l-menu");if(o){const e=o.shadowRoot;if(e){const t=e.querySelector("d2l-menu-item-return");if(t){const o=e.querySelector(`style[${r.viewOptions}='return-item-two']`),l=t.shadowRoot;if(l){const t=l.querySelector("d2l-icon");if(t){const l=t.shadowRoot;if(l){const t=l.querySelector(`style[${r.viewOptions}='chevron']`);(0,n.darkModeCheck)(t,r.whiteIconCss,l,"chevron"),(0,n.darkModeCheck)(o,r.returnMenuCss,e,"return-item-two")}}}}}}}))}))}},9085:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528),l=o(5528);t.default=()=>{r.parentWindow.document.querySelectorAll("d2l-menu > d2l-menu-item-link, d2l-menu > d2l-menu-item").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='dropdown']`);(0,n.darkModeCheck)(e,l.dropdownMenuCss,t,"dropdown")}})),r.parentWindow.document.querySelectorAll("d2l-dropdown-menu, d2l-dropdown-content").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='dropdown']`);(0,n.darkModeCheck)(e,l.dropdownBorderCss,t,"dropdown");const o=t.querySelector("d2l-icon[icon='tier1:chevron-right']"),i=t.querySelector(`style[${r.viewOptions}='chevron']`);o&&(0,n.darkModeCheck)(i,l.dropdownMenuCss,t,"chevron")}}))}},9764:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=".d2l-branding-navigation-dark-foreground-color .d2l-navigation-s-group",t=".vui-list>li.vui-selected, .vui-list>li.vui-selected",o="#ContentNavigator .vui-list > .vui-selected",l=".vui-tabmenu > .vui-tabmenu-item-select > a",i="#CompletionTaskForm d2l-button-subtle",c="div.d2l-filterinline-group-filter > div > a",s=`html {background: ${r.colors.colorDark};}`,a=`#d2l_body, .d2l-body {background: ${r.colors.colorDark};}`,d=`.d2l-navigation-s, .d2l-branding-navigation-background-color, d2l-navigation-main-header {background: ${r.colors.colorDp1};}`,u=`.d2l-branding-navigation-dark-foreground-color a.d2l-navigation-s-link, .d2l-branding-navigation-dark-foreground-color a.d2l-navigation-s-link:link, .d2l-branding-navigation-dark-foreground-color a.d2l-navigation-s-link:visited, .d2l-branding-navigation-dark-foreground-color div.d2l-navigation-s-item>span, ${e}, ${e} {color: ${r.colors.textColor}}`,m=`d2l-breadcrumbs::after {background: ${r.colors.colorDark};}`,p=`${t} {background: ${r.colors.colorDp1}}`,g=`.d2l-courseselector-wrapper, .d2l-page-main-padding > .d2l-datalist-style1, .d2l-page-main-padding > .d2l-placeholder > .d2l-datalist-style1, .d2l-page-main-padding > form > .d2l-datalist-style1, .d2l-datalist-outdent, ${t} {background: ${r.colors.colorDark}}`,h=`.vui-list>.d2l-list-item-action-hover {background: ${r.colors.colorDp1} !important}`,b=`.vui-list>li.d2l-list-item-action-hover.vui-selected {background: ${r.colors.colorDp2} !important}`,f=`.d2l-admin-tools, .d2l-admin-tools .d2l-heading {background: ${r.colors.colorDark}; color: ${r.colors.textColor}}`,v=`.d2l-page-collapsepane-content-inner, ${o}, .d2l-page-collapsepane-handle, .d2l-page-collapsepane.d2l-page-collapsepane-opening .d2l-page-collapsepane-handle, .d2l-page-collapsepane-content {background: ${r.colors.colorDark}}`,y=`${o} {background: ${r.colors.colorDp1}; border-top-color: ${r.colors.textColor}}`,w=`.d2l-link.d2l-link-flat, .d2l-linkheading-link.d2l-link-flat {color: ${r.colors.colorLinks}}`,k=`.d2l-page-collapsepane.d2l-page-collapsepane-opening .d2l-page-collapsepane-handle .d2l-page-collapsepane-handle-link, .d2l-page-collapsepane-handle-link {border-right-color: ${r.colors.textColor}; border-left-color: ${r.colors.textColor}; border-color: ${r.colors.borderColor}}`,S=`.d2l-iterator-button, .d2l-iterator-button.d2l-iterator-button-disabled:hover, .d2l-iterator-button.d2l-iterator-button-disabled:focus {background: transparent; border-color: ${r.colors.colorDp1};}`,C=`.d2l-link, .d2l-link:visited, .d2l-link:active, .d2l-link:link {color: ${r.colors.linkColor}}`,$=`d2l-dropdown-content .d2l-list {background: ${r.colors.colorDark};}`,q=`.d2l-editable:hover {background: ${r.colors.colorDp4}}`,E=`.d2l-button, .d2l-button[active][disabled], .d2l-button[disabled]:focus, .d2l-button[disabled]:hover {background: ${r.colors.colorDark}; border: 1px solid ${r.colors.textColor}; color: ${r.colors.textColor}}`,x=`${l}, .vui-tabmenu > .vui-tabmenu-item:last-child > a, ${l}, .vui-tabmenu > .vui-tabmenu-item > a {background: ${r.colors.colorDp1}; color: ${r.colors.textColor}}`,A=`.d2l-typography {color: ${r.colors.textColor}}`,L=`.d2l-navigation-s-personal-menu-text, .d2l-textblock-secondary {color: ${r.colors.textColor}}`,D=`.d2l-navigation-s-linkarea-no-color .d2l-navigation-s-group:hover, .d2l-navigation-s-linkarea-no-color a.d2l-navigation-s-link:hover {color: ${r.colors.linkColor};}`,M=`\n button:not([disabled]):hover, button:not([disabled]):focus, button[active], *:focus > .d2l-navigation-highlight-border, *:hover > .d2l-navigation-highlight-border, *[active] > .d2l-navigation-highlight-border {\n --d2l-icon-fill-color: ${r.colors.colorLinks} !important;\n --d2l-color-celestine: ${r.colors.colorLinks} !important;\n }\n `,O=`#AdditionalInfoPlaceholder .vui-tabmenu .vui-tabmenu-item a:hover {color: ${r.colors.borderColor}}`,T=`${i} .d2l-container-icon .d2l-textblock {color: ${r.colors.textColor}}\n\t${i} .d2l-inline .d2l-container-icon {background-image: url("/shared/images/svg/check-solid-white.svg")}\n`,_=`${c} {color: ${r.colors.textColor}}\n\t${c}:hover {color: ${r.colors.borderColor}}\n\t#ResultDetails #Filter .d2l-filterinline-item-selected {color: ${r.colors.colorLinks}}\n\t`,N=`#EvaluationSummaryTabId button:hover {background-color: ${r.colors.colorDp1}}`,j=`button:focus:not([disabled]) {background-color: ${r.colors.colorDp1}}`,P=`.d2l-page-collapsepane .d2l-page-collapsepane-handle-link {border-color: transparent;border-left: 5px solid ${r.colors.textColor};}`,H=`.d2l-page-collapsepane.d2l-page-collapsepane-open .d2l-page-collapsepane-handle-link {border-color: transparent !important; border-right: 5px solid ${r.colors.textColor} !important;}`,B=`.d2l-branding-navigation-dark-foreground-color .d2l-navigation-s-mobile-menu-title-bp {color: ${r.colors.textColor}}`,W=`.d2l-navigation-s-mobile-menu-content {background-color: ${r.colors.colorDark}}`,R=`.d2l-navigation-s-mobile-menu-nav d2l-menu-item-link, .d2l-navigation-s-mobile-menu-nav d2l-menu-item, .d2l-navigation-s-mobile-menu-nav d2l-menu-item {background-color: ${r.colors.colorDark}}`,I=`\n\t\t${a}\n\t\t${d}\n\t\t${v}\n\t\t${y}\n\t\t${S}\n\t\t${g}\n\t\t${h}\n\t\t${p}\n\t\t${b}\n\t\t${f}\n\t\t${u}\n\t\t${w}\n\t\t${C}\n\t\t${k}\n\t\t${$}\n\t\t${q}\n\t\t${E}\n\t\t${x}\n\t\t${A}\n\t\t${L}\n\t\t${M}\n\t\t${D}\n\t ${m}\n\t ${O}\n\t ${T}\n\t ${_}\n\t ${N}\n\t ${j}\n\t ${P}\n\t ${H}\n\t .d2l-draghandle-handle-icon {background-image: url("/shared/images/svg/grip-vertical-solid-white.svg")}\n\t .d2l-draghandle-content .d2l-container-icon {background-image: url("/shared/images/svg/globe-solid-white.svg")}\n\t ${B}\n\t ${W}\n\t .d2l-navigation-s-mobile-menu-nav d2l-menu-item-link:hover, .d2l-navigation-s-mobile-menu-nav d2l-menu-item:hover {background-color: ${r.colors.colorDp1}}\n\t ${R}\n\t #ContentNavigator .d2l-link.d2l-link-flat:focus, #ContentNavigator .d2l-link.d2l-link-flat:hover, .d2l-linkheading-link.d2l-link-flat:focus, #ContentNavigator .d2l-linkheading-link.d2l-link-flat:hover {color: ${r.colors.linkColor}}\n\t .d2l-typography .d2l-body-small {color: ${r.colors.textColor}}\n\t \n\n d2l-menu-item-link.d2l-navigation-s-menu-item-root, d2l-menu-item.d2l-navigation-s-menu-item-root {\n background: ${r.colors.colorDark};\n }\n\n .d2l-menu-item-text {\n color: ${r.colors.textColor};\n }\n\n\t\td2l-dropdown d2l-icon[icon='tier1:chevron-down'] {\n\t\t\tfill: ${r.colors.textColor};\n\t\t}\n\t .d2l-courseselector-wrapper #courseSelectorId .d2l-datalist-item .d2l-course-selector-item a {color: ${r.colors.textColor}}\n\t d2l-dropdown-content d2l-datalist vui-list d2l-datalist-item {background-color: ${r.colors.colorDp1} !important}\n\t d2l-dropdown-content .d2l-data-list-item-action-hover {background-color: ${r.colors.colorDp2} !important}\n\t .d2l-navigation-s-mobile-menu-content d2l-navigation-band {background: transparent}\n\t d2l-navigation-dropdown-button-icon[icon='tier3:notification-bell'] d2l-dropdown-content button.d2l-loadmore-pager {\n\tbackground-color: ${r.colors.colorPrimary};\n\tcolor: ${r.colors.colorBlack};\n\tborder: none;\n\t}\n\t d2l-navigation-dropdown-button-icon[icon='tier3:notification-bell'] d2l-dropdown-content button.d2l-loadmore-pager:hover {\n\tbackground-color: ${r.colors.colorPrimaryHover};\n\tcolor: ${r.colors.colorBlack};\n\tborder: none;\n\t}\n\t .d2l-messagebucket-button-container + #AB_DL_PH_Messages .d2l-datalist-container {background: ${r.colors.colorDark}}\n\t d2l-menu.d2l-menu-mvc.d2l-contextmenu d2l-menu-item {color: ${r.colors.textColor};\n\tbackground-color: ${r.colors.colorDark};\n\t}\n\t d2l-menu.d2l-menu-mvc.d2l-contextmenu d2l-menu-item:hover {\n\tcolor: ${r.colors.textColor};\n\tbackground: ${r.colors.colorDp1};\n\t}\n\t .d2l-navigation-s-more d2l-menu > d2l-menu-item {\n\t\tbackground: ${r.colors.colorDark}\n\t}\n\t .d2l-navigation-s-more d2l-menu > d2l-menu-item:hover {\n\t\tbackground: ${r.colors.colorDp1}\n\t}\n\t .d2l-editable.d2l-editable-autosize.d2l-editable-focus {background: ${r.colors.colorDark}}\n\t .d2l-navigation-s-linkarea-no-color .d2l-navigation-s-group:focus {color: ${r.colors.textColor}}\n\t d2l-dropdown-more d2l-menu d2l-menu-item, d2l-dropdown-more d2l-menu d2l-menu-item-link {\n\tbackground-color: ${r.colors.colorDark};\n\t}\n\t d2l-dropdown-more d2l-menu d2l-menu-item:hover, d2l-dropdown-more d2l-menu d2l-menu-item-link:hover {\n\tbackground-color: ${r.colors.colorDp1};\n\t}\n\t #CompletionTaskForm .d2l-container-icon {background-image: url('/shared/images/svg/check-solid-white.svg')}\n\t\tul.d2l-personal-tools-list li {color: ${r.colors.textColor}}\n\t\tul.d2l-personal-tools-list li a.d2l-link {color: ${r.colors.textColor}}\n\tul.d2l-personal-tools-list li a.d2l-link:hover {color: ${r.colors.linkColor}}\n\t\t#ContentNavigator a.d2l-link {color: ${r.colors.textColor}}\n\t\t#ContentNavigator a.d2l-link:hover {color: ${r.colors.linkColor}}\n\t\td2l-menu-item.d2l-navigation-s-menu-item-root:hover, d2l-menu-item-link.d2l-navigation-s-menu-item-root:hover {background: ${r.colors.colorDp1}}\n\t\t#AdminToolsPlaceholderId a.d2l-link {color: ${r.colors.textColor}}\n\t\t#AdminToolsPlaceholderId a.d2l-link:hover {color: ${r.colors.linkColor}}\n\t\t.d2l-iterator-button {background: ${r.colors.colorDp1}}\n\t\t${s}\n\t`;if(r.d2lBodyElement){const e=r.d2lBodyElement.querySelector(`style[${r.viewOptions}='parent']`);(0,n.darkModeCheck)(e,I,r.d2lBodyElement,"parent")}}},7152:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelectorAll(".d2l-navigation-s-item.d2l-navigation-s-more d2l-menu-item");e.length>0&&e.forEach((e=>{const t=e.querySelector("d2l-menu");if(t){const e=t.shadowRoot;if(e){const t=e.querySelector(`style[${r.viewOptions}='return-item']`);(0,n.darkModeCheck)(t,r.returnMenuCss,e,"return-item");const o=e.querySelector("d2l-menu-item-return");if(o){const e=o.shadowRoot;if(e){const t=e.querySelector("d2l-icon");if(t){const e=t.shadowRoot;if(e){const t=e.querySelector(`style[${r.viewOptions}='chevron']`);(0,n.darkModeCheck)(t,r.whiteIconCss,e,"chevron")}}}}}}const o=e.shadowRoot;if(o){const e=o.querySelector("d2l-icon");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='chevron']`);(0,n.darkModeCheck)(e,r.whiteIconCss,t,"chevron")}}}}))}},9301:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("d2l-navigation");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='band']`);(0,n.darkModeCheck)(e,r.topNavigationBandCss,t,"band")}}}},9283:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=()=>{const e=r.parentWindow.document.querySelectorAll("d2l-navigation-dropdown-button-icon");e.length>0&&e.forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector("d2l-icon");if(e){const o=e.shadowRoot;if(o){const e=t.querySelector(`style[${r.viewOptions}='waffle']`),l=o.querySelector(`style[${r.viewOptions}='waffle-icon']`);(0,n.darkModeCheck)(l,r.topNavIconCss,t,"waffle"),(0,n.darkModeCheck)(e,r.whiteIconCss,o,"waffle-icon")}}}}));const t=r.parentWindow.document.querySelector("d2l-navigation-button-icon[icon='tier3:classes']");if(t){const e=t.shadowRoot;if(e){const t=e.querySelector("d2l-icon");if(t){const e=t.shadowRoot;if(e){const t=e.querySelector(`style[${r.viewOptions}='waffle-icon']`);(0,n.darkModeCheck)(t,r.whiteIconCss,e,"waffle-icon")}}}}};e();const t=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:notification-bell']");t&&t.addEventListener("click",e);const o=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:discussions']");o&&o.addEventListener("click",e);const l=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:email']");l&&l.addEventListener("click",e)}},513:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=o(8256),r=o(5528);t.default=()=>{const e=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:notification-bell']");if(e){const t=()=>{e.querySelectorAll("d2l-icon").forEach((e=>{const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='icon-white']`);(0,n.darkModeCheck)(e,r.whiteIconCss,t,"icon-white")}}))};e.addEventListener("click",(()=>{setTimeout(t,750)}))}const t=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:discussions']");if(t){const e=()=>{const e=t.querySelector("d2l-empty-state-simple");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='icon-white']`);(0,n.darkModeCheck)(e,r.messageAreaBkgCss,t,"icon-white")}}};t.addEventListener("click",(()=>{setTimeout(e,500)}))}const o=r.parentWindow.document.querySelector("d2l-navigation-dropdown-button-icon[icon='tier3:email']");if(o){const e=()=>{const e=o.querySelector("d2l-button-subtle[icon='tier1:email']");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector("d2l-icon");if(e){const l=e.shadowRoot;if(l){const e=l.querySelector(`style[${r.viewOptions}='button-styles']`),i=l.querySelector(`style[${r.viewOptions}='button-styles']`);(0,n.darkModeCheck)(i,r.messageButtonCss,t,"button-styles"),(0,n.darkModeCheck)(e,r.messageButtonCss,l,"button-styles");const c=o.querySelector("#AB_DL_PH_Messages>div");if(c){const e=c.querySelector("d2l-empty-state-simple");if(e){const t=e.shadowRoot;if(t){const e=t.querySelector(`style[${r.viewOptions}='empty-state-container']`);(0,n.darkModeCheck)(e,r.messageAreaBkgCss,t,"empty-state-container")}}}}}}}};o.addEventListener("click",(()=>{setTimeout(e,500)}))}}},8495:function(e,t,o){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});const r=n(o(7261)),l=n(o(7471)),i=n(o(8338)),c=n(o(8039)),s=n(o(3167)),a=n(o(1179)),d=n(o(4387)),u=n(o(7338)),m=n(o(2209)),p=n(o(7383)),g=n(o(630)),h=n(o(2)),b=n(o(9085)),f=n(o(9764)),v=n(o(7152)),y=n(o(9301)),w=n(o(9283)),k=n(o(513)),S=()=>{(0,r.default)(),(0,l.default)(),(0,i.default)(),(0,c.default)(),(0,s.default)(),(0,a.default)(),(0,d.default)(),(0,u.default)(),(0,m.default)(),(0,p.default)(),(0,g.default)(),(0,h.default)(),(0,b.default)(),(0,f.default)(),(0,v.default)(),(0,y.default)(),(0,w.default)(),(0,k.default)()};document.querySelector("body[dark-mode]")&&S(),t.default=S},1424:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),o(5528),o(8256),o(8495)},8256:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.darkModeCheck=t.injectCSS=void 0;const n=o(5528);function r(e,t,o){const r=document.createElement("style");r.setAttribute(`${n.viewOptions}`,o),r.innerHTML=e,t.prepend(r)}t.injectCSS=r,t.darkModeCheck=function(e,t,o,l){n.darkOn?null==e&&r(t,o,l):null!=e&&e.remove()}},5528:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.darkBackgroundAlertCss=t.topNavIconCss=t.topNavigationBandCss=t.dropdownDarkBackgroundCss=t.pinBtnStylesCss=t.breadcrumbsCss=t.buttonGroupStyle2Css=t.activityDetailsTabCss=t.dropdownBorderCss=t.dropdownMenuCss=t.messageButtonCss=t.messageAreaBkgCss=t.returnMenuCss=t.logoCss=t.buttonGroupCss=t.whiteIconCss=t.d2lBodyElement=t.parentWindow=t.toggleDarkOn=t.darkOn=t.colors=t.viewOptions=void 0,t.viewOptions="pccviewoptions",t.colors={colorPrimary:"rgba(149, 209, 255, 1)",colorPrimaryHover:"rgba(126, 199, 255, 1)",colorDark:"rgba(15, 23, 42, 1)",colorDp1:"rgba(255, 255, 255, .05)",colorDp2:"rgba(255, 255, 255, .07)",colorDp3:"rgba(255, 255, 255, .08)",colorDp4:"rgba(255, 255, 255, .09)",colorLinks:"rgba(56, 189, 248, 1)",colorLinksHover:"rgba(136, 179, 202, 1)",colorLinksVisited:"rgba(185, 183, 237, 1)",colorBlack:"rgba(13, 13, 13, 1)",linkColor:"rgba(56, 189, 248, 1)",textColor:"rgba(255, 255, 255, 1)",borderColor:"rgba(255, 255, 255, .5)",pccPrimary:"rgba(4, 85, 148, 1)"},t.darkOn=!1,t.toggleDarkOn=()=>{t.darkOn=!t.darkOn},t.parentWindow=window.parent,t.d2lBodyElement=t.parentWindow.document.querySelector(".d2l-body"),t.whiteIconCss=`svg {color: ${t.colors.textColor};fill: ${t.colors.textColor};}`,t.buttonGroupCss="\n\tbutton:hover:not([disabled]), button:focus:not([disabled]), :host([active]) button:not([disabled]) {\n\t\tbackground-color: transparent !important;\n\t}\n\n\tsvg {\n\t\tcolor: white !important;\n\t\tfill: white !important;\n\t}",t.logoCss="\n\t.logo-img {\n\t\twidth: 40px;\n\t\theight: 173px;\n\t}\n\t.logo-img-white {\n\t\twidth: 60px;\n\t\tmax-height: 60px !important;\n\t\theight: 173px;\n\t\tmargin-left: -10px;\n\t\tmargin-right: -5px;\n\t}",t.returnMenuCss=`\n\td2l-menu-item-return {background-color: ${t.colors.colorDp2}}\n\td2l-menu-item-return:hover {background-color: ${t.colors.colorDp3}}\n\td2l-menu-item-return {color: ${t.colors.textColor}}\n\t`,t.messageAreaBkgCss=`\n\t.empty-state-container {background: ${t.colors.colorDark}}\n\t.empty-state-container p {color: ${t.colors.textColor}}\n\t}`,t.messageButtonCss=`\nbutton:hover:not([disabled]), button:focus:not([disabled]), :host([active]) button:not([disabled]) {\n color: ${t.colors.colorBlack} !important;\n background-color: ${t.colors.colorPrimaryHover} !important;\n}\nbutton {\n color: ${t.colors.colorBlack} !important;\n background-color: ${t.colors.colorPrimary} !important;\n} \nbutton .d2l-button-subtle-content {\n color: ${t.colors.colorBlack} !important;\n background-color: transparent !important;\n}\nbutton .d2l-button-subtle-content:hover {\n color: ${t.colors.colorBlack} !important;\n background-color: transparent !important;\n}\nsvg {\n color: ${t.colors.colorBlack} !important;\n fill: ${t.colors.colorBlack} !important;\n}`;const o="d2l-menu-item-link.d2l-navigation-s-menu-item-root",n="d2l-menu-item.d2l-navigation-s-menu-item-root";t.dropdownMenuCss=`\n ${o}, ${n} {\n background: ${t.colors.colorDark} !important;\n }\n .d2l-menu-item-text {\n color: ${t.colors.textColor} !important;\n }\n ${o}:hover, ${n}:hover {\n background: rgba(255, 255, 255, .05) !important;\n } \n `,t.dropdownBorderCss=`\n .d2l-dropdown-content-top, .d2l-dropdown-content-bottom, .d2l-dropdown-content-pointer > div {\n background: ${t.colors.colorDark} !important;\n }\n\n\t.d2l-dropdown-content-width {\n\t background-color: ${t.colors.colorDark} !important;\n\t}`,t.activityDetailsTabCss=`\nbutton:hover, button:focus, :host([active]) button {\n background-color: ${t.colors.colorDp2} !important;\n}`,t.buttonGroupStyle2Css=`\nbutton:hover:not([disabled]), button:focus:not([disabled]), :host([active]) button:not([disabled]) {\n background-color: ${t.colors.colorDp1} !important;\n}\nsvg {\n color: white !important;\n fill: white !important;\n}`,t.breadcrumbsCss=`\n.d2l-link, .d2l-link:visited, .d2l-link:active, .d2l-link:link { \n color: ${t.colors.textColor} !important; \n}\n .d2l-link:hover { \n color: ${t.colors.linkColor} !important; \n}`,t.pinBtnStylesCss=`\nbutton:hover:not([disabled]), button:focus:not([disabled]), :host([active]) button:not([disabled]) {\n background-color: ${t.colors.linkColor} !important\n}`,t.dropdownDarkBackgroundCss=`\n#d2l-dropdown-wrapper {\n background-color: ${t.colors.colorDark}\n}`,t.topNavigationBandCss="\n\td2l-navigation-band {\n\t background: transparent;\n\t}",t.topNavIconCss=`button:not([disabled]):hover, button:not([disabled]):focus, button[active], *:focus > .d2l-navigation-highlight-border, *:hover > .d2l-navigation-highlight-border, *[active] > .d2l-navigation-highlight-border {\n --d2l-icon-fill-color: ${t.colors.colorLinks} !important;\n --d2l-color-celestine: ${t.colors.colorLinks} !important;\n }`,t.darkBackgroundAlertCss=`\nd2l-alert {\n background-color: ${t.colors.colorDark}\n}`,t.default=t.colors},4996:function(e,t,o){var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.callDarkMode=void 0;const r=o(5528),l=n(o(8495));let i=!1;t.callDarkMode=function(){const e=document.querySelector("#dark-mode-btn");e?(e.addEventListener("click",(t=>{t.stopPropagation(),i=!i,(0,r.toggleDarkOn)(),e.innerHTML=i?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>',(0,l.default)()})),e.addEventListener("keydown",(t=>{"Enter"!==t.key&&13!==t.keyCode||(t.preventDefault(),i=!i,(0,r.toggleDarkOn)(),e.innerHTML=i?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>',(0,l.default)())}))):console.warn("Document error: dark mode switch element is missing - event listeners not added")}},3258:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.callViewOptionsDrawer=void 0,t.callViewOptionsDrawer=function(){let e=!1;const t=document.querySelector("body"),o=document.querySelector("head"),n=(e,t)=>{const n=document.createElement(e);Object.keys(t).forEach((e=>n.setAttribute(e,t[e]))),null==o||o.append(n)};n("link",{rel:"stylesheet",href:"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"}),n("script",{src:"https://www.jsdelivr.com/package/npm/intersection-observer"});const r=document.createElement("div");function l(e,t,o,n){return`\n <div class="${o}-wrapper">\n <img src="${n}" alt="">\n <p class="feature">${e}</p>\n <p class="caption">${t}</p>\n <button id="${o}-btn" class="vo-toggle-btns" tabindex="-1" aria-label="${e.toLowerCase()} toggle button" aria-checked="false" role="button">\n <i class="fas fa-toggle-off"></i>\n </button>\n </div>\n `}r.className="view-options-switches",null==t||t.append(r),r.innerHTML=`\n <button aria-label="view options drawer" aria-expanded="false" role="button" tabindex="1">\n <img src="/shared/images/svg/sliders-icon.svg" alt="">\n </button>\n <div class="control-panel">\n <h2>View Options</h2>\n ${l("Dark Mode","Turn browser dark","dark-mode","/shared/images/svg/moon-icon.svg")}\n ${l("Large Text","Increase font size","large-text","/shared/images/svg/text-icon.svg")}\n ${l("Focus Text","Highlight text as you scroll","focus-text","/shared/images/svg/eye-icon.svg")}\n ${l("Narrow Width","Make width of text narrow","narrow-width","/shared/images/svg/width-icon.svg")}\n </div>\n `;const i={"focus-text":document.querySelector(".focus-text-wrapper"),"dark-mode":document.querySelector(".dark-mode-wrapper"),"large-text":document.querySelector(".large-text-wrapper"),"narrow-width":document.querySelector(".narrow-width-wrapper"),"view-options":document.querySelectorAll(".focus-text-wrapper, .dark-mode-wrapper, .large-text-wrapper, .narrow-width-wrapper")};for(const e in i)if(null==t?void 0:t.hasAttribute(e)){const t=i[e];"view-options"===e?t.forEach((e=>{e instanceof HTMLElement&&(e.style.display="grid")})):t instanceof HTMLElement&&(t.style.display="grid")}((null==t?void 0:t.hasAttribute("view-options"))&&(document.querySelector("#second-column")||document.querySelector("#third-column"))||window.innerWidth<768)&&i["narrow-width"]&&(i["narrow-width"].style.display="none");const c=document.querySelector(".view-options-switches > button"),s=["#focus-text-btn","#dark-mode-btn","#large-text-btn","#narrow-width-btn"].map((e=>document.querySelector(e)));function a(t){t.stopPropagation(),e=!e,r.classList.toggle("expand-panel"),s.forEach((t=>null==t?void 0:t.setAttribute("tabindex",e?"1":"-1")))}null==c||c.addEventListener("click",a),null==c||c.addEventListener("keydown",(e=>{"Enter"!==e.key&&13!==e.keyCode||(e.preventDefault(),a(e))})),document.addEventListener("click",(t=>{!e||r.contains(t.target)||(null==c?void 0:c.contains(t.target))||a(t)}))}},6289:(e,t)=>{function o(e,t){e.nodeType===Node.TEXT_NODE&&""!==e.textContent.trim()?(e.textContent.split(" ").forEach((o=>{if(""!==o){const n=document.createElement("span");n.textContent=o+" ",t.observe(n),e.parentNode?e.parentNode.insertBefore(n,e):console.warn("Document error: parent node not found for text node")}})),e.parentNode?e.parentNode.removeChild(e):console.warn("Document error: parent node not found to remove text node")):e.nodeType===Node.ELEMENT_NODE&&Array.from(e.childNodes).forEach((e=>{o(e,t)}))}function n(e){if(e.nodeType===Node.ELEMENT_NODE){const t=e;if("SPAN"!==t.tagName||"focus-text"!==t.className&&""!==t.className&&""!==t.textContent.trim()&&0!==t.attributes.length)Array.from(e.childNodes).forEach((e=>{n(e)}));else{const e=document.createTextNode(t.textContent);t.parentNode?(t.parentNode.insertBefore(e,t),t.parentNode.removeChild(t)):console.warn("Document error: parent node not found for span element")}}}Object.defineProperty(t,"__esModule",{value:!0}),t.focusText=t.removeSpans=t.traverseAndWrapTextInSpans=t.toggleFocusText=t.options=void 0,t.options={root:null,rootMargin:"-48.9% 0px",threshold:0},t.toggleFocusText=function(e,t,r){if(e&&t){const e=t.querySelectorAll("#content-wrapper .content-body :is(p, li, dd, dt, blockquote)");0===e.length&&console.warn("Document error: no elements found to wrap for focus text"),e.forEach((e=>{o(e,r)}))}else t?n(t):console.warn("Document error: content wrapper element not found for removing spans")},t.traverseAndWrapTextInSpans=o,t.removeSpans=n,t.focusText=new IntersectionObserver((e=>{e.forEach((e=>{const t=e.target.closest("span");t?e.isIntersecting?t.classList.add("focus-text"):t.classList.remove("focus-text"):console.warn("Document error: closest span not found for intersection observer entry")}))}),t.options)},2692:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.callFocusText=void 0;const n=o(6289);t.callFocusText=function(){let e=!1;const t=document.querySelector("#content-wrapper"),o=document.querySelector("#focus-text-btn");function r(){e=!e,t?t.toggleAttribute("focus-on",e):console.warn("Document error: content wrapper element not found"),o?(o.setAttribute("aria-checked",e.toString()),o.innerHTML=e?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>'):console.warn("Document error: focus text switch element not found"),(0,n.toggleFocusText)(e,t,n.focusText)}o?(o.addEventListener("click",(e=>{e.stopPropagation(),r()})),o.addEventListener("keydown",(e=>{"Enter"!==e.key&&13!==e.keyCode||(e.preventDefault(),r())}))):console.warn("Document error: focus text switch element is missing - event listeners not added")}},5207:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.processElements=t.getLargeTextElementsSelectors=t.adjustParagraphMargins=t.wordSpacing=t.lineHeight=t.lgFont=t.mdFont=void 0,t.mdFont=4,t.lgFont=6,t.lineHeight=1.5,t.wordSpacing=.16,t.adjustParagraphMargins=function(e){document.querySelectorAll(".content-body p, .content-body > h3").forEach((t=>{e?(t.dataset.originalMarginBottom=t.style.marginBottom,t.style.marginBottom="1em"):t.style.marginBottom=t.dataset.originalMarginBottom||""}))},t.getLargeTextElementsSelectors=function(e){const t=".header :is(h1, p), .content-body :is(h2, h3, h4, h5, h6, p:not(table p), li, a:not(table a), blockquote, figcaption, .front, .overlay, .back, dt, dd, span), footer *, #footer p",o="td, th, label";return{largeTextElements:e.querySelectorAll(t),smallerTextElements:e.querySelectorAll(o),largeTextSelectors:t,smallerTextSelectors:o}},t.processElements=function(e,t,o,n,r,l,i,c,s){e.forEach((e=>{if(!e)return;let a=e.parentElement;for(;a&&!a.matches(t?s:c);)a=a.parentElement;if(!a)if(o){const o=window.getComputedStyle(e);e.dataset.originalFontSize=o.fontSize,e.dataset.originalLineHeight=o.lineHeight,e.dataset.originalWordSpacing=o.wordSpacing;const c=parseFloat(o.fontSize)+(t?n:r);e.style.fontSize=`${c}px`,e.style.lineHeight=`${l}`,e.style.wordSpacing=`${i}em`}else e.removeAttribute("style"),e.removeAttribute("data-original-margin-bottom"),e.removeAttribute("data-original-font-size"),e.removeAttribute("data-original-line-height"),e.removeAttribute("data-original-word-spacing")}))}},9191:(e,t,o)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.callLargeText=void 0;const n=o(6079),r=o(5207);t.callLargeText=function(){let e=!1;const t=document.querySelector("#large-text-btn");function o(){if(e=!e,!n.courseBody)return void console.warn("Document error: content wrapper element not found");n.courseBody.toggleAttribute("large-text-on",e),(0,r.adjustParagraphMargins)(e);const{largeTextElements:o,smallerTextElements:l,largeTextSelectors:i,smallerTextSelectors:c}=(0,r.getLargeTextElementsSelectors)(n.courseBody);(0,r.processElements)(l,!0,e,r.mdFont,r.lgFont,r.lineHeight,r.wordSpacing,i,c),(0,r.processElements)(o,!1,e,r.mdFont,r.lgFont,r.lineHeight,r.wordSpacing,i,c),t.setAttribute("aria-checked",e.toString()),t.innerHTML=e?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>'}t?(t.addEventListener("click",(e=>{e.stopPropagation(),o()})),t.addEventListener("keydown",(e=>{"Enter"!==e.key&&13!==e.keyCode||(e.preventDefault(),o())}))):console.warn("Document error: large text switch element is missing - event listeners not added")}},3966:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.callNarrowWidth=void 0,t.callNarrowWidth=function(){let e=!1;const t=document.querySelector("#content-wrapper"),o=document.querySelector("#narrow-width-btn");function n(){e=!e,t?t.toggleAttribute("narrow-on",e):console.warn("Document error: content wrapper element not found"),o?(o.setAttribute("aria-checked",e.toString()),o.innerHTML=e?'<i class="fas fa-toggle-on"></i>':'<i class="fas fa-toggle-off"></i>'):console.warn("Document error: narrow width switch element not found")}o?(o.addEventListener("click",(e=>{e.stopPropagation(),n()})),o.addEventListener("keydown",(e=>{"Enter"!==e.key&&13!==e.keyCode||(e.preventDefault(),n())}))):console.warn("Document error: narrow width switch element is missing - event listeners not added")}}},t={};!function o(n){var r=t[n];if(void 0!==r)return r.exports;var l=t[n]={exports:{}};return e[n].call(l.exports,l,l.exports,o),l.exports}(7080)})();
|