PageSourceSearch

https://peerj.com/js/05779bd-a411a7a.js

js peerj.com collected 2026-09-24 07:44:04 UTC 28,131 bytes, 687 lines download raw bytes

1PeerJ.Tools.accessibility = (function () {
2    /**
3     * Minified by jsDelivr using Terser v5.19.2.
4     * Original file: /npm/[email protected]/src/color-contrast-checker.js
5     *
6     * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
7     */
8    function ColorContrastChecker() {
9    }
10
11    ColorContrastChecker.prototype = {
12        fontSize: 14, rgbClass: {
13            toString: function () {
14                return "<r: " + this.r + " g: " + this.g + " b: " + this.b + " >"
15            }
16        }, isValidSixDigitColorCode: function (t) {
17            return /^(#)?([0-9a-fA-F]{6})?$/.test(t)
18        }, isValidThreeDigitColorCode: function (t) {
19            return /^(#)?([0-9a-fA-F]{3})?$/.test(t)
20        }, isValidColorCode: function (t) {
21            return this.isValidSixDigitColorCode(t) || this.isValidThreeDigitColorCode(t)
22        }, isValidRatio: function (t) {
23            return "number" == typeof t
24        }, convertColorToSixDigit: function (t) {
25            return "#" + t[1] + t[1] + t[2] + t[2] + t[3] + t[3]
26        }, hexToLuminance: function (t) {
27            if (!this.isValidColorCode(t)) throw new Error("Invalid Color :" + t);
28            this.isValidThreeDigitColorCode(t) && (t = this.convertColorToSixDigit(t)), t = this.getRGBFromHex(t);
29            var i = this.calculateLRGB(t);
30            return this.calculateLuminance(i)
31        }, check: function (t, i, r, o) {
32            if (void 0 !== r && (this.fontSize = r), !t || !i) return !1;
33            var e = this.hexToLuminance(t), n = this.hexToLuminance(i), s = this.getContrastRatio(e, n);
34            return void 0 !== o ? !!this.isValidRatio(o) && this.verifyCustomContrastRatio(s, o) : this.verifyContrastRatio(s)
35        }, checkPairs: function (t, i) {
36            var r = [];
37            for (var o in t) {
38                var e = t[o];
39                void 0 !== e.fontSize ? r.push(this.check(e.colorA, e.colorB, e.fontSize, i)) : r.push(this.check(e.colorA, e.colorB, void 0, i))
40            }
41            return r
42        }, calculateLuminance: function (t) {
43            return .2126 * t.r + .7152 * t.g + .0722 * t.b
44        }, isLevelAA: function (t, i, r) {
45            return this.check(t, i, r).WCAG_AA
46        }, isLevelAAA: function (t, i, r) {
47            return this.check(t, i, r).WCAG_AAA
48        }, isLevelCustom: function (t, i, r) {
49            return this.check(t, i, void 0, r).customRatio
50        }, getRGBFromHex: function (t) {
51            var i, r, o, e = Object.create(this.rgbClass);
52            if ("string" != typeof t) throw new Error("must use string");
53            return i = parseInt(t.slice(1, 3), 16), r = parseInt(t.slice(3, 5), 16), o = parseInt(t.slice(5, 7), 16), e.r = i, e.g = r, e.b = o, e
54        }, calculateSRGB: function (t) {
55            var i, r = Object.create(this.rgbClass);
56            for (i in t) t.hasOwnProperty(i) && (r[i] = parseFloat(t[i] / 255, 10));
57            return r
58        }, calculateLRGB: function (t) {
59            var i, r = this.calculateSRGB(t), o = Object.create(this.rgbClass), e = 0;
60            for (i in r) r.hasOwnProperty(i) && (e = parseFloat(r[i], 10), o[i] = e <= .03928 ? e / 12.92 : Math.pow((e + .055) / 1.055, 2.4));
61            return o
62        }, getContrastRatio: function (t, i) {
63            var r, o;
64            return t >= i ? (r = t, o = i) : (r = i, o = t), (r + .05) / (o + .05)
65        }, verifyContrastRatio: function (t) {
66            var i = Object.create({
67                toString: function () {
68                    return "< WCAG-AA: " + (this.WCAG_AA ? "pass" : "fail") + " WCAG-AAA: " + (this.WCAG_AAA ? "pass" : "fail") + " >"
69                }
70            });
71            return (this.fontSize || 14) >= 18 ? (i.WCAG_AA = t >= 3, i.WCAG_AAA = t >= 4.5) : (i.WCAG_AA = t >= 4.5, i.WCAG_AAA = t >= 7), i
72        }, verifyCustomContrastRatio: function (t, i) {
73            var r = Object.create({
74                toString: function () {
75                    return "< Custom Ratio: " + (this.customRatio ? "pass" : "fail") + "  >"
76                }
77            });
78            return r.customRatio = t >= i, r
79        }
80    };
81
82    function useAccessibilityComposable(classExemptions = []) {
83        var ccc = new ColorContrastChecker();
84
85        function addAriaLabelsToMdiButtons(
86            buttons = document.querySelectorAll('button, .v-btn')) {
87            buttons.forEach(function (button) {
88                if (button.hasAttribute('aria-label')) return;
89
90                var mdiClass = Array
91                    .from(button.classList)
92                    .find(function (className) {
93                        return className.includes('mdi-');
94                    });
95
96                if (!mdiClass) {
97                    var iconElement = button.querySelector('[class*="mdi-"]');
98
99                    if (iconElement) {
100                        mdiClass = Array.from(iconElement.classList).find(function (className) {
101                            return className.includes('mdi-');
102                        });
103                    }
104                }
105
106                if (mdiClass) {
107                    var iconName = mdiClass.split('mdi-')[1];
108                    var readableLabel = iconName.replace(/-/g, ' ');
109                    button.setAttribute('aria-label', checkForConventionalIcons(readableLabel));
110                }
111            });
112        }
113
114        function addAriaLabelsToLegacyButtons(
115            buttons = document.querySelectorAll('button.btn')) {
116            buttons.forEach(function (button) {
117                if (button.hasAttribute('aria-label')) return;
118
119                if (button.hasAttribute('id')) {
120                    button.setAttribute(
121                        'aria-label',
122                        button.getAttribute('id')
123                            .replace(/-/g, ' ')
124                            .replace('landing ', ''));
125                }
126            })
127        }
128
129        function parentHasClass(img, clazz) {
130            return img.tagName.toLowerCase() === 'img' &&
131                img.parentElement &&
132                img.parentElement.classList &&
133                img.parentElement.classList.contains(clazz)
134        }
135
136        function subjectUsers(img) {
137            if (parentHasClass(img, 'subject-user-image')) {
138                if (img.parentElement &&
139                    img.parentElement.nextElementSibling &&
140                    img.parentElement.nextElementSibling.classList &&
141                    img.parentElement.nextElementSibling.classList.contains('subject-user-info'))
142                    var userName = img.parentElement.nextElementSibling.querySelector('.subject-user-name')
143                return userName ? [0, userName.innerText] : null
144            }
145            return null
146        }
147
148        function addAltTextToImages() {
149            var images = document.querySelectorAll('img');
150            // var regex = /\/([a-z]+-[a-z]+)-\d+\.[^\.]+$/;
151            var regex = /\/([A-Za-z]+(?:[-_][A-Za-z]+)*)\.[^.]+$/
152
153            images.forEach(function (img) {
154                var r = null
155
156                switch (true) {
157                    case !!img.classList && img.classList.contains('benefits-inline-image'):
158                        img.setAttribute('aria-hidden', true)
159                        break
160
161                    case !img.hasAttribute('alt') && !!subjectUsers(img):
162                        r = subjectUsers(img) || regex.exec(img.src)
163                        break
164
165                    case !img.hasAttribute('alt'):
166                        r = regex.exec(img.src)
167                        break
168                }
169
170                if (r) {
171                    const quoteMessage = parentHasClass(img, 'boxout-quote') ? ' Quote from: ' : ': '
172
173                    img.setAttribute(
174                        'alt',
175                        'Image containing' +
176                        quoteMessage +
177                        r[1].replace(/^e_/, '')
178                            .replace(/[-_]/g, ' ')
179                    )
180                }
181            })
182        }
183
184        function addAriaLabelsToInputs() {
185            const inputs = document.querySelectorAll('input')
186
187            inputs.forEach(function (input) {
188                if (input.hasAttribute('placeholder')) {
189                    input.setAttribute(
190                        'aria-label',
191                        input.getAttribute('placeholder')
192                    )
193                } else if (input.hasAttribute('id')) {
194                    input.setAttribute(
195                        'aria-label',
196                        input.getAttribute('id').replace(/-/g, '')
197                    )
198                }
199            })
200        }
201
202        function checkForConventionalIcons(label) {
203            switch (label) {
204                case 'weather night':
205                    return 'dark/light mode toggle';
206                case 'cog':
207                    return 'settings';
208                case 'pencil':
209                    return 'edit';
210                case 'plus':
211                    return 'add';
212                case 'trash can':
213                case 'trash can outline':
214                    return 'remove';
215                case 'mdi eye':
216                case 'mdi eye outline':
217                    return 'show';
218                case 'mdi eye off':
219                case 'mdi eye off-outline':
220                case 'mdi eye closed':
221                    return 'hide';
222            }
223            return label;
224        }
225
226        function removeStyleAttributeAlpha(element, attrName) {
227            var style = window.getComputedStyle(element);
228            if (style[attrName].includes('rgba')) {
229                var colors = style[attrName].match(/[+-]?(\d*\.)?\d+/g);
230                colors.pop();
231                element.style[attrName] = 'rgb(' + colors.toString() + ')';
232            }
233        }
234
235        function isolateRGBChannels(style) {
236            var matches = style ? style.match(/[+-]?(\d*\.)?\d+/g) : null;
237            return matches ? matches.map(function (it) {
238                return parseInt(it);
239            }) : [255, 255, 255];
240        }
241
242        function rgbToHex(rgb) {
243            return '#' + ((1 << 24) + (rgb[0] << 16) + (rgb[1] << 8) + rgb[2]).toString(16).slice(1);
244        }
245
246        function adjustFontChannels(params) {
247            var rCol = params.rCol;
248            var bgCol = params.bgCol;
249
250            for (var j = 0; j < 3; j++) {
251                if (rCol[j] <= bgCol[j]) rCol[j] -= !rCol[j] ? 0 : 1;
252                else rCol[j] += rCol[j] === 255 ? 0 : 1;
253            }
254
255            return {rCol: rCol, bgCol: bgCol};
256        }
257
258        function maxFontChannel(params, root) {
259            var rCol = params.rCol;
260            var bgCol = params.bgCol;
261
262            for (var j = 0; j < 3; j++) {
263                if (rCol[j] <= 128) rCol[j] = 0;
264                else rCol[j] = 255;
265            }
266
267            root.style.setProperty('color', rgbToHex(rCol), 'important');
268            return {rCol: rCol, bgCol: bgCol};
269        }
270
271        function adjustBgChannels(params, bgEl) {
272            var rCol = params.rCol;
273            var bgCol = params.bgCol;
274            var success = false;
275
276            for (var i = 0; i < 256; i++) {
277                for (var j = 0; j < 3; j++) {
278                    if (rCol[j] <= 128) {
279                        bgCol[j] += bgCol[j] === 255 ? 0 : 1;
280                    } else {
281                        bgCol[j] -= !bgCol[j] ? 0 : 1;
282                    }
283                }
284
285                if (ccc.isLevelCustom(rgbToHex(rCol), rgbToHex(bgCol), 7.1)) {
286                    bgEl.style.setProperty('background-color', rgbToHex(bgCol), 'important');
287                    success = true;
288                    break;
289                }
290            }
291
292            if (!success) {
293                for (var j = 0; j < 3; j++) {
294                    if (rCol[j] < 128) bgCol[j] = 255;
295                    else bgCol[j] = 0;
296                }
297                bgEl.style.setProperty('background-color', rgbToHex(bgCol), 'important');
298            }
299        }
300
301        function isInsideButton(node) {
302            var current = node;
303            while (current) {
304                if (current.tagName === 'BUTTON' ||
305                    (current.getAttribute && current.getAttribute('role') === 'button')) {
306                    return true;
307                }
308                current = current.parentElement;
309            }
310            return false;
311        }
312
313        function testAndRepairContrast(root, bgEl) {
314            var rStyle = window.getComputedStyle(root);
315            var bgStyle = window.getComputedStyle(bgEl);
316
317            var rCol = isolateRGBChannels(rStyle.color);
318            var bgCol = isolateRGBChannels(bgStyle.backgroundColor);
319            var success = false;
320
321            if (!ccc.isLevelAAA(rgbToHex(rCol), rgbToHex(bgCol), rStyle.fontSize)) {
322                if (rCol.length >= 3 && bgCol.length >= 3) {
323                    for (var i = 0; i < 256; i++) {
324                        var out = adjustFontChannels({rCol: rCol, bgCol: bgCol});
325
326                        if (ccc.isLevelCustom(rgbToHex(out.rCol), rgbToHex(bgCol), 7.1)) {
327                            root.style.setProperty('color', rgbToHex(out.rCol), 'important');
328                            if (!isInsideButton(root)) {
329                                bgEl.style.setProperty('background-color', rgbToHex(out.bgCol), 'important');
330                            }
331                            success = true;
332                            break;
333                        }
334                    }
335                    if (!success) {
336                        adjustBgChannels(
337                            maxFontChannel({rCol: rCol, bgCol: bgCol}, bgEl),
338                            bgEl);
339                    }
340                } else {
341                    console.error('Root and/or BG Element have invalid channels, (root, element:)', root, bgEl);
342                }
343            }
344        }
345
346        function manageContrast(rootElement) {
347            var walker = document.createTreeWalker(
348                rootElement,
349                NodeFilter.SHOW_TEXT,
350                null,
351                false
352            );
353
354            var firstPass = true;
355            var textnode;
356
357            while (textnode = walker.nextNode()) {
358                if (textnode.parentElement) {
359                    var currentElement = textnode.parentElement;
360                    var bgElement = null;
361
362                    while (currentElement && currentElement !== rootElement.parentElement) {
363                        var style = window.getComputedStyle(currentElement);
364                        if (style.backgroundColor !== 'rgba(0, 0, 0, 0)') {
365                            bgElement = currentElement;
366                            break;
367                        }
368                        currentElement = currentElement.parentElement;
369                    }
370
371                    if (!bgElement) {
372                        bgElement = rootElement;
373                        if (firstPass) {
374                            bgElement.style.backgroundColor = 'rgb(255,255,255)';
375                        }
376                    }
377                    if (!classExemptions.some(className => bgElement.classList.contains(className))) {
378                        removeStyleAttributeAlpha(bgElement, 'background-color');
379                        removeStyleAttributeAlpha(textnode.parentElement, 'color');
380                        testAndRepairContrast(textnode.parentElement, bgElement);
381                    }
382
383                    firstPass = false;
384                }
385            }
386        }
387
388        function assignDOTToAriaLabel() {
389            var aTags = $('a[data-original-title]:not([aria-label])')
390
391            aTags.each(function () {
392                var originalTitle = $(this).attr('data-original-title');
393                $(this).attr('aria-label', originalTitle);
394                if (originalTitle === 'Cite this object using this DOI') {
395                    $(this).attr('aria-label', originalTitle + ': ' + $(this).text())
396                } else $(this).attr('aria-label', originalTitle);
397            });
398        }
399
400        function assignAriaLabelToAuthors() {
401            var aTags = $('div.article-authors > .contrib a')
402            aTags.each(function () {
403                if ($(this).attr('rel') === 'author') {
404                    $(this).attr('aria-label', 'Link to profile of: ' + $(this).text())
405                } else if ($(this).attr('data-original-title')) {
406                    $(this).attr('aria-label', 'send email to: ' + $(this).attr('href').replace(/^mailto:/, ''))
407                } else if ($(this).attr('itemprop') === 'affiliation') {
408                    $(this).attr('aria-label', 'link to author\'s affiliation details, no. ' + $(this).text())
409                }
410            });
411
412            var spanTag = $('div.article-authors > .contrib span')
413            spanTag.each(function () {
414                $(this)
415                    .attr('role', 'tooltip')
416                    .attr('aria-description', $(this).attr('data-original-title'))
417            })
418        }
419
420        function createSkipToMainContentLink() {
421            var newElement = document.createElement('a');
422            newElement.textContent = 'Skip to main content';
423            newElement.setAttribute('aria-label', 'Skip to main content')
424            newElement.className = 'SkipToMainContent'; // Use className for ES5 compatibility
425            newElement.href = '#MainContent'
426            return newElement
427        }
428
429        function skipToJournalLandingPage(el, toolbar) {
430            var targetElement = el
431            window.history.replaceState(null, null, '#MainContentJournal');
432            targetElement.setAttribute('tabindex', '0'); // Make the element focusable
433            targetElement.focus(); // Programmatically move focus
434
435            setTimeout(function () {
436                window.scrollTo({top: targetElement.offsetTop - toolbar.offsetHeight,});
437            }, 150)
438            return targetElement
439        }
440
441        function skipToOAMetaPage(el) {
442            var targetElement = el
443            targetElement.setAttribute('tabindex', '0'); // Make the element focusable
444            targetElement.focus(); // Programmatically move focus
445            window.history.replaceState(null, null, '#MainContentVue');
446
447            setTimeout(function () {
448                window.scrollTo({top: 0});
449            }, 250)
450            return targetElement
451        }
452
453        function skipToHubHomePage(el, toolbar) {
454            var targetElement = el
455            targetElement.setAttribute('tabindex', '0'); // Make the element focusable
456            targetElement.focus(); // Programmatically move focus
457            window.history.replaceState(null, null, '#MainContentHubsHome');
458
459            setTimeout(function () {
460                window.scrollTo({top: toolbar.offsetHeight - 50,});
461            }, 150)
462            return targetElement
463        }
464
465        function skipToHomePage(el) {
466            var targetElement = el
467            targetElement.setAttribute('tabindex', '0'); // Make the element focusable
468            targetElement.focus(); // Programmatically move focus
469            window.history.replaceState(null, null, '#MainContentVue');
470
471            setTimeout(function () {
472                window.scrollTo({
473                    top: document.querySelector('.HomeHeader').offsetHeight
474                });
475            }, 150)
476            return targetElement
477        }
478
479        function skipToVuePageContent(el, toolbar) {
480            targetElement = el
481            targetElement.setAttribute('tabindex', '0'); // Make the element focusable
482            targetElement.focus(); // Programmatically move focus
483            window.history.replaceState(null, null, '#MainContentVue');
484
485            setTimeout(function () {
486                window.scrollTo({top: toolbar.offsetHeight,});
487            }, 150)
488            return targetElement
489        }
490
491        function skipToLegacyPageContent(el, toolbar) {
492            var targetElement = el
493            window.history.replaceState(null, null, '#MainContent');
494            targetElement.setAttribute('tabindex', '0'); // Make the element focusable
495            targetElement.setAttribute('role', 'main')
496            targetElement.focus(); // Programmatically move focus
497            setTimeout(function () {
498                window.scrollTo({top: targetElement.offsetTop - toolbar.offsetHeight,});
499            }, 150)
500            return targetElement
501        }
502
503        function handleSkipToMainContentScroll(event = null, hash = '#MainContent') {
504            if (event) event.preventDefault(); // Prevent default behavior
505            var targetElement = document.querySelector(hash);
506            var toolbar = document.querySelector('.v-toolbar__content');
507
508            if (targetElement) {
509                switch (true) {
510                    // journal landing pages
511                    case !!document.querySelector('.journal-landing-title-header'):
512                        console.log(1)
513                        targetElement = skipToJournalLandingPage(
514                            document.querySelector('.journal-landing-title-header'),
515                            toolbar)
516                        break
517
518                    // Hubs Home
519                    case !!document.querySelector('#MainContentHubsHome'):
520                        targetElement = skipToHubHomePage(
521                            document.querySelector('#MainContentHubsHome'),
522                            toolbar)
523                        break
524
525                    // Open advances dynamic meta pages
526                    case !!document.querySelector('.mlp-dynamic-page'):
527                        targetElement = skipToOAMetaPage(document.querySelector('#MainContentVue'))
528                        break
529
530                    // home page
531                    case !!document.querySelector('#MainContentHome'):
532                        targetElement = skipToHomePage(document.querySelector('#MainContentHome'))
533                        break
534
535                    // Vue page catch all
536                    case !!document.querySelector('#MainContentVue > div > div'):
537                        targetElement = skipToVuePageContent(
538                            document.querySelector('#MainContentVue'),
539                            toolbar)
540                        break
541
542                    // legacy page catch all
543                    default:
544                        targetElement = skipToLegacyPageContent(targetElement, toolbar)
545                        break
546                }
547
548                // Remove tabindex after focus is moved to restore natural tab order
549                targetElement.addEventListener('blur', function () {
550                    targetElement.removeAttribute('tabindex');
551                }, {once: true});
552            }
553        }
554
555        function skipToMainContentLink() {
556            var newElement = createSkipToMainContentLink()
557
558            // Add event listeners for all possible interactions
559            newElement.addEventListener('click', handleSkipToMainContentScroll); // Handle mouse click
560            newElement.addEventListener('mousedown', handleSkipToMainContentScroll); // Handle mouse down
561            newElement.addEventListener('keydown', function (event) {
562                if (event.key === 'Enter' || event.key === ' ') { // Handle Enter and Space keys
563                    handleSkipToMainContentScroll(event);
564                }
565            });
566
567            // Insert the element at the start of the <body>
568            document.body.insertBefore(newElement, document.body.firstChild);
569        }
570
571        function setMainRole() {
572            var targetElement
573
574            switch (true) {
575                // journal landing pages
576                case !!document.querySelector('#MainContentJournal'):
577                    targetElement = document.querySelector('#MainContentJournal')
578                    break
579
580                // Hubs Home
581                case !!document.querySelector('#MainContentHubsHome'):
582                    targetElement = document.querySelector('#MainContentHubsHome')
583                    break
584
585                // Open advances dynamic meta pages
586                case !!document.querySelector('.mlp-dynamic-page'):
587                    targetElement = document.querySelector('#MainContentVue')
588                    break
589
590                // home page
591                case !!document.querySelector('#MainContentHome'):
592                    targetElement = document.querySelector('#MainContentHome')
593                    break
594
595                // Vue page catch all
596                case !!document.querySelector('#MainContentVue > div > div'):
597                    targetElement = document.querySelector('#MainContentVue')
598                    break
599
600                // legacy page catch all
601                default:
602                    targetElement = document.querySelector('#MainContent');
603                    break
604            }
605
606            if (targetElement) targetElement.setAttribute('role', 'main')
607        }
608
609        return {
610            assignAriaLabelToAuthors: assignAriaLabelToAuthors,
611            manageContrast: manageContrast,
612            addAriaLabelsToMdiButtons: addAriaLabelsToMdiButtons,
613            addAriaLabelsToLegacyButtons: addAriaLabelsToLegacyButtons,
614            addAltTextToImages: addAltTextToImages,
615            addAriaLabelsToInputs: addAriaLabelsToInputs,
616            assignDOTToAriaLabel: assignDOTToAriaLabel,
617            skipToMainContentLink: skipToMainContentLink,
618            handleSkipToMainContentScroll: handleSkipToMainContentScroll,
619            setMainRole: setMainRole,
620        };
621    }
622
623    return useAccessibilityComposable([
624        'self-citation',
625        'self-citation-elocation',
626        'alert-info',
627        'xref',
628        'xref-bibr',
629        'subject-btn-unfollow',
630        'activity-summary',
631        'offline-share',
632        'bluesky-share',
633        'fb-share',
634        'payment-notice-content',
635        'article-recommendation',
636        'peerj-paper-form',
637        'previous-reviews',
638        'previous-review-head',
639        'previous-review',
640        'article-revision-current',
641        'article-status-header',
642        'tag-coi-pass-ae',
643        'institutions-container',
644        'InstitutionSignupButton',
645        'card-type-reviewing',
646        'article-person-institution',
647        'tag-coi-pass-ae',
648    ]);
649})();
650
651$(document).ready(function () {
652    var articlePage = document.querySelector('.article-status-header')
653    var mainPadding = document.querySelector('.main-padding')
654    var publicationJsonData = document.querySelector('.publication-jsondata')
655    switch (true) {
656        case !!articlePage:
657            PeerJ.Tools.accessibility.manageContrast(articlePage)
658            PeerJ.Tools.accessibility.manageContrast(document.querySelector('#wrap > .container'))
659            break
660
661        case !!publicationJsonData:
662            var left = document.querySelector('.article-sidebar-left')
663            if (left) PeerJ.Tools.accessibility.manageContrast(left)
664            break
665
666        case !!mainPadding:
667            PeerJ.Tools.accessibility.manageContrast(mainPadding)
668            break;
669
670        default:
671            PeerJ.Tools.accessibility.manageContrast(document.querySelector('.container'))
672    }
673
674    PeerJ.Tools.accessibility.skipToMainContentLink()
675    PeerJ.Tools.accessibility.assignAriaLabelToAuthors(articlePage)
676    PeerJ.Tools.accessibility.addAltTextToImages()
677    PeerJ.Tools.accessibility.addAriaLabelsToInputs()
678    PeerJ.Tools.accessibility.addAriaLabelsToLegacyButtons()
679    PeerJ.Tools.accessibility.assignDOTToAriaLabel()
680    PeerJ.Tools.accessibility.setMainRole()
681
682    if (window.location.hash && window.location.pathname !== '/benefits/') {
683        setTimeout(function () {
684            PeerJ.Tools.accessibility.handleSkipToMainContentScroll(null, window.location.hash)
685        }, 2500)
686    }
687})

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.