PageSourceSearch

https://wcsoe.gov/wp-content/themes/hello-theme-child-elyk/js/Utils.js

js wcsoe.gov collected 2026-10-06 13:04:44 UTC 30,420 bytes, 813 lines download raw bytes

1/** USEFUL FRONTEND QUERY FUNCTIONALITY
2 * Last updated by Daniel Bage
3 * On 03/15/2017
4 *
5 * Last method added was swapChildElements
6 *
7 * METHODS
8 * addClassToLiWithExternalLinks
9 * addClassToLiWithPdfs
10 * addHvrClass
11 * addOrRemoveStackClass
12 * clearContentFromFooter
13 * clearContentFromHeader
14 * documentReady
15 * documentScrolled
16 * elementDistanceFromViewportrtbs
17 * externalLinksTargetBlank
18 * fadeIn
19 * fadeContentOnLink
20 * fixHeader
21 * fixFooter
22 * freeFooter
23 * isDevice
24 * getQueryVariable
25 * matchHeights
26 * matchHeightsOfEqualVerticalPosition
27 * matchHeightsOfSecondElement
28 * maximiseContentArea
29 * print_r
30 * removeEmptyElements
31 * responsiveTables
32 * restoreHeights
33 * stackCells
34 * swapChildElements
35 * swapElements
36 * tallestHeight
37 * viewportLoaded
38 * viewportOrientationChanged
39 * viewportResized
40 * viewportResizedFinished
41 * viewportWidth
42 *
43 */
44
45
46var Utils =
47    {
48        /**
49         * Enum for device names.
50         * @readonly
51         * @enum {string}
52         */
53        device: {
54            IPHONE5_PORTRAIT: 'IPHONE5 PORTRAIT',
55            GALAXY_PORTRAIT: 'GALAXY PORTRAIT',
56            IPHONE6_PORTRAIT: 'IPHONE6 PORTRAIT',
57            CELL_PORTRAIT: 'CELL PORTRAIT',
58            IPHONE4_LANDSCAPE: 'IPHONE4 LANDSCAPE',
59            IPHONE5_LANDSCAPE: 'IPHONE5 LANDSCAPE',
60            GALAXY_LANDSCAPE: 'GALAXY LANDSCAPE',
61            IPHONE6_LANDSCAPE: 'IPHONE6 LANDSCAPE',
62            CELL: 'CELL',
63            SMALL_DESKTOP: 'SMALL DESKTOP',
64            TABLET_PORTRAIT: 'TABLET PORTRAIT',
65            TABLET: 'TABLET',
66            DESKTOP: 'DESKTOP'
67        },
68        /**
69         * @description Add .pdf to li elements that contain links to PDFS
70         */
71        addClassToLiWithPdfs: function () {
72            jQuery('[href$= ".pdf"]').each(function () {
73                jQuery(this).parent('li').addClass('contains_pdf');
74            });
75        },
76        /**
77         * @description Add .external_link to li elements that contain links to external web pages
78         */
79        addClassToLiWithExternalLinks: function () {
80            jQuery('.external_link').each(function () {
81                jQuery(this).parent('li').addClass('contains_external_link');
82            });
83        },
84        addHvrClass: function (hoverType, elemString) {
85            /*hoverTypes:
86             grow, shrink,
87             pulse, pulse-grow, pulse-shrink,
88             push, pop,
89             bounce-in, bounce-out,
90             rotate, grow-rotate,
91             float, sink, bob, hang,
92             skew, skew-forward, slew-backward,
93             wobble-horizontal, wobble-vertical, wobble-to-bottom-right, wobble-to-top-right, wobble-top, wobble-bottom, wobble-skew
94             buzz, buzz-out
95
96             see http://ianlunn.github.io/Hover/ for more
97             */
98            jQuery(elemString).each(function () {
99                jQuery(this).addClass('hvr-' + hoverType).css('cursor', 'pointer');
100            });
101        },
102        /**
103         * @description Add padding to top of content area, equal to header height
104         * @param {string} [headerElem = '#headerwrap'] Header area element
105         * @param {string} [contentElem = '#contentwrap'] Content area element
106         */
107        clearContentFromHeader: function (headerElem, contentElem) {
108            //defaults
109            var header = jQuery('#headerwrap');
110            var content = jQuery('#middlewrap');
111
112            //overwrite if provided
113            if (typeof headerElem !== 'undefined') {
114                header = jQuery(headerElem);
115            }
116            if (typeof contentElem !== 'undefined') {
117                content = jQuery(contentElem);
118            }
119
120            //add css
121            content.css('padding-top', header.outerHeight());
122        },
123        /**
124         * @description Add padding to bottom of content area, equal to footer height
125         * @param {string} [contentElem = '#middlewrap'] Content area element
126         * @param {string} [footerElem = '#footerwrap'] Footer area element
127         */
128        clearContentFromFooter: function (contentElem, footerElem) {
129            //defaults
130            var content = jQuery('#middlewrap');
131            var footer = jQuery('#footerwrap');
132
133            //overwrite if provided
134            if (typeof contentElem !== 'undefined') {
135                content = jQuery(contentElem);
136            }
137            if (typeof footerElem !== 'undefined') {
138                footer = jQuery(footerElem);
139            }
140
141            //add css
142            content.css('padding-bottom', footer.outerHeight());
143        },
144        /**
145         * @description Once document is ready, perform callback
146         * @param {function} [callback] Callback for document ready
147         */
148        documentReady: function (callback) {
149            jQuery(document).ready(callback);
150        },
151        /**
152         * @description Add 'scrolled' class to body when an element is a specified distance from the top of the viewport
153         * @param {int} [triggerDistance = -100] The distance the element is from the viewport top.
154         * @param {string} [triggerElement = #middlewrap] The element that acts as a trigger.
155         */
156        documentScrolled: function (triggerDistance, triggerElement) {
157            if (!triggerDistance) {
158                triggerDistance = -65;
159            }
160            if (!triggerElement) {
161                triggerElement = '#main';
162            }
163            // adding scrolled class
164            var headerClear = true;
165            var body = jQuery('body');
166            var timeout;
167
168            jQuery(window).scroll(function () {
169                    clearTimeout(timeout);
170
171                    var headerY = jQuery(triggerElement).offset().top;
172                    var scroll = headerY - jQuery(window).scrollTop();
173                    //console.log('Scroll: '+scroll);
174                    //console.log('triggerDistance" '+triggerDistance);
175                    if ((scroll < triggerDistance) && headerClear) {
176                        body.toggleClass('scrolled');
177                        headerClear = false;
178                    }
179                    else if ((scroll > triggerDistance) && !headerClear) {
180                        body.toggleClass('scrolled');
181                        headerClear = true;
182                    }
183                    if(scroll == 0){
184                        jQuery('body').removeClass('scrolled');
185                    }
186
187                    timeout = setTimeout(function () {
188                        // do your stuff
189                    }, 500);
190                }
191            )
192        },
193        /**
194         * @description Once viewport is loaded, perform callback
195         * @param {function} [callback] Callback for window load
196         */
197        viewportLoaded: function (callback) {
198            jQuery(window).load(callback);
199        },
200        /**
201         * @description Once orientation is changed, perform callback
202         * @param {function} [callback] Callback for orientation changed
203         */
204        viewportOrientationChanged: function (callback) {
205            window.addEventListener("orientationchange", callback, false);
206        },
207        /**
208         * @description As viewport is re-sized, perform callback
209         * @param {function} [callback] Callback for viewport resizing
210         */
211        viewportResized: function (callback) {
212            jQuery(window).resize(callback);
213        },
214        /**
215         * @description Once viewport resizing ends, perform callback
216         * @param {function} [callback] Callback for viewport resizing ending
217         */
218        viewportResizedFinished: function (callback) {
219            var resizeTimer;
220            jQuery(window).on('resize', function (e) {
221                clearTimeout(resizeTimer);
222                resizeTimer = setTimeout(function () {
223                    callback();
224                }, 250);
225            });
226        },
227        /**
228         * @description Pixel-less viewport width
229         * @returns {number} Viewport width
230         */
231        viewportWidth: function () {
232            var viewportWidth = jQuery(window).width();
233            return viewportWidth;
234        },
235        /**
236         * @description Set heights equally on source elements
237         * @param {string|JQuery} source The source elements to match heights of
238         * @param {boolean} [includeMargin = false] Whether to include element margins
239         */
240        matchHeights: function (source, includeMargin) {
241            if (typeof(includeMargin) === 'undefined') {
242                includeMargin = false;
243            }
244            var list = [];
245            if (jQuery.isArray(source)) {
246                list = source;
247            }
248            else {
249                list.push(source);
250            }
251
252            for (var i = 0; i < list.length; i++) {
253                var src = jQuery(list[i]);
254                var tgtHt = 0;
255                src.each(function () {
256                    if ((jQuery(this).outerHeight(includeMargin)) > tgtHt) {
257                        tgtHt = jQuery(this).outerHeight(includeMargin);
258
259                    }
260                });
261                jQuery(src).css('height', (tgtHt));
262            }
263        },
264        /**
265         * @description Return pixel-less value of tallest source element
266         * @param {string|JQuery} source The source elements to compare heights of
267         * @param {boolean} [includeMargin = false] Whether to include element margins
268         * @returns {number} Pixel-less height
269         */
270        tallestHeight: function (source, includeMargin) {
271            if (typeof(includeMargin) === 'undefined') {
272                includeMargin = false;
273            }
274            var list = [];
275            if (jQuery.isArray(source)) {
276                list = source;
277            }
278            else {
279                list.push(source);
280            }
281
282            for (var i = 0; i < list.length; i++) {
283                var src = jQuery(list[i]);
284                var tgtHt = 0;
285                src.each(function () {
286                    if ((jQuery(this).outerHeight(includeMargin)) > tgtHt) {
287                        tgtHt = jQuery(this).outerHeight(includeMargin);
288
289                    }
290                });
291                return tgtHt;
292            }
293        },
294        /**
295         * @description Remove all css heights from source elements
296         * @param {string|JQuery} source The source elements to remove css heights of
297         */
298        restoreHeights: function (source) {
299            var list = [];
300            if (jQuery.isArray(source)) {
301                list = source;
302            }
303            else {
304                list.push(source);
305            }
306            for (var i = 0; i < list.length; i++) {
307                jQuery(list[i]).css("height", "");
308            }
309        },
310        /**
311         * @description Set heights equally on source elements with same vertical position
312         * @param {string|JQuery} source The source elements to match
313         * @param {boolean} [includeMargin = false] Whether to include element margins
314         */
315        matchHeightsOfEqualVerticalPosition: function (source, includeMargin) {
316            if (typeof(includeMargin) === 'undefined') {
317                includeMargin = false;
318            }
319            var list = [];
320            if (jQuery.isArray(source)) {
321                list = source;
322            }
323            else {
324                list.push(source);
325            }
326            for (var i = 0; i < list.length; i++) {
327                var src = jQuery(list[i]);
328
329                var elementsWithEqualVerticalPositions = [];
330                var positionOfFirstElement = jQuery(src[0]).position();
331                var verticalPositionOfFirstElement = 0;
332                if (positionOfFirstElement) {
333                    verticalPositionOfFirstElement = positionOfFirstElement.top;
334                }
335                var y = 0;
336                jQuery.each(src, function () {
337
338                    var srcP = jQuery(this).position();
339                    var srcY = srcP.top;
340                    //console.log(srcY);
341                    if (srcY == y) {
342                        jQuery(this).addClass('match');
343                    }
344                    else {
345
346                        Utils.matchHeights('.match', includeMargin);
347                        srcP = jQuery(this).position();
348                        srcY = srcP.top;
349                        y = srcY;
350                        jQuery('.match').removeClass('match');
351                        jQuery(this).addClass('match');
352                    }
353                });
354
355                Utils.matchHeights('.match', includeMargin);
356                jQuery('.match').removeClass('match');
357            }
358        },
359        /**
360         * @description Make height of element A match element B
361         * @param {string} elementA The element to receive new height
362         * @param {string} elementB The element to match height of
363         * @param {boolean} [includeMargin = false] Whether to include the elementA margin
364         */
365        matchHeightsOfSecondElement: function (elementA, elementB, includeMargin) {
366            if (typeof(includeMargin) === 'undefined') {
367                includeMargin = false;
368            }
369            var heightOfSecondSource = jQuery(elementB).outerHeight(includeMargin);
370            jQuery(elementA).css('height', heightOfSecondSource);
371        },
372        /**
373         * @description Move element B infront of element A
374         * @param {string} elemA First Element
375         * @param {string} elemB Second element to be moved in front of first
376         */
377        swapElements: function (elemA, elemB) {
378            jQuery(elemA).before(jQuery(elemB));
379        },
380        /**
381         * @description Determine device based on viewport width
382         * @param {Utils.device} deviceName Device name
383         * @returns {boolean}
384         */
385        isDevice: function (deviceName) {
386            deviceName = deviceName.toUpperCase();
387            var width = jQuery(window).width();
388            if ((width < 321) && deviceName == Utils.device.IPHONE5_PORTRAIT) {
389                return true
390            }
391            else if ((width < 361) && deviceName == Utils.device.GALAXY_PORTRAIT) {
392                return true
393            }
394            else if ((width < 376) && deviceName == Utils.device.IPHONE6_PORTRAIT) {
395                return true
396            }
397            else if ((width < 481) && ((deviceName == Utils.device.CELL_PORTRAIT) || (deviceName == Utils.device.IPHONE4_LANDSCAPE))) {
398                return true
399            }
400            else if ((width < 569) && deviceName == Utils.device.IPHONE5_LANDSCAPE) {
401                return true
402            }
403            else if ((width < 641) && ((deviceName == Utils.device.GALAXY_LANDSCAPE))) {
404                return true
405            }
406            else if ((width < 667) && ((deviceName == Utils.device.IPHONE6_LANDSCAPE))) {
407                return true
408            }
409            else if ((width < 768) && ((deviceName == Utils.device.CELL))) {
410                return true
411            }
412            else if ((width < 769) && (width > 640) && deviceName == Utils.device.TABLET_PORTRAIT) {
413                return true
414            }
415            else if ((width < 1025) && (width > 736) && deviceName == Utils.device.TABLET) {
416                return true
417            }
418            else if ((width < 1280) && deviceName == Utils.device.SMALL_DESKTOP) {
419                return true
420            }
421            else if ((width > 1024) && deviceName == Utils.device.DESKTOP) {
422                return true
423            }
424            else {
425                return false
426            }
427        },
428        /**
429         * @description Once viewport finishes loading, fade in source element
430         * @param {string|JQuery} source Source element to fade in
431         * @param {number} [delay = 0] Delay before fade time in milliseconds
432         * @param {number} [fadeInTime = 0] Fade duration in milliseconds
433         */
434        fadeIn: function (source, delay, fadeInTime) {
435            var list = [];
436            if (jQuery.isArray(source)) {
437                list = source;
438            }
439            else {
440                list.push(source);
441            }
442            for (var i = 0; i < list.length; i++) {
443                jQuery(list[i]).each(function (index) {
444                    var item = jQuery(this);
445                    //item.css('opacity', 0);
446                    Utils.viewportLoaded(function () {
447                        item.delay(delay * index).animate({
448                            opacity: 1
449                        }, fadeInTime);
450                    });
451                });
452            }
453        },
454        /**
455         * @description content area fades out on navigation click
456         * @param {string} [triggerElement = .primary-menu li a] Elements that trigger the fade
457         * @param {string} [mainContentContainer = #middlewrap] Container element to be faded
458         */
459        fadeContentOnLink: function (triggerElement, mainContentContainer) {
460            if (!triggerElement) {
461                triggerElement = 'a';
462            }
463            if (!mainContentContainer) {
464                mainContentContainer = '#middlewrap';
465            }
466            jQuery(triggerElement).each(function () {
467                jQuery(this).click(function () {
468                    jQuery(mainContentContainer).animate({
469                        opacity: 0
470                    });
471                });
472            })
473        },
474        getQueryVariable: function (variable) {
475            var query = window.location.search.substring(1);
476            var vars = query.split("&");
477            for (var i = 0; i < vars.length; i++) {
478                var pair = vars[i].split("=");
479                if (pair[0] == variable) {
480                    return pair[1];
481                }
482            }
483            return (false);
484        },
485        addOrRemoveStackClass: function (commaSeperatedStringOfSelectors) {
486            var cellsToStack = jQuery(commaSeperatedStringOfSelectors);
487            cellsToStack.each(function () {
488                if (Utils.isDevice('CELL')) {
489                    jQuery(this).addClass('stack');
490                } else {
491                    jQuery(this).removeClass('stack');
492                }
493            })
494        },
495        stackCells: function (commaSeperatedStringOfSelectors) {
496            if (typeof commaSeperatedStringOfSelectors === 'undefined') {
497                commaSeperatedStringOfSelectors = '.cell';
498            }
499            Utils.documentReady(function () {
500                Utils.addOrRemoveStackClass(commaSeperatedStringOfSelectors);
501            });
502            Utils.viewportOrientationChanged(function () {
503                Utils.addOrRemoveStackClass(commaSeperatedStringOfSelectors);
504            });
505            Utils.viewportResized(function () {
506                Utils.addOrRemoveStackClass(commaSeperatedStringOfSelectors);
507            });
508        },
509        elementDistanceFromViewport: function (elem, side) {
510            var scroll = jQuery(window).scrollTop();
511            var elementOffset = jQuery(elem).parent().offset().top;
512            var windowHeight = jQuery(window).height();
513            var distance = '';
514
515            switch (side) {
516                case 'right':
517
518                    break;
519                case 'bottom':
520                    elementOffset = (jQuery(elem).offset().top);
521                    distance = Math.abs((windowHeight - elementOffset) - scroll);
522                    break;
523                case 'left':
524
525                    break;
526                default:
527                    distance = (elementOffset - scroll);
528            }
529            return distance
530        },
531        /**
532         * @description Fix the header to the top of the viewport
533         * @param {string} [header_elem = '#headerwrap']
534         */
535        fixHeader: function (header_elem) {
536            //defaults
537            var header = jQuery('#headerwrap');
538
539            //overwrite if provided
540            if (typeof header_elem !== 'undefined') {
541                header = jQuery(header_elem);
542            }
543
544            //set top based on logged in or not
545            var top = jQuery('#wpadminbar').outerHeight();
546
547            //add css
548            header.css({
549                'position': 'fixed',
550                'top': top,
551                'width': '100%',
552                'z-index': '3000',
553                'box-shadow': '0 0 10px #000000'
554            });
555
556            //clear content from header
557            this.clearContentFromHeader(header_elem);
558
559            var anchors = jQuery('.anchor');
560            var headerHeight = header.outerHeight();
561            var adminBarHeight = jQuery('#wpadminbar').outerHeight();
562            if (jQuery('body').hasClass('logged-in')) {
563                headerHeight += adminBarHeight;
564            }
565            ;
566            anchors.each(function () {
567                jQuery(this).css('top', -headerHeight);
568            });
569        }
570        ,
571        /**
572         * @description Fix the footer to the bottom of the viewport
573         * @param {string} [footer_elem = '#footerwrap']
574         */
575        fixFooter: function (footer_elem) {
576            //defaults
577            var footer = jQuery('#footerwrap');
578
579            //overwrite if provided
580            if (typeof footer_elem !== 'undefined') {
581                footer = jQuery(footer_elem);
582            }
583
584            //add css
585            footer.css({
586                'position': 'fixed',
587                'bottom': '0',
588                'width': '100%',
589                'z-index': '1'
590            });
591
592            //clear content from footer
593            this.clearContentFromFooter();
594        },
595        /**
596         * @description Remove footer css styling
597         * @param {string} [footer_elem = '#footerwrap'] Footer area element
598         */
599        freeFooter: function (footer_elem) {
600            //defaults
601            var footer = jQuery('#footerwrap');
602
603            //overwrite if provided
604            if (typeof footer_elem !== 'undefined') {
605                footer = jQuery(footer_elem);
606            }
607
608            //remove css
609            footer.removeAttr('style');
610        },
611        /**
612         * @description Maximise content area so it at least fills the viewport
613         * @param {string} [headerElem = '#header'] Header element
614         * @param {string} [contentElem = '#middlewrap'] Content element
615         * @param {string} [footerElem = '#footerwrap'] Footer element
616         */
617        maximiseContentArea: function (headerElem, contentElem, footerElem) {
618            //defaults
619            var header = jQuery('#headerwrap');
620            var content = jQuery('#middlewrap');
621            var footer = jQuery('#footerwrap');
622            var adminBar = jQuery('#wpadminbar');
623
624            //overwrite if provided
625            if (typeof headerElem !== 'undefined') {
626                header = jQuery(headerElem);
627            }
628            if (typeof contentElem !== 'undefined') {
629                content = jQuery(contentElem);
630            }
631            if (typeof footerElem !== 'undefined') {
632                footer = jQuery(footerElem);
633            }
634
635            //additional vars
636            var windowHeight = jQuery(window).height();
637            var headerHeight = header.outerHeight();
638            var footerHeight = footer.outerHeight();
639            var adminBarHeight = adminBar.outerHeight();
640
641            if ((header).css('position') == 'fixed') {
642                headerHeight = 0;
643            }
644
645            if ((footer).css('position') == 'fixed') {
646                footerHeight = 0;
647            }
648
649            //add css
650            content.css('min-height', windowHeight - headerHeight - footerHeight - adminBarHeight);
651        },
652        /**
653         * @description Adds target="_blank" to all links that leave the current domain
654         */
655        externalLinksTargetBlank: function () {
656            //get the domain
657            var domain = location.hostname + (location.port ? ':' + location.port : '');
658            var setTarget = true;
659            var target = null;
660
661            //loop through each link element that doesn't already have a target
662            jQuery('a:not([target])').each(function (index, element) {
663                setTarget = false;
664                target = null;
665
666                //if the link is javascript, don't mess with it
667                if (element.href.indexOf('javascript:') != -1) {
668                    // break out, go to next element
669                    return true;
670                }
671
672                // href doesn't contain our domain
673                if (element.href.indexOf(domain) == -1) {
674                    target = "_blank";
675                    setTarget = true;
676                }
677
678                // link opens a pdf, Word doc, csv, or txt file
679                if (jQuery.inArray(
680                    element.href.substr(element.href.lastIndexOf('.') + 1),
681                    ['pdf', 'doc', 'docx', 'csv', 'txt']) > -1) {
682                    target = "_blank";
683                    setTarget = true;
684                }
685
686                // set the element's target
687                if (setTarget !== false) {
688                    element.target = target;
689                    jQuery(element).addClass('external_link');
690                }
691
692                return true;
693            });
694            this.addClassToLiWithExternalLinks();
695        },
696        /**
697         * @description Remove empty elements
698         * @param {string} [element = p] The element type to remove.
699         */
700        removeEmptyElements: function (element) {
701            if (!element) {
702                element = 'p';
703            }
704            jQuery(element).each(function () {
705                var elem = jQuery(this);
706                if (elem.html().replace(/\s|&nbsp;/g, '').length == 0)
707                    elem.remove();
708            });
709        },
710        /**
711         * @description PHP-like print_r() & var_dump() equivalent for JavaScript Object
712         * @author Faisalman - [email protected]
713         * @license http://www.opensource.org/licenses/mit-license.php
714         * @link http://gist.github.com/879208
715         *
716         * examples:
717         *   // alert a boolean value
718         *   alert(Utils.isDevice("TABLET"));
719         *   // alert an object/array
720         *   alert(Utils.print_r(Utils.device));
721         */
722        print_r: function (obj) {
723            // define tab spacing
724            var tab = '';
725            // check if it's array
726            var isArr = Object.prototype.toString.call(obj) === '[object Array]' ? true : false;
727            // use {} for object, [] for array
728            var str = isArr ? ('Array [' + tab + '\n') : ('Object {' + tab + '\n');
729            // walk through it's properties
730            for (var prop in obj) {
731                if (obj.hasOwnProperty(prop)) {
732                    var val1 = obj[prop];
733                    var val2 = '';
734                    var type = Object.prototype.toString.call(val1);
735                    switch (type) {
736                        // recursive if object/array
737                        case '[object Array]':
738                        case '[object Object]':
739                            val2 = print_r(val1, (tab + '\t'));
740                            break;
741                        case '[object String]':
742                            val2 = '\'' + val1 + '\'';
743                            break;
744                        default:
745                            val2 = val1;
746                    }
747                    str += tab + '\t' + prop + ' => ' + val2 + ',\n';
748                }
749            }
750            // remove extra comma for last property
751            str = str.substring(0, str.length - 2) + '\n' + tab;
752            return isArr ? (str + ']') : (str + '}');
753            var var_dump = print_r; // equivalent function
754        },
755        /**
756         * @description Move element B infront of element A inside many children elements
757         * @param {string} childElem Child Element
758         * @param {string} elemA First Element
759         * @param {string} elemB Second element to be moved in front of first
760         */
761        swapChildElements: function (childElem, elemA, elemB) {
762            var children = jQuery(childElem);
763            children.each(function () {
764                var child = jQuery(this);
765                var a = child.find(elemA);
766                var b = child.find(elemB);
767                a.before(b);
768            })
769        },
770        /**
771         * @description Make generic HTML tables with theads, responsive
772         */
773        responsiveTables: function () {
774            var headertext = [];
775            var headers = document.querySelectorAll("thead");
776            var tablebody = document.querySelectorAll("tbody");
777
778            for (var i = 0; i < headers.length; i++) {
779                headertext[i] = [];
780                for (var j = 0, headrow; headrow = headers[i].rows[0].cells[j]; j++) {
781                    var current = headrow;
782                    headertext[i].push(current.textContent.replace(/\r?\n|\r/, ""));
783                }
784            }
785            if (headers.length > 0) {
786                for (var h = 0, tbody; tbody = tablebody[h]; h++) {
787                    for (var i = 0, row; row = tbody.rows[i]; i++) {
788                        for (var j = 0, col; col = row.cells[j]; j++) {
789                            col.setAttribute("data-th", headertext[h][j]);
790                        }
791                    }
792                }
793            }
794        },
795        /**
796         *
797         */
798        fixDevURL: function(){
799            //in order for this to work the script must be localised and a [theme] object with a [site_url] property passed into it
800            if(theme.site_url) {
801                var site_url = theme.site_url;
802                //var internalLinks = jQuery("a[href^='"+siteURL+"'], a[href^='/'], a[href^='./'], a[href^='../'], a[href^='#']");
803                //only interested in links starting with /
804                var internalLinks = jQuery("a[href^='/']");
805                internalLinks.each(function () {
806                    var url = jQuery(this).attr('href');
807                    jQuery(this).attr('href', site_url + url);
808
809                });
810            }
811        }
812    }
813;

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.