PageSourceSearch

https://simple-server.ru/assets/tpl/js/vendors/hs.megamenu.js?v=2

js simple-server.ru collected 2026-10-08 15:18:49 UTC 22,792 bytes, 1,006 lines download raw bytes

1/*
2 * HS Mega Menu - jQuery Plugin
3 * @version: 1.0.0 (Sun, 26 Feb 2017)
4 * @requires: jQuery v1.6 or later
5 * @author: HtmlStream
6 * @event-namespace: .HSMegaMenu
7 * @browser-support: IE9+
8 * @license:
9 *
10 * Copyright 2017 HtmlStream
11 *
12 */
13(function ($) {
14  'use strict';
15
16  /**
17   * Creates a mega menu.
18   *
19   * @constructor
20   * @param {HTMLElement|jQuery} element - The element to create the mega menu for.
21   * @param {Object} options - The options
22   */
23
24  var MegaMenu = window.MegaMenu || {};
25
26  MegaMenu = (function () {
27
28    var isMenuOpened = false;
29
30    function MegaMenu(element, options) {
31
32      var self = this;
33
34      /**
35       * Current element.
36       *
37       * @public
38       */
39      this.$element = $(element);
40
41      /**
42       * Current options set by the caller including defaults.
43       *
44       * @public
45       */
46      this.options = $.extend(true, {}, MegaMenu.defaults, options);
47
48
49      /**
50       * Collection of menu elements.
51       *
52       * @private
53       */
54      this._items = $();
55
56
57      Object.defineProperties(this, {
58
59        /**
60         * Contains composed selector of menu items.
61         *
62         * @public
63         */
64        itemsSelector: {
65          get: function () {
66            return self.options.classMap.hasSubMenu + ',' +
67              self.options.classMap.hasMegaMenu;
68          }
69        },
70
71        /**
72         * Contains chain of active items.
73         *
74         * @private
75         */
76        _tempChain: {
77          value: null,
78          writable: true
79        },
80
81        /**
82         * Contains current behavior state.
83         *
84         * @public
85         */
86        state: {
87          value: null,
88          writable: true
89        }
90
91      });
92
93      this.initialize();
94
95    }
96
97    return MegaMenu;
98
99  }());
100
101
102  /**
103   * Default options of the mega menu.
104   *
105   * @public
106   */
107  MegaMenu.defaults = {
108    event: 'hover',
109    direction: 'horizontal',
110    breakpoint: 991,
111    animationIn: false,
112    animationOut: false,
113
114    rtl: false,
115    hideTimeOut: 300,
116
117    // For 'vertical' direction only
118    sideBarRatio: 1 / 4,
119    pageContainer: $('body'),
120
121    classMap: {
122      initialized: '.hs-menu-initialized',
123      mobileState: '.hs-mobile-state',
124
125      subMenu: '.hs-sub-menu',
126      hasSubMenu: '.hs-has-sub-menu',
127      hasSubMenuActive: '.hs-sub-menu-opened',
128
129      megaMenu: '.hs-mega-menu',
130      hasMegaMenu: '.hs-has-mega-menu',
131      hasMegaMenuActive: '.hs-mega-menu-opened'
132    },
133
134    mobileSpeed: 400,
135    mobileEasing: 'linear',
136
137    beforeOpen: function () {},
138    beforeClose: function () {},
139    afterOpen: function () {},
140    afterClose: function () {}
141  };
142
143  /**
144   * Initialization of the plugin.
145   *
146   * @protected
147   */
148  MegaMenu.prototype.initialize = function () {
149    var self = this,
150      $w = $(window);
151
152    if (this.options.rtl) this.$element.addClass('hs-rtl');
153
154    this.$element
155      .addClass(this.options.classMap.initialized.slice(1))
156      .addClass('hs-menu-' + this.options.direction);
157
158
159    // Independent events
160    $w.on('resize.HSMegaMenu', function (e) {
161
162      if (self.resizeTimeOutId) clearTimeout(self.resizeTimeOutId);
163
164      self.resizeTimeOutId = setTimeout(function () {
165
166        if (window.innerWidth <= self.options.breakpoint && self.state == 'desktop') self.initMobileBehavior();
167        else if (window.innerWidth > self.options.breakpoint && self.state == 'mobile') self.initDesktopBehavior();
168
169        self.refresh();
170
171      }, 50);
172
173    });
174
175    $(document).on('click.HSMegaMenu touchstart.HSMegaMenu', 'body', function (e) {
176
177      var $parents = $(e.target).parents(self.itemsSelector);
178
179      self.closeAll($parents.add($(e.target)));
180
181    });
182
183    $w.on('keyup.HSMegaMenu', function (e) {
184
185      if (e.keyCode && e.keyCode === 27) {
186
187        self.closeAll();
188
189        isMenuOpened = false;
190      }
191
192    });
193
194    if (window.innerWidth <= this.options.breakpoint) this.initMobileBehavior();
195    else if (window.innerWidth > this.options.breakpoint) this.initDesktopBehavior();
196
197    this.smartPositions();
198
199    return this;
200
201  };
202
203  MegaMenu.prototype.smartPositions = function () {
204
205    var self = this,
206      $submenus = this.$element.find(this.options.classMap.subMenu);
207
208    $submenus.each(function (i, el) {
209
210      MenuItem.smartPosition($(el), self.options);
211
212    });
213
214  };
215
216  /**
217   * Binding events to menu elements.
218   *
219   * @protected
220   */
221  MegaMenu.prototype.bindEvents = function () {
222
223    var self = this,
224      selector;
225
226    // Hover case
227    if (this.options.event === 'hover' && !_isTouch()) {
228      this.$element
229        .on(
230          'mouseenter.HSMegaMenu',
231          this.options.classMap.hasMegaMenu + ':not([data-event="click"]),' +
232          this.options.classMap.hasSubMenu + ':not([data-event="click"])',
233          function (e) {
234
235            var $this = $(this),
236              $chain = $this.parents(self.itemsSelector);
237
238            // Lazy initialization
239            if (!$this.data('HSMenuItem')) {
240              self.initMenuItem($this, self.getType($this));
241            }
242
243            $chain = $chain.add($this);
244
245            self.closeAll($chain);
246
247            $chain.each(function (i, el) {
248
249              var HSMenuItem = $(el).data('HSMenuItem');
250
251              if (HSMenuItem.hideTimeOutId) clearTimeout(HSMenuItem.hideTimeOutId);
252              HSMenuItem.desktopShow();
253
254            });
255
256            self._items = self._items.not($chain);
257            self._tempChain = $chain;
258
259            e.preventDefault();
260            e.stopPropagation();
261          }
262        )
263        .on(
264          'mouseleave.HSMegaMenu',
265          this.options.classMap.hasMegaMenu + ':not([data-event="click"]),' +
266          this.options.classMap.hasSubMenu + ':not([data-event="click"])',
267          function (e) {
268
269            var $this = $(this),
270              HSMenuItem = $this.data('HSMenuItem'),
271              $chain = $(e.relatedTarget).parents(self.itemsSelector);
272
273            HSMenuItem.hideTimeOutId = setTimeout(function () {
274              self.closeAll($chain);
275            }, self.options.hideTimeOut);
276
277            self._items = self._items.add(self._tempChain);
278            self._tempChain = null;
279
280            e.preventDefault();
281            e.stopPropagation();
282          }
283        )
284        .on(
285          'click.HSMegaMenu',
286          this.options.classMap.hasMegaMenu + '[data-event="click"] > a, ' +
287          this.options.classMap.hasSubMenu + '[data-event="click"] > a',
288          function (e) {
289
290            var $this = $(this).parent('[data-event="click"]'),
291              HSMenuItem;
292
293            // Lazy initialization
294            if (!$this.data('HSMenuItem')) {
295              self.initMenuItem($this, self.getType($this));
296            }
297
298
299            self.closeAll($this.add(
300              $this.parents(self.itemsSelector)
301            ));
302
303            HSMenuItem = $this
304              .data('HSMenuItem');
305
306            if (HSMenuItem.isOpened) {
307              HSMenuItem.desktopHide();
308            }
309            else {
310              HSMenuItem.desktopShow();
311            }
312
313
314            e.preventDefault();
315            e.stopPropagation();
316
317          }
318        );
319    }
320    // Click case
321    else {
322
323      this.$element
324        .on(
325          'click.HSMegaMenu',
326          (_isTouch() ?
327            this.options.classMap.hasMegaMenu + ' > a, ' +
328            this.options.classMap.hasSubMenu + ' > a' :
329            this.options.classMap.hasMegaMenu + ':not([data-event="hover"]) > a,' +
330            this.options.classMap.hasSubMenu + ':not([data-event="hover"]) > a'),
331          function (e) {
332
333            var $this = $(this).parent(),
334              HSMenuItem,
335              $parents = $this.parents(self.itemsSelector);
336            if ($(this).attr('id') == 'homeMegaMenu') {
337              window.location.href = '/'
338            }
339            if ($(this).attr('id') == 'contactMegaMenu') {
340              window.location.href = $(this).attr('href')
341            }
342
343            // Lazy initialization
344            if (!$this.data('HSMenuItem')) {
345              self.initMenuItem($this, self.getType($this));
346            }
347
348            self.closeAll($this.add(
349              $this.parents(self.itemsSelector)
350            ));
351
352            HSMenuItem = $this
353              .addClass('hs-event-prevented')
354              .data('HSMenuItem');
355
356            if (HSMenuItem.isOpened) {
357              HSMenuItem.desktopHide();
358            }
359            else {
360              HSMenuItem.desktopShow();
361            }
362
363            e.preventDefault();
364            e.stopPropagation();
365          }
366        );
367
368      if (!_isTouch()) {
369        this.$element
370          .on(
371            'mouseenter.HSMegaMenu',
372            this.options.classMap.hasMegaMenu + '[data-event="hover"],' +
373            this.options.classMap.hasSubMenu + '[data-event="hover"]',
374            function (e) {
375
376              var $this = $(this),
377                $parents = $this.parents(self.itemsSelector);
378
379              // Lazy initialization
380              if (!$this.data('HSMenuItem')) {
381                self.initMenuItem($this, self.getType($this));
382              }
383
384              self.closeAll($this.add($parents));
385
386              $parents.add($this).each(function (i, el) {
387
388                var HSMenuItem = $(el).data('HSMenuItem');
389
390                if (HSMenuItem.hideTimeOutId) clearTimeout(HSMenuItem.hideTimeOutId);
391                HSMenuItem.desktopShow();
392
393              });
394
395              e.preventDefault();
396              e.stopPropagation();
397            }
398          )
399          .on(
400            'mouseleave.HSMegaMenu',
401            this.options.classMap.hasMegaMenu + '[data-event="hover"],' +
402            this.options.classMap.hasSubMenu + '[data-event="hover"]',
403            function (e) {
404
405              var $this = $(this),
406                HSMenuItem = $this.data('HSMenuItem');
407
408              HSMenuItem.hideTimeOutId = setTimeout(function () {
409
410                self.closeAll(
411                  $(e.relatedTarget).parents(self.itemsSelector)
412                );
413
414              }, self.options.hideTimeOut);
415
416              e.preventDefault();
417              e.stopPropagation();
418            }
419          )
420      }
421    }
422
423    this.$element.on('keydown.HSMegaMenu',
424      this.options.classMap.hasMegaMenu + ' > a,' +
425      this.options.classMap.hasSubMenu + ' > a',
426      function (e) {
427
428        var $this = $(this),
429          $parent = $this.parent(),
430          HSMenuItem;
431
432        // Lazy initialization
433        if (!$parent.data('HSMenuItem')) {
434
435          self.initMenuItem($parent, self.getType($parent));
436
437        }
438
439        HSMenuItem = $parent.data('HSMenuItem');
440
441        if ($this.is(':focus')) {
442
443          if (e.keyCode && e.keyCode === 40) {
444
445            e.preventDefault();
446
447            HSMenuItem.desktopShow();
448
449            isMenuOpened = true;
450
451          }
452
453          if (e.keyCode && e.keyCode === 13) {
454
455            if (isMenuOpened === true) {
456
457              HSMenuItem.desktopHide();
458
459              isMenuOpened = false;
460
461            } else {
462
463              HSMenuItem.desktopShow();
464
465              isMenuOpened = true;
466
467            }
468
469          }
470
471        }
472
473        $this.on('focusout', function () {
474
475          isMenuOpened = false;
476
477        });
478
479        HSMenuItem.menu.find('a').on('focusout', function () {
480
481          setTimeout(function () {
482
483            if (!HSMenuItem.menu.find('a').is(':focus')) {
484
485              HSMenuItem.desktopHide();
486
487              isMenuOpened = false;
488
489            }
490
491          });
492
493        });
494
495      })
496  };
497
498  /**
499   * Initialization of certain menu item.
500   *
501   * @protected
502   */
503  MegaMenu.prototype.initMenuItem = function (element, type) {
504
505    var self = this,
506      Item = new MenuItem(
507        element,
508        element.children(
509          self.options.classMap[type === 'mega-menu' ? 'megaMenu' : 'subMenu']
510        ),
511        $.extend(true, {type: type}, self.options, element.data()),
512        self.$element
513      );
514
515    element.data('HSMenuItem', Item);
516    this._items = this._items.add(element);
517
518  };
519
520  /**
521   * Destroys of desktop behavior, then makes initialization of mobile behavior.
522   *
523   * @protected
524   */
525  MegaMenu.prototype.initMobileBehavior = function () {
526
527    var self = this;
528
529    this.state = 'mobile';
530
531    this.$element
532      .off('.HSMegaMenu')
533      .addClass(this.options.classMap.mobileState.slice(1))
534      .on('click.HSMegaMenu', self.options.classMap.hasSubMenu + ' > a, ' + self.options.classMap.hasMegaMenu + ' > a', function (e) {
535
536        var $this = $(this).parent(),
537          MenuItemInstance;
538
539        // Lazy initialization
540        if (!$this.data('HSMenuItem')) {
541          self.initMenuItem($this, self.getType($this));
542        }
543
544        self.closeAll($this.parents(self.itemsSelector).add($this));
545
546        MenuItemInstance = $this
547          .data('HSMenuItem');
548
549        if (MenuItemInstance.isOpened) {
550          MenuItemInstance.mobileHide();
551        }
552        else {
553          MenuItemInstance.mobileShow();
554        }
555
556        e.preventDefault();
557        e.stopPropagation();
558
559      })
560      .find(this.itemsSelector)
561      .not(
562        this.options.classMap.hasSubMenuActive + ',' +
563        this.options.classMap.hasMegaMenuActive
564      )
565      .children(
566        this.options.classMap.subMenu + ',' +
567        this.options.classMap.megaMenu
568      )
569      .hide();
570
571  };
572
573  /**
574   * Destroys of mobile behavior, then makes initialization of desktop behavior.
575   *
576   * @protected
577   */
578  MegaMenu.prototype.initDesktopBehavior = function () {
579
580    this.state = 'desktop';
581
582    this.$element
583      .removeClass(this.options.classMap.mobileState.slice(1))
584      .off('.HSMegaMenu')
585      .find(this.itemsSelector)
586      .not(
587        this.options.classMap.hasSubMenuActive + ',' +
588        this.options.classMap.hasMegaMenuActive
589      )
590      .children(
591        this.options.classMap.subMenu + ',' +
592        this.options.classMap.megaMenu
593      )
594      .hide();
595
596    this.bindEvents();
597
598  };
599
600  /**
601   * Hides all of opened submenus/megamenus.
602   *
603   * @param {jQuery} except - collection of elements, which shouldn't be closed.
604   * @return {jQuery}
605   * @public
606   */
607  MegaMenu.prototype.closeAll = function (except) {
608
609    var self = this;
610
611    return this._items.not(except && except.length ? except : $()).each(function (i, el) {
612
613      $(el)
614        .removeClass('hs-event-prevented')
615        .data('HSMenuItem')[self.state === 'mobile' ? 'mobileHide' : 'desktopHide']();
616
617    });
618
619  };
620
621  /**
622   * Returns type of sub menu based on specified menu item.
623   *
624   * @param {jQuery} item
625   * @return {String|null}
626   * @public
627   */
628  MegaMenu.prototype.getType = function (item) {
629
630    if (!item || !item.length) return null;
631
632    return item.hasClass(this.options.classMap.hasSubMenu.slice(1)) ? 'sub-menu' :
633      (item.hasClass(this.options.classMap.hasMegaMenu.slice(1)) ? 'mega-menu' : null);
634
635  };
636
637  /**
638   * Returns current menu state.
639   *
640   * @return {String}
641   * @public
642   */
643  MegaMenu.prototype.getState = function () {
644    return this.state;
645  };
646
647  /**
648   * Updates bounds of all menu items.
649   *
650   * @return {jQuery}
651   * @public
652   */
653  MegaMenu.prototype.refresh = function () {
654
655    return this._items.add(this._tempChain).each(function (i, el) {
656      $(el).data('HSMenuItem')._updateMenuBounds();
657    });
658
659  };
660
661
662  /**
663   * Creates a mega-menu element.
664   *
665   * @param {jQuery} element
666   * @param {jQuery} menu
667   * @param {Object} options
668   * @param {jQuery} container
669   * @constructor
670   */
671  function MenuItem(element, menu, options, container) {
672
673    var self = this;
674
675    /**
676     * Current menu item element.
677     *
678     * @public
679     */
680    this.$element = element;
681
682    /**
683     * Current mega menu element.
684     *
685     * @public
686     */
687    this.menu = menu;
688
689    /**
690     * Item options.
691     *
692     * @public
693     */
694    this.options = options;
695
696
697    /**
698     * MegaMenu container.
699     *
700     * @public
701     */
702    this.$container = container;
703
704    Object.defineProperties(this, {
705
706      /**
707       * Contains css class of menu item element.
708       *
709       * @public
710       */
711      itemClass: {
712        get: function () {
713          return self.options.type === 'mega-menu' ?
714            self.options.classMap.hasMegaMenu :
715            self.options.classMap.hasSubMenu;
716        }
717      },
718
719      /**
720       * Contains css active-class of menu item element.
721       *
722       * @public
723       */
724      activeItemClass: {
725        get: function () {
726          return self.options.type === 'mega-menu' ?
727            self.options.classMap.hasMegaMenuActive :
728            self.options.classMap.hasSubMenuActive;
729        }
730      },
731
732      /**
733       * Contains css class of menu element.
734       *
735       * @public
736       */
737      menuClass: {
738        get: function () {
739          return self.options.type === 'mega-menu' ?
740            self.options.classMap.megaMenu :
741            self.options.classMap.subMenu;
742        }
743      },
744
745      isOpened: {
746        get: function () {
747          return this.$element.hasClass(this.activeItemClass.slice(1));
748        }
749      }
750
751    });
752
753
754    this.menu.addClass('animated').on('click.HSMegaMenu', function (e) {
755      self._updateMenuBounds();
756    });
757
758    if (this.$element.data('max-width')) this.menu.css('max-width', this.$element.data('max-width'));
759    if (this.$element.data('position')) this.menu.addClass('hs-position-' + this.$element.data('position'));
760
761
762    if (this.options.animationOut) {
763
764      this.menu.on('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function (e) {
765
766        if (self.menu.hasClass(self.options.animationOut)) {
767          self.$element.removeClass(self.activeItemClass.slice(1));
768          self.options.afterClose.call(self, self.$element, self.menu);
769        }
770
771        if (self.menu.hasClass(self.options.animationIn)) {
772          self.options.afterOpen.call(self, self.$element, self.menu);
773        }
774
775        e.stopPropagation();
776        e.preventDefault();
777      });
778    }
779
780  }
781
782  /**
783   * Shows the mega-menu item.
784   *
785   * @public
786   * @return {MenuItem}
787   */
788  MenuItem.prototype.desktopShow = function () {
789    if (!this.menu.length) return this;
790
791    this.$element.addClass(this.activeItemClass.slice(1));
792
793    this._updateMenuBounds();
794
795    this.menu.show();
796
797    if (this.options.direction == 'horizontal') this.smartPosition(this.menu, this.options);
798
799    if (this.options.animationOut) {
800      this.menu.removeClass(this.options.animationOut);
801    }
802    else {
803      this.options.afterOpen.call(this, this.$element, this.menu);
804    }
805
806    if (this.options.animationIn) {
807      this.menu.addClass(this.options.animationIn)
808    }
809
810    return this;
811  }
812
813  /**
814   * Hides the mega-menu item.
815   *
816   * @public
817   * @return {MenuItem}
818   */
819  MenuItem.prototype.desktopHide = function () {
820
821    var self = this;
822
823    if (!this.menu.length) return this;
824
825    this.$element.removeClass(this.activeItemClass.slice(1));
826
827    this.menu.hide();
828
829    if (this.options.animationIn) {
830      this.menu.removeClass(this.options.animationIn);
831    }
832    if (this.options.animationOut) {
833      this.menu.addClass(this.options.animationOut);
834    }
835    else {
836      this.options.afterClose.call(this, this.$element, this.menu);
837    }
838
839    return this;
840  }
841
842  /**
843   * Shows the mega-menu item.
844   *
845   * @public
846   * @return {MenuItem}
847   */
848  MenuItem.prototype.mobileShow = function () {
849    var self = this;
850
851    if (!this.menu.length) return this;
852
853
854    this.menu
855      .removeClass(this.options.animationIn)
856      .removeClass(this.options.animationOut)
857      .stop()
858      .slideDown({
859        duration: self.options.mobileSpeed,
860        easing: self.options.mobileEasing,
861        complete: function () {
862          self.options.afterOpen.call(self, self.$element, self.menu);
863        }
864      });
865
866    this.$element.addClass(this.activeItemClass.slice(1));
867
868    return this;
869  };
870
871  /**
872   * Hides the mega-menu item.
873   *
874   * @public
875   * @return {MenuItem}
876   */
877  MenuItem.prototype.mobileHide = function () {
878    var self = this;
879
880    if (!this.menu.length) return this;
881
882    this.menu.stop().slideUp({
883      duration: self.options.mobileSpeed,
884      easing: self.options.mobileEasing,
885      complete: function () {
886        self.options.afterClose.call(self, self.$element, self.menu);
887      }
888    });
889
890    this.$element.removeClass(this.activeItemClass.slice(1));
891
892    return this;
893  };
894
895  /**
896   * Check, if element is in viewport.
897   *
898   * @param {jQuery} element
899   * @param {Object} options
900   * @public
901   */
902  MenuItem.prototype.smartPosition = function (element, options) {
903
904    MenuItem.smartPosition(element, options);
905
906  };
907
908  /**
909   * Check, if element is in viewport.
910   *
911   * @param {jQuery} element
912   * @param {Object} options
913   * @static
914   * @public
915   */
916  MenuItem.smartPosition = function (element, options) {
917    if (!element && !element.length) return;
918
919    var $w = $(window);
920
921    element.removeClass('hs-reversed');
922
923    if (!options.rtl) {
924
925      if (element.offset().left + element.outerWidth() > window.innerWidth) {
926        element.addClass('hs-reversed');
927      }
928
929    }
930    else {
931
932      if (element.offset().left < 0) {
933        element.addClass('hs-reversed');
934      }
935
936    }
937  };
938
939  /**
940   * Updates bounds of current opened menu.
941   *
942   * @private
943   */
944  MenuItem.prototype._updateMenuBounds = function () {
945
946    var width = 'auto';
947
948    if (this.options.direction == 'vertical' && this.options.type == 'mega-menu') {
949
950      if (this.$container && this.$container.data('HSMegaMenu').get
950State() == 'desktop') {
951        if (!this.options.pageContainer.length) this.options.pageContainer = $('body');
952        width = this.options.pageContainer.outerWidth() * (1 - this.options.sideBarRatio);
953      }
954      else {
955        width = 'auto';
956      }
957
958
959      this.menu.css({
960        'width': width,
961        'height': 'auto'
962      });
963
964      if (this.menu.outerHeight() > this.$container.outerHeight()) {
965        return;
966      }
967
968      this.menu.css('height', '100%');
969    }
970
971  };
972
973  /**
974   * The jQuery plugin for the MegaMenu.
975   *
976   * @public
977   */
978
979  $.fn.HSMegaMenu = function () {
980    var _ = this,
981      opt = arguments[0],
982      args = Array.prototype.slice.call(arguments, 1),
983      l = _.length,
984      i,
985      ret;
986    for (i = 0; i < l; i++) {
987      if (typeof opt == 'object' || typeof opt == 'undefined')
988        _[i].MegaMenu = new MegaMenu(_[i], opt);
989      else
990        ret = _[i].MegaMenu[opt].apply(_[i].MegaMenu, args);
991      if (typeof ret != 'undefined') return ret;
992    }
993    return _;
994  };
995
996  /**
997   * Helper function for detect touch events in the environment.
998   *
999   * @return {Boolean}
1000   * @private
1001   */
1002  function _isTouch() {
1003    return ('ontouchstart' in window);
1004  }
1005
1006})(jQuery);

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.