Browse Source

first commit

kevin tessier 5 years ago
commit
2affb782f4
71 changed files with 9879 additions and 0 deletions
  1. 4 0
      .directory
  2. 4 0
      fonts/.directory
  3. BIN
      fonts/ubuntu-b-webfont.eot
  4. 10 0
      fonts/ubuntu-b-webfont.svg
  5. BIN
      fonts/ubuntu-b-webfont.woff
  6. BIN
      fonts/ubuntu-b-webfont.woff2
  7. BIN
      fonts/ubuntu-bi-webfont.eot
  8. 10 0
      fonts/ubuntu-bi-webfont.svg
  9. BIN
      fonts/ubuntu-bi-webfont.woff
  10. BIN
      fonts/ubuntu-bi-webfont.woff2
  11. BIN
      fonts/ubuntu-c-webfont.eot
  12. 22 0
      fonts/ubuntu-c-webfont.svg
  13. BIN
      fonts/ubuntu-c-webfont.woff
  14. BIN
      fonts/ubuntu-c-webfont.woff2
  15. BIN
      fonts/ubuntu-l-webfont.eot
  16. 21 0
      fonts/ubuntu-l-webfont.svg
  17. BIN
      fonts/ubuntu-l-webfont.woff
  18. BIN
      fonts/ubuntu-l-webfont.woff2
  19. BIN
      fonts/ubuntu-li-webfont.eot
  20. 8 0
      fonts/ubuntu-li-webfont.svg
  21. BIN
      fonts/ubuntu-li-webfont.woff
  22. BIN
      fonts/ubuntu-li-webfont.woff2
  23. BIN
      fonts/ubuntu-m-webfont.eot
  24. 10 0
      fonts/ubuntu-m-webfont.svg
  25. BIN
      fonts/ubuntu-m-webfont.ttf
  26. BIN
      fonts/ubuntu-m-webfont.woff
  27. BIN
      fonts/ubuntu-m-webfont.woff2
  28. BIN
      fonts/ubuntu-mi-webfont.eot
  29. 9 0
      fonts/ubuntu-mi-webfont.svg
  30. BIN
      fonts/ubuntu-mi-webfont.woff
  31. BIN
      fonts/ubuntu-mi-webfont.woff2
  32. 22 0
      fonts/ubuntu-r-webfont.svg
  33. BIN
      fonts/ubuntu-r-webfont.woff
  34. BIN
      fonts/ubuntu-r-webfont.woff2
  35. 9 0
      fonts/ubuntu-ri-webfont.svg
  36. BIN
      fonts/ubuntu-ri-webfont.woff
  37. BIN
      fonts/ubuntu-ri-webfont.woff2
  38. 17 0
      fonts/ubuntumono-r-webfont.svg
  39. BIN
      fonts/ubuntumono-r-webfont.woff
  40. BIN
      fonts/ubuntumono-r-webfont.woff2
  41. 15 0
      fonts/ubuntumono-ri-webfont.svg
  42. BIN
      fonts/ubuntumono-ri-webfont.woff
  43. BIN
      fonts/ubuntumono-ri-webfont.woff2
  44. 582 0
      images/bubulle.svg
  45. BIN
      images/image1.png
  46. BIN
      images/image2.png
  47. BIN
      images/image3.png
  48. BIN
      images/image4.png
  49. BIN
      images/image5.png
  50. BIN
      images/image6.png
  51. BIN
      images/image7.png
  52. BIN
      images/image8.png
  53. BIN
      images/image9.png
  54. 102 0
      images/oeil.svg
  55. BIN
      images/video1.png
  56. 52 0
      index.php
  57. 33 0
      pages/databases.php
  58. 22 0
      pages/showrooms.php
  59. 17 0
      pages/videos.php
  60. 4 0
      script/.directory
  61. 3918 0
      script/fullpage.js
  62. 1 0
      script/jquery.min.js
  63. 10 0
      script/script.js
  64. 5 0
      script/scrolloverflow.min.js
  65. 4182 0
      script/simplebar.js
  66. 4 0
      style/.directory
  67. 79 0
      style/fonts.css
  68. 236 0
      style/fullpage.css
  69. 4 0
      style/knacss.css
  70. 183 0
      style/simplebar.css
  71. 284 0
      style/style.css

+ 4 - 0
.directory

@@ -0,0 +1,4 @@
+[Dolphin]
+Timestamp=2018,11,15,10,6,10
+Version=4
+ViewMode=2

+ 4 - 0
fonts/.directory

@@ -0,0 +1,4 @@
+[Dolphin]
+Timestamp=2018,11,13,2,37,0
+Version=4
+ViewMode=2

BIN
fonts/ubuntu-b-webfont.eot


File diff suppressed because it is too large
+ 10 - 0
fonts/ubuntu-b-webfont.svg


BIN
fonts/ubuntu-b-webfont.woff


BIN
fonts/ubuntu-b-webfont.woff2


BIN
fonts/ubuntu-bi-webfont.eot


File diff suppressed because it is too large
+ 10 - 0
fonts/ubuntu-bi-webfont.svg


BIN
fonts/ubuntu-bi-webfont.woff


BIN
fonts/ubuntu-bi-webfont.woff2


BIN
fonts/ubuntu-c-webfont.eot


File diff suppressed because it is too large
+ 22 - 0
fonts/ubuntu-c-webfont.svg


BIN
fonts/ubuntu-c-webfont.woff


BIN
fonts/ubuntu-c-webfont.woff2


BIN
fonts/ubuntu-l-webfont.eot


File diff suppressed because it is too large
+ 21 - 0
fonts/ubuntu-l-webfont.svg


BIN
fonts/ubuntu-l-webfont.woff


BIN
fonts/ubuntu-l-webfont.woff2


BIN
fonts/ubuntu-li-webfont.eot


File diff suppressed because it is too large
+ 8 - 0
fonts/ubuntu-li-webfont.svg


BIN
fonts/ubuntu-li-webfont.woff


BIN
fonts/ubuntu-li-webfont.woff2


BIN
fonts/ubuntu-m-webfont.eot


File diff suppressed because it is too large
+ 10 - 0
fonts/ubuntu-m-webfont.svg


BIN
fonts/ubuntu-m-webfont.ttf


BIN
fonts/ubuntu-m-webfont.woff


BIN
fonts/ubuntu-m-webfont.woff2


BIN
fonts/ubuntu-mi-webfont.eot


File diff suppressed because it is too large
+ 9 - 0
fonts/ubuntu-mi-webfont.svg


BIN
fonts/ubuntu-mi-webfont.woff


BIN
fonts/ubuntu-mi-webfont.woff2


File diff suppressed because it is too large
+ 22 - 0
fonts/ubuntu-r-webfont.svg


BIN
fonts/ubuntu-r-webfont.woff


BIN
fonts/ubuntu-r-webfont.woff2


File diff suppressed because it is too large
+ 9 - 0
fonts/ubuntu-ri-webfont.svg


BIN
fonts/ubuntu-ri-webfont.woff


BIN
fonts/ubuntu-ri-webfont.woff2


File diff suppressed because it is too large
+ 17 - 0
fonts/ubuntumono-r-webfont.svg


BIN
fonts/ubuntumono-r-webfont.woff


BIN
fonts/ubuntumono-r-webfont.woff2


File diff suppressed because it is too large
+ 15 - 0
fonts/ubuntumono-ri-webfont.svg


BIN
fonts/ubuntumono-ri-webfont.woff


BIN
fonts/ubuntumono-ri-webfont.woff2


File diff suppressed because it is too large
+ 582 - 0
images/bubulle.svg


BIN
images/image1.png


BIN
images/image2.png


BIN
images/image3.png


BIN
images/image4.png


BIN
images/image5.png


BIN
images/image6.png


BIN
images/image7.png


BIN
images/image8.png


BIN
images/image9.png


File diff suppressed because it is too large
+ 102 - 0
images/oeil.svg


BIN
images/video1.png


+ 52 - 0
index.php

@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<link rel="stylesheet" type="text/css" href="style/knacss.css" />
+	<link rel="stylesheet" type="text/css" href="style/fonts.css" />
+	<link rel="stylesheet" type="text/css" href="style/fullpage.css" />
+	<link rel="stylesheet" type="text/css" href="style/simplebar.css" />
+	<link rel="stylesheet" type="text/css" href="style/style.css" />
+
+</head>
+
+<title>materiO'</title>
+
+<body>
+
+	<header>
+		<div class="logo">
+			<h1>materiO'</h1>
+			<h2>l'inspiration par la matière</h2>
+		</div>
+
+		<nav>
+			<li>Accès Membre</li>
+			<li>Qui Sommes Nous ?</li>
+			<li> Tarifs</li>
+			<li>Contact</li>
+			<li>Aide</li>
+			<li>Langue</li>
+		</nav>
+
+	</header>
+
+	<section id="fullpage">
+
+		<?php include('pages/databases.php'); ?>
+		<?php include('pages/videos.php'); ?>
+		<?php include('pages/showrooms.php'); ?>
+
+	</section>
+
+	<footer></footer>
+</body>
+
+<script type="text/javascript" src="script/jquery.min.js"></script>
+<script type="text/javascript" src="script/simplebar.js"></script>
+<script type="text/javascript" src="script/fullpage.js"></script>
+<script type="text/javascript" src="script/scrolloverflow.min.js"></script>
+<script type="text/javascript" src="script/script.js"></script>
+
+</html>

+ 33 - 0
pages/databases.php

@@ -0,0 +1,33 @@
+ <div class="section" id="ddb" data-simplebar>
+
+	<div class="content">
+		<h3>Une base </br> de données </br> intuitive</h3>
+
+		<div class="txt">
+
+		<p>Plus de 7000 fiches de matériaux extra-ordinaires, plus de 5000 industriels référencés ! Faire des recherches : cette matériOthèque virtuelle rassemble toutes les références sélectionnées avec soin par l’équipe matériO (y figurent les contacts directs des fournisseurs). L’outil en ligne, ergonomique, facilite une recherche intuitive, simple
+			et ludique, pour des résultats riches et surprenants. Un outil indispensable! Showroom
+			et base de données en ligne sont mis à jour quotidiennement et se nourrissent
+			en permanence des dernières nouveautés internationales.</p>
+
+			<button type="button" name="join_us">Rejoignez nous</button>
+			<img src="images/bubulle.svg" alt="bulles">
+      <img src="images/oeil.svg" alt="bulles">
+
+		</div>
+
+		</div>
+
+		<div class="images" id="gal" data-simplebar>
+      <img src="images/image6.png" alt="img6">
+      <img src="images/image5.png" alt="img5">
+			<img src="images/image1.png" alt="img">
+			<img src="images/image2.png" alt="img2">
+			<img src="images/image3.png" alt="img3">
+      <img src="images/image7.png" alt="img7">
+			<img src="images/image4.png" alt="img4">
+			<img src="images/image8.png" alt="img8">
+			<img src="images/image9.png" alt="img9">
+		</div>
+
+	</div>

+ 22 - 0
pages/showrooms.php

@@ -0,0 +1,22 @@
+<div class="section " id="showroom">
+
+	<div class="content">
+		<h3>Des showrooms </br> foisonnants</h3>
+		<div class="txt">
+
+		<p>Venez voir et toucher plusieurs milliers d’échantillons de produits, de matériaux et de technologies singuliers, classés par grandes familles. Un lieu effervescent où les créateurs viennent manipuler et s’inspirer... Une véritable caverne d'Ali Baba pour designers !</p>
+
+		<button type="button" name="join_us">Rejoignez nous</button>
+		<button type="button" name="rdv">RdV de présentation</button>
+		<button type="button" name="Brochure">Brochure</button>
+	</div>
+
+		<img src="" alt="bulles">
+		<img src="" alt="fioles">
+
+	</div>
+
+	<div class="images">
+	</div>
+
+</div>

+ 17 - 0
pages/videos.php

@@ -0,0 +1,17 @@
+<div class="section" id="videos">
+
+	<div class="content">
+		<img src="" alt="">
+
+		<div class="liste_movies">
+			<img src="images/video1.png" alt="video">
+			<ul>
+				<li><img src="images/video1.png" alt="video2"></li>
+				<li><img src="images/video1.png" alt="video2"></li>
+			</ul>
+
+		</div>
+
+	</div>
+
+</div>

+ 4 - 0
script/.directory

@@ -0,0 +1,4 @@
+[Dolphin]
+Timestamp=2018,11,15,15,54,34
+Version=4
+ViewMode=2

+ 3918 - 0
script/fullpage.js

@@ -0,0 +1,3918 @@
+/*!
+ * fullPage 3.0.3
+ * https://github.com/alvarotrigo/fullPage.js
+ *
+ * @license GPLv3 for open source use only
+ * or Fullpage Commercial License for commercial use
+ * http://alvarotrigo.com/fullPage/pricing/
+ *
+ * Copyright (C) 2018 http://alvarotrigo.com/fullPage - A project by Alvaro Trigo
+ */
+(function( root, window, document, factory, undefined) {
+    if( typeof define === 'function' && define.amd ) {
+        // AMD. Register as an anonymous module.
+        define( function() {
+            root.fullpage = factory(window, document);
+            return root.fullpage;
+        } );
+    } else if( typeof exports === 'object' ) {
+        // Node. Does not work with strict CommonJS.
+        module.exports = factory(window, document);
+    } else {
+        // Browser globals.
+        window.fullpage = factory(window, document);
+    }
+}(this, window, document, function(window, document){
+    'use strict';
+
+    // keeping central set of classnames and selectors
+    var WRAPPER =               'fullpage-wrapper';
+    var WRAPPER_SEL =           '.' + WRAPPER;
+
+    // slimscroll
+    var SCROLLABLE =            'fp-scrollable';
+    var SCROLLABLE_SEL =        '.' + SCROLLABLE;
+
+    // util
+    var RESPONSIVE =            'fp-responsive';
+    var NO_TRANSITION =         'fp-notransition';
+    var DESTROYED =             'fp-destroyed';
+    var ENABLED =               'fp-enabled';
+    var VIEWING_PREFIX =        'fp-viewing';
+    var ACTIVE =                'active';
+    var ACTIVE_SEL =            '.' + ACTIVE;
+    var COMPLETELY =            'fp-completely';
+    var COMPLETELY_SEL =        '.' + COMPLETELY;
+
+    // section
+    var SECTION_DEFAULT_SEL =   '.section';
+    var SECTION =               'fp-section';
+    var SECTION_SEL =           '.' + SECTION;
+    var SECTION_ACTIVE_SEL =    SECTION_SEL + ACTIVE_SEL;
+    var TABLE_CELL =            'fp-tableCell';
+    var TABLE_CELL_SEL =        '.' + TABLE_CELL;
+    var AUTO_HEIGHT =           'fp-auto-height';
+    var AUTO_HEIGHT_SEL =       '.' + AUTO_HEIGHT;
+    var NORMAL_SCROLL =         'fp-normal-scroll';
+    var NORMAL_SCROLL_SEL =     '.' + NORMAL_SCROLL;
+
+    // section nav
+    var SECTION_NAV =           'fp-nav';
+    var SECTION_NAV_SEL =       '#' + SECTION_NAV;
+    var SECTION_NAV_TOOLTIP =   'fp-tooltip';
+    var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP;
+    var SHOW_ACTIVE_TOOLTIP =   'fp-show-active';
+
+    // slide
+    var SLIDE_DEFAULT_SEL =     '.slide';
+    var SLIDE =                 'fp-slide';
+    var SLIDE_SEL =             '.' + SLIDE;
+    var SLIDE_ACTIVE_SEL =      SLIDE_SEL + ACTIVE_SEL;
+    var SLIDES_WRAPPER =        'fp-slides';
+    var SLIDES_WRAPPER_SEL =    '.' + SLIDES_WRAPPER;
+    var SLIDES_CONTAINER =      'fp-slidesContainer';
+    var SLIDES_CONTAINER_SEL =  '.' + SLIDES_CONTAINER;
+    var TABLE =                 'fp-table';
+
+    // slide nav
+    var SLIDES_NAV =            'fp-slidesNav';
+    var SLIDES_NAV_SEL =        '.' + SLIDES_NAV;
+    var SLIDES_NAV_LINK_SEL =   SLIDES_NAV_SEL + ' a';
+    var SLIDES_ARROW =          'fp-controlArrow';
+    var SLIDES_ARROW_SEL =      '.' + SLIDES_ARROW;
+    var SLIDES_PREV =           'fp-prev';
+    var SLIDES_PREV_SEL =       '.' + SLIDES_PREV;
+    var SLIDES_ARROW_PREV =     SLIDES_ARROW + ' ' + SLIDES_PREV;
+    var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL;
+    var SLIDES_NEXT =           'fp-next';
+    var SLIDES_NEXT_SEL =       '.' + SLIDES_NEXT;
+    var SLIDES_ARROW_NEXT =     SLIDES_ARROW + ' ' + SLIDES_NEXT;
+    var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL;
+
+    function initialise(containerSelector, options) {
+        var isLicenseValid = options && new RegExp('([\\d\\w]{8}-){3}[\\d\\w]{8}|OPEN-SOURCE-GPLV3-LICENSE').test(options.licenseKey) || document.domain.indexOf('alvarotrigo.com') > -1;
+
+        //only once my friend!
+        if(hasClass($('html'), ENABLED)){ displayWarnings(); return; }
+
+        // common jQuery objects
+        var $htmlBody = $('html, body');
+        var $body = $('body')[0];
+
+        var FP = {};
+
+        // Creating some defaults, extending them with any options that were provided
+        options = deepExtend({
+            //navigation
+            menu: false,
+            anchors:[],
+            lockAnchors: false,
+            navigation: false,
+            navigationPosition: 'right',
+            navigationTooltips: [],
+            showActiveTooltip: false,
+            slidesNavigation: false,
+            slidesNavPosition: 'bottom',
+            scrollBar: false,
+            hybrid: false,
+
+            //scrolling
+            css3: true,
+            scrollingSpeed: 700,
+            autoScrolling: true,
+            fitToSection: true,
+            fitToSectionDelay: 1000,
+            easing: 'easeInOutCubic',
+            easingcss3: 'ease',
+            loopBottom: false,
+            loopTop: false,
+            loopHorizontal: true,
+            continuousVertical: false,
+            continuousHorizontal: false,
+            scrollHorizontally: false,
+            interlockedSlides: false,
+            dragAndMove: false,
+            offsetSections: false,
+            resetSliders: false,
+            fadingEffect: false,
+            normalScrollElements: null,
+            scrollOverflow: false,
+            scrollOverflowReset: false,
+            scrollOverflowHandler: window.fp_scrolloverflow ? window.fp_scrolloverflow.iscrollHandler : null,
+            scrollOverflowOptions: null,
+            touchSensitivity: 5,
+            normalScrollElementTouchThreshold: 5,
+            bigSectionsDestination: null,
+
+            //Accessibility
+            keyboardScrolling: true,
+            animateAnchor: true,
+            recordHistory: true,
+
+            //design
+            controlArrows: true,
+            controlArrowColor: '#fff',
+            verticalCentered: true,
+            sectionsColor : [],
+            paddingTop: 0,
+            paddingBottom: 0,
+            fixedElements: null,
+            responsive: 0, //backwards compabitility with responsiveWiddth
+            responsiveWidth: 0,
+            responsiveHeight: 0,
+            responsiveSlides: false,
+            parallax: false,
+            parallaxOptions: {
+                type: 'reveal',
+                percentage: 62,
+                property: 'translate'
+            },
+
+            //Custom selectors
+            sectionSelector: SECTION_DEFAULT_SEL,
+            slideSelector: SLIDE_DEFAULT_SEL,
+
+            //events
+            v2compatible: false,
+            afterLoad: null,
+            onLeave: null,
+            afterRender: null,
+            afterResize: null,
+            afterReBuild: null,
+            afterSlideLoad: null,
+            onSlideLeave: null,
+            afterResponsive: null,
+
+            lazyLoading: true
+        }, options);
+
+        //flag to avoid very fast sliding for landscape sliders
+        var slideMoving = false;
+
+        var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/);
+        var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints));
+        var container = typeof containerSelector === 'string' ? $(containerSelector)[0] : containerSelector;
+        var windowsHeight = getWindowHeight();
+        var isResizing = false;
+        var isWindowFocused = true;
+        var lastScrolledDestiny;
+        var lastScrolledSlide;
+        var canScroll = true;
+        var scrollings = [];
+        var controlPressed;
+        var startingSection;
+        var isScrollAllowed = {};
+        isScrollAllowed.m = {  'up':true, 'down':true, 'left':true, 'right':true };
+        isScrollAllowed.k = deepExtend({}, isScrollAllowed.m);
+        var MSPointer = getMSPointer();
+        var events = {
+            touchmove: 'ontouchmove' in window ? 'touchmove' :  MSPointer.move,
+            touchstart: 'ontouchstart' in window ? 'touchstart' :  MSPointer.down
+        };
+        var scrollBarHandler;
+
+        // taken from https://github.com/udacity/ud891/blob/gh-pages/lesson2-focus/07-modals-and-keyboard-traps/solution/modal.js
+        var focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"], [contenteditable]';
+
+        //timeouts
+        var resizeId;
+        var afterSectionLoadsId;
+        var afterSlideLoadsId;
+        var scrollId;
+        var scrollId2;
+        var keydownId;
+        var originals = deepExtend({}, options); //deep copy
+        var activeAnimation;
+
+        displayWarnings();
+
+        //easeInOutCubic animation included in the plugin
+        window.fp_easings = deepExtend(window.fp_easings, {
+            easeInOutCubic: function (t, b, c, d) {
+                if ((t/=d/2) < 1) return c/2*t*t*t + b;return c/2*((t-=2)*t*t + 2) + b;
+            }
+        });
+
+        /**
+        * Sets the autoScroll option.
+        * It changes the scroll bar visibility and the history of the site as a result.
+        */
+        function setAutoScrolling(value, type){
+            //removing the transformation
+            if(!value){
+                silentScroll(0);
+            }
+
+            setVariableState('autoScrolling', value, type);
+
+            var element = $(SECTION_ACTIVE_SEL)[0];
+
+            if(options.autoScrolling && !options.scrollBar){
+                css($htmlBody, {
+                    'overflow': 'hidden',
+                    'height': '100%'
+                });
+
+                setRecordHistory(originals.recordHistory, 'internal');
+
+                //for IE touch devices
+                css(container, {
+                    '-ms-touch-action': 'none',
+                    'touch-action': 'none'
+                });
+
+                if(element != null){
+                    //moving the container up
+                    silentScroll(element.offsetTop);
+                }
+
+            }else{
+                css($htmlBody, {
+                    'overflow' : 'visible',
+                    'height' : 'initial'
+                });
+
+                setRecordHistory(false, 'internal');
+
+                //for IE touch devices
+                css(container, {
+                    '-ms-touch-action': '',
+                    'touch-action': ''
+                });
+
+                //scrolling the page to the section with no animation
+                if (element != null) {
+                    var scrollSettings = getScrollSettings(element.offsetTop);
+                    scrollSettings.element.scrollTo(0, scrollSettings.options);
+                }
+            }
+        }
+
+        /**
+        * Defines wheter to record the history for each hash change in the URL.
+        */
+        function setRecordHistory(value, type){
+            setVariableState('recordHistory', value, type);
+        }
+
+        /**
+        * Defines the scrolling speed
+        */
+        function setScrollingSpeed(value, type){
+            setVariableState('scrollingSpeed', value, type);
+        }
+
+        /**
+        * Sets fitToSection
+        */
+        function setFitToSection(value, type){
+            setVariableState('fitToSection', value, type);
+        }
+
+        /**
+        * Sets lockAnchors
+        */
+        function setLockAnchors(value){
+            options.lockAnchors = value;
+        }
+
+        /**
+        * Adds or remove the possibility of scrolling through sections by using the mouse wheel or the trackpad.
+        */
+        function setMouseWheelScrolling(value){
+            if(value){
+                addMouseWheelHandler();
+                addMiddleWheelHandler();
+            }else{
+                removeMouseWheelHandler();
+                removeMiddleWheelHandler();
+            }
+        }
+
+        /**
+        * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures.
+        * Optionally a second parameter can be used to specify the direction for which the action will be applied.
+        *
+        * @param directions string containing the direction or directions separated by comma.
+        */
+        function setAllowScrolling(value, directions){
+            if(typeof directions !== 'undefined'){
+                directions = directions.replace(/ /g,'').split(',');
+
+                directions.forEach(function (direction){
+                    setIsScrollAllowed(value, direction, 'm');
+                });
+            }
+            else{
+                setIsScrollAllowed(value, 'all', 'm');
+            }
+        }
+
+        /**
+        * Adds or remove the mouse wheel hijacking
+        */
+        function setMouseHijack(value){
+            if(value){
+                setMouseWheelScrolling(true);
+                addTouchHandler();
+            }else{
+                setMouseWheelScrolling(false);
+                removeTouchHandler();
+            }
+        }
+
+        /**
+        * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys
+        */
+        function setKeyboardScrolling(value, directions){
+            if(typeof directions !== 'undefined'){
+                directions = directions.replace(/ /g,'').split(',');
+
+                directions.forEach(function(direction){
+                    setIsScrollAllowed(value, direction, 'k');
+                });
+            }else{
+                setIsScrollAllowed(value, 'all', 'k');
+                options.keyboardScrolling = value;
+            }
+        }
+
+        /**
+        * Moves the page up one section.
+        */
+        function moveSectionUp(){
+            var prev = prevUntil($(SECTION_ACTIVE_SEL)[0], SECTION_SEL);
+
+            //looping to the bottom if there's no more sections above
+            if (!prev && (options.loopTop || options.continuousVertical)) {
+                prev = last($(SECTION_SEL));
+            }
+
+            if (prev != null) {
+                scrollPage(prev, null, true);
+            }
+        }
+
+        /**
+        * Moves the page down one section.
+        */
+        function moveSectionDown(){
+            var next = nextUntil($(SECTION_ACTIVE_SEL)[0], SECTION_SEL);
+
+            //looping to the top if there's no more sections below
+            if(!next &&
+                (options.loopBottom || options.continuousVertical)){
+                next = $(SECTION_SEL)[0];
+            }
+
+            if(next != null){
+                scrollPage(next, null, false);
+            }
+        }
+
+        /**
+        * Moves the page to the given section and slide with no animation.
+        * Anchors or index positions can be used as params.
+        */
+        function silentMoveTo(sectionAnchor, slideAnchor){
+            setScrollingSpeed (0, 'internal');
+            moveTo(sectionAnchor, slideAnchor);
+            setScrollingSpeed (originals.scrollingSpeed, 'internal');
+        }
+
+        /**
+        * Moves the page to the given section and slide.
+        * Anchors or index positions can be used as params.
+        */
+        function moveTo(sectionAnchor, slideAnchor){
+            var destiny = getSectionByAnchor(sectionAnchor);
+
+            if (typeof slideAnchor !== 'undefined'){
+                scrollPageAndSlide(sectionAnchor, slideAnchor);
+            }else if(destiny != null){
+                scrollPage(destiny);
+            }
+        }
+
+        /**
+        * Slides right the slider of the active section.
+        * Optional `section` param.
+        */
+        function moveSlideRight(section){
+            moveSlide('right', section);
+        }
+
+        /**
+        * Slides left the slider of the active section.
+        * Optional `section` param.
+        */
+        function moveSlideLeft(section){
+            moveSlide('left', section);
+        }
+
+        /**
+         * When resizing is finished, we adjust the slides sizes and positions
+         */
+        function reBuild(resizing){
+            if(hasClass(container, DESTROYED)){ return; }  //nothing to do if the plugin was destroyed
+
+            isResizing = true;
+
+            windowsHeight = getWindowHeight();  //updating global var
+
+            var sections = $(SECTION_SEL);
+            for (var i = 0; i < sections.length; ++i) {
+                var section = sections[i];
+                var slidesWrap = $(SLIDES_WRAPPER_SEL, section)[0];
+                var slides = $(SLIDE_SEL, section);
+
+                //adjusting the height of the table-cell for IE and Firefox
+                if(options.verticalCentered){
+                    css($(TABLE_CELL_SEL, section), {'height': getTableHeight(section) + 'px'});
+                }
+
+                css(section, {'height': windowsHeight + 'px'});
+
+                //adjusting the position fo the FULL WIDTH slides...
+                if (slides.length > 1) {
+                    landscapeScroll(slidesWrap, $(SLIDE_ACTIVE_SEL, slidesWrap)[0]);
+                }
+            }
+
+            if(options.scrollOverflow){
+                scrollBarHandler.createScrollBarForAll();
+            }
+
+            var activeSection = $(SECTION_ACTIVE_SEL)[0];
+            var sectionIndex = index(activeSection, SECTION_SEL);
+
+            //isn't it the first section?
+            if(sectionIndex){
+                //adjusting the position for the current section
+                silentMoveTo(sectionIndex + 1);
+            }
+
+            isResizing = false;
+            if(isFunction( options.afterResize ) && resizing){
+                options.afterResize.call(container, window.innerWidth, window.innerHeight);
+            }
+            if(isFunction( options.afterReBuild ) && !resizing){
+                options.afterReBuild.call(container);
+            }
+        }
+
+        /**
+        * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height`
+        * are smaller than the set limit values.
+        */
+        function setResponsive(active){
+            var isResponsive = hasClass($body, RESPONSIVE);
+
+            if(active){
+                if(!isResponsive){
+                    setAutoScrolling(false, 'internal');
+                    setFitToSection(false, 'internal');
+                    hide($(SECTION_NAV_SEL));
+                    addClass($body, RESPONSIVE);
+                    if(isFunction( options.afterResponsive )){
+                        options.afterResponsive.call( container, active);
+                    }
+                }
+            }
+            else if(isResponsive){
+                setAutoScrolling(originals.autoScrolling, 'internal');
+                setFitToSection(originals.autoScrolling, 'internal');
+                show($(SECTION_NAV_SEL));
+                removeClass($body, RESPONSIVE);
+                if(isFunction( options.afterResponsive )){
+                    options.afterResponsive.call( container, active);
+                }
+            }
+        }
+
+        if(container){
+            //public functions
+            FP.version = '3.0.2';
+            FP.setAutoScrolling = setAutoScrolling;
+            FP.setRecordHistory = setRecordHistory;
+            FP.setScrollingSpeed = setScrollingSpeed;
+            FP.setFitToSection = setFitToSection;
+            FP.setLockAnchors = setLockAnchors;
+            FP.setMouseWheelScrolling = setMouseWheelScrolling;
+            FP.setAllowScrolling = setAllowScrolling;
+            FP.setKeyboardScrolling = setKeyboardScrolling;
+            FP.moveSectionUp = moveSectionUp;
+            FP.moveSectionDown = moveSectionDown;
+            FP.silentMoveTo = silentMoveTo;
+            FP.moveTo = moveTo;
+            FP.moveSlideRight = moveSlideRight;
+            FP.moveSlideLeft = moveSlideLeft;
+            FP.fitToSection = fitToSection;
+            FP.reBuild = reBuild;
+            FP.setResponsive = setResponsive;
+            FP.getFullpageData = options;
+            FP.destroy = destroy;
+            FP.getActiveSection = getActiveSection;
+            FP.getActiveSlide = getActiveSlide;
+
+            FP.test = {
+                top: '0px',
+                translate3d: 'translate3d(0px, 0px, 0px)',
+                translate3dH: (function(){
+                    var a = [];
+                    for(var i = 0; i < $(options.sectionSelector, container).length; i++){
+                        a.push('translate3d(0px, 0px, 0px)');
+                    }
+                    return a;
+                })(),
+                left: (function(){
+                    var a = [];
+                    for(var i = 0; i < $(options.sectionSelector, container).length; i++){
+                        a.push(0);
+                    }
+                    return a;
+                })(),
+                options: options,
+                setAutoScrolling: setAutoScrolling
+            };
+
+            //functions we want to share across files but which are not
+            //mean to be used on their own by developers
+            FP.shared = {
+                afterRenderActions: afterRenderActions
+            };
+
+            window.fullpage_api = FP;
+
+            init();
+
+            bindEvents();
+        }
+
+        function init(){
+            //if css3 is not supported, it will use jQuery animations
+            if(options.css3){
+                options.css3 = support3d();
+            }
+
+            options.scrollBar = options.scrollBar || options.hybrid;
+
+            setOptionsFromDOM();
+            prepareDom();
+            setAllowScrolling(true);
+            setMouseHijack(true);
+            setAutoScrolling(options.autoScrolling, 'internal');
+            responsive();
+
+            //setting the class for the body element
+            setBodyClass();
+
+            if(document.readyState === 'complete'){
+                scrollToAnchor();
+            }
+            window.addEventListener('load', scrollToAnchor);
+        }
+
+        function bindEvents(){
+
+            //when scrolling...
+            window.addEventListener('scroll', scrollHandler);
+
+            //detecting any change on the URL to scroll to the given anchor link
+            //(a way to detect back history button as we play with the hashes on the URL)
+            window.addEventListener('hashchange', hashChangeHandler);
+
+            //when opening a new tab (ctrl + t), `control` won't be pressed when coming back.
+            window.addEventListener('blur', blurHandler);
+
+            //when resizing the site, we adjust the heights of the sections, slimScroll...
+            window.addEventListener('resize', resizeHandler);
+
+            //Sliding with arrow keys, both, vertical and horizontal
+            document.addEventListener('keydown', keydownHandler);
+
+            //to prevent scrolling while zooming
+            document.addEventListener('keyup', keyUpHandler);
+
+            //Scrolls to the section when clicking the navigation bullet
+            //simulating the jQuery .on('click') event using delegation
+            ['click', 'touchstart'].forEach(function(eventName){
+                document.addEventListener(eventName, delegatedEvents);
+            });
+
+            /**
+            * Applying normalScroll elements.
+            * Ignoring the scrolls over the specified selectors.
+            */
+            if(options.normalScrollElements){
+                ['mouseenter', 'touchstart'].forEach(function(eventName){
+                    forMouseLeaveOrTOuch(eventName, false);
+                });
+
+                ['mouseleave', 'touchend'].forEach(function(eventName){
+                   forMouseLeaveOrTOuch(eventName, true);
+                });
+            }
+        }
+
+        function delegatedEvents(e){
+            var target = e.target;
+
+            if(target && closest(target, SECTION_NAV_SEL + ' a')){
+                sectionBulletHandler.call(target, e);
+            }
+            else if(matches(target, SECTION_NAV_TOOLTIP_SEL)){
+                tooltipTextHandler.call(target);
+            }
+            else if(matches(target, SLIDES_ARROW_SEL)){
+                slideArrowHandler.call(target, e);
+            }
+            else if(matches(target, SLIDES_NAV_LINK_SEL) || closest(target, SLIDES_NAV_LINK_SEL) != null){
+                slideBulletHandler.call(target, e);
+            }
+        }
+
+        function forMouseLeaveOrTOuch(eventName, allowScrolling){
+            //a way to pass arguments to the onMouseEnterOrLeave function
+            document['fp_' + eventName] = allowScrolling;
+            document.addEventListener(eventName, onMouseEnterOrLeave, true); //capturing phase
+        }
+
+        function onMouseEnterOrLeave(e) {
+            if(e.target == document){
+                return;
+            }
+            var normalSelectors = options.normalScrollElements.split(',');
+            normalSelectors.forEach(function(normalSelector){
+                if(matches(e.target, normalSelector)){
+                    setMouseHijack(document['fp_' + e.type]); //e.type = eventName
+                }
+            });
+        }
+
+        /**
+        * Setting options from DOM elements if they are not provided.
+        */
+        function setOptionsFromDOM(){
+
+            //no anchors option? Checking for them in the DOM attributes
+            if(!options.anchors.length){
+                var attrName = '[data-anchor]';
+                var anchors = $(options.sectionSelector.split(',').join(attrName + ',') + attrName, container);
+                if(anchors.length){
+                    anchors.forEach(function(item){
+                        options.anchors.push(item.getAttribute('data-anchor').toString());
+                    });
+                }
+            }
+
+            //no tooltips option? Checking for them in the DOM attributes
+            if(!options.navigationTooltips.length){
+                var attrName = '[data-tooltip]';
+                var tooltips = $(options.sectionSelector.split(',').join(attrName + ',') + attrName, container);
+                if(tooltips.length){
+                    tooltips.forEach(function(item){
+                        options.navigationTooltips.push(item.getAttribute('data-tooltip').toString());
+                    });
+                }
+            }
+        }
+
+        /**
+        * Works over the DOM structure to set it up for the current fullpage options.
+        */
+        function prepareDom(){
+            css(container, {
+                'height': '100%',
+                'position': 'relative'
+            });
+
+            //adding a class to recognize the container internally in the code
+            addClass(container, WRAPPER);
+            addClass($('html'), ENABLED);
+
+            //due to https://github.com/alvarotrigo/fullPage.js/issues/1502
+            windowsHeight = getWindowHeight();
+
+            removeClass(container, DESTROYED); //in case it was destroyed before initializing it again
+
+            addInternalSelectors();
+
+            var sections = $(SECTION_SEL);
+
+            //styling the sections / slides / menu
+            for(var i = 0; i<sections.length; i++){
+                var sectionIndex = i;
+                var section = sections[i];
+                var slides = $(SLIDE_SEL, section);
+                var numSlides = slides.length;
+
+                //caching the original styles to add them back on destroy('all')
+                section.setAttribute('data-fp-styles', section.getAttribute('style'));
+
+                styleSection(section, sectionIndex);
+                styleMenu(section, sectionIndex);
+
+                // if there's any slide
+                if (numSlides > 0) {
+                    styleSlides(section, slides, numSlides);
+                }else{
+                    if(options.verticalCentered){
+                        addTableClass(section);
+                    }
+                }
+            }
+
+            //fixed elements need to be moved out of the plugin container due to problems with CSS3.
+            if(options.fixedElements && options.css3){
+                $(options.fixedElements).forEach(function(item){
+                    $body.appendChild(item);
+                });
+            }
+
+            //vertical centered of the navigation + active bullet
+            if(options.navigation){
+                addVerticalNavigation();
+            }
+
+            enableYoutubeAPI();
+
+            if(options.scrollOverflow){
+                scrollBarHandler = options.scrollOverflowHandler.init(options);
+            }else{
+                afterRenderActions();
+            }
+        }
+
+        /**
+        * Styles the horizontal slides for a section.
+        */
+        function styleSlides(section, slides, numSlides){
+            var sliderWidth = numSlides * 100;
+            var slideWidth = 100 / numSlides;
+
+            var slidesWrapper = document.createElement('div');
+            slidesWrapper.className = SLIDES_WRAPPER; //fp-slides
+            wrapAll(slides, slidesWrapper);
+
+            var slidesContainer = document.createElement('div');
+            slidesContainer.className = SLIDES_CONTAINER; //fp-slidesContainer
+            wrapAll(slides, slidesContainer);
+
+            css($(SLIDES_CONTAINER_SEL, section), {'width': sliderWidth + '%'});
+
+            if(numSlides > 1){
+                if(options.controlArrows){
+                    createSlideArrows(section);
+                }
+
+                if(options.slidesNavigation){
+                    addSlidesNavigation(section, numSlides);
+                }
+            }
+
+            slides.forEach(function(slide) {
+                css(slide, {'width': slideWidth + '%'});
+
+                if(options.verticalCentered){
+                    addTableClass(slide);
+                }
+            });
+
+            var startingSlide = $(SLIDE_ACTIVE_SEL, section)[0];
+
+            //if the slide won't be an starting point, the default will be the first one
+            //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/slide by default.
+            if( startingSlide != null && (index($(SECTION_ACTIVE_SEL), SECTION_SEL) !== 0 || (index($(SECTION_ACTIVE_SEL), SECTION_SEL) === 0 && index(startingSlide) !== 0))){
+                silentLandscapeScroll(startingSlide, 'internal');
+            }else{
+                addClass(slides[0], ACTIVE);
+            }
+        }
+
+        /**
+        * Styling vertical sections
+        */
+        function styleSection(section, index){
+            //if no active section is defined, the 1st one will be the default one
+            if(!index && $(SECTION_ACTIVE_SEL)[0] == null) {
+                addClass(section, ACTIVE);
+            }
+            startingSection = $(SECTION_ACTIVE_SEL)[0];
+
+            css(section, {'height': windowsHeight + 'px'});
+
+            if(options.paddingTop){
+                css(section, {'padding-top': options.paddingTop});
+            }
+
+            if(options.paddingBottom){
+                css(section, {'padding-bottom': options.paddingBottom});
+            }
+
+            if (typeof options.sectionsColor[index] !==  'undefined') {
+                css(section, {'background-color': options.sectionsColor[index]});
+            }
+
+            if (typeof options.anchors[index] !== 'undefined') {
+                section.setAttribute('data-anchor', options.anchors[index]);
+            }
+        }
+
+        /**
+        * Sets the data-anchor attributes to the menu elements and activates the current one.
+        */
+        function styleMenu(section, index){
+            if (typeof options.anchors[index] !== 'undefined') {
+                //activating the menu / nav element on load
+                if(hasClass(section, ACTIVE)){
+                    activateMenuAndNav(options.anchors[index], index);
+                }
+            }
+
+            //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms)
+            if(options.menu && options.css3 && closest($(options.menu)[0], WRAPPER_SEL) != null){
+                $body.appendChild($(options.menu)[0]);
+            }
+        }
+
+        /**
+        * Adds internal classes to be able to provide customizable selectors
+        * keeping the link with the style sheet.
+        */
+        function addInternalSelectors(){
+            addClass($(options.sectionSelector, container), SECTION);
+            addClass($(options.slideSelector, container), SLIDE);
+        }
+
+        /**
+        * Creates the control arrows for the given section
+        */
+        function createSlideArrows(section){
+            var arrows = [createElementFromHTML('<div class="' + SLIDES_ARROW_PREV + '"></div>'), createElementFromHTML('<div class="' + SLIDES_ARROW_NEXT + '"></div>')];
+            after($(SLIDES_WRAPPER_SEL, section)[0], arrows);
+
+            if(options.controlArrowColor !== '#fff'){
+                css($(SLIDES_ARROW_NEXT_SEL, section), {'border-color': 'transparent transparent transparent '+options.controlArrowColor});
+                css($(SLIDES_ARROW_PREV_SEL, section), {'border-color': 'transparent '+ options.controlArrowColor + ' transparent transparent'});
+            }
+
+            if(!options.loopHorizontal){
+                hide($(SLIDES_ARROW_PREV_SEL, section));
+            }
+        }
+
+        /**
+        * Creates a vertical navigation bar.
+        */
+        function addVerticalNavigation(){
+            var navigation = document.createElement('div');
+            navigation.setAttribute('id', SECTION_NAV);
+
+            var divUl = document.createElement('ul');
+            navigation.appendChild(divUl);
+
+            appendTo(navigation, $body);
+            var nav = $(SECTION_NAV_SEL)[0];
+
+            addClass(nav, 'fp-' + options.navigationPosition);
+
+            if(options.showActiveTooltip){
+                addClass(nav, SHOW_ACTIVE_TOOLTIP);
+            }
+
+            var li = '';
+
+            for (var i = 0; i < $(SECTION_SEL).length; i++) {
+                var link = '';
+                if (options.anchors.length) {
+                    link = options.anchors[i];
+                }
+
+                li += '<li><a href="#' + link + '"><span class="fp-sr-only">' + getBulletLinkName(i, 'Section') + '</span><span></span></a>';
+
+                // Only add tooltip if needed (defined by user)
+                var tooltip = options.navigationTooltips[i];
+
+                if (typeof tooltip !== 'undefined' && tooltip !== '') {
+                    li += '<div class="' + SECTION_NAV_TOOLTIP + ' fp-' + options.navigationPosition + '">' + tooltip + '</div>';
+                }
+
+                li += '</li>';
+            }
+            $('ul', nav)[0].innerHTML = li;
+
+            //centering it vertically
+            css($(SECTION_NAV_SEL), {'margin-top': '-' + ($(SECTION_NAV_SEL)[0].offsetHeight/2) + 'px'});
+
+            //activating the current active section
+
+            var bullet = $('li', $(SECTION_NAV_SEL)[0])[index($(SECTION_ACTIVE_SEL)[0], SECTION_SEL)];
+            addClass($('a', bullet), ACTIVE);
+        }
+
+        /**
+        * Gets the name for screen readers for a section/slide navigation bullet.
+        */
+        function getBulletLinkName(i, defaultName){
+            return options.navigationTooltips[i]
+                || options.anchors[i]
+                || defaultName + ' ' + (i+1)
+        }
+
+        /*
+        * Enables the Youtube videos API so we can control their flow if necessary.
+        */
+        function enableYoutubeAPI(){
+            $('iframe[src*="youtube.com/embed/"]', container).forEach(function(item){
+                addURLParam(item, 'enablejsapi=1');
+            });
+        }
+
+        /**
+        * Adds a new parameter and its value to the `src` of a given element
+        */
+        function addURLParam(element, newParam){
+            var originalSrc = element.getAttribute('src');
+            element.setAttribute('src', originalSrc + getUrlParamSign(originalSrc) + newParam);
+        }
+
+        /*
+        * Returns the prefix sign to use for a new parameter in an existen URL.
+        *
+        * @return {String}  ? | &
+        */
+        function getUrlParamSign(url){
+            return ( !/\?/.test( url ) ) ? '?' : '&';
+        }
+
+        /**
+        * Actions and callbacks to fire afterRender
+        */
+        function afterRenderActions(){
+            var section = $(SECTION_ACTIVE_SEL)[0];
+
+            addClass(section, COMPLETELY);
+
+            lazyLoad(section);
+            playMedia(section);
+
+            if(options.scrollOverflow){
+                options.scrollOverflowHandler.afterLoad();
+            }
+
+            if(isDestinyTheStartingSection() && isFunction(options.afterLoad) ){
+                fireCallback('afterLoad', {
+                    activeSection: null,
+                    element: section,
+                    direction: null,
+
+                    //for backwards compatibility callback (to be removed in a future!)
+                    anchorLink: section.getAttribute('data-anchor'),
+                    sectionIndex: index(section, SECTION_SEL)
+                });
+            }
+
+            if(isFunction(options.afterRender)){
+                fireCallback('afterRender');
+            }
+        }
+
+        /**
+        * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization)
+        */
+        function isDestinyTheStartingSection(){
+            var destinationSection = getSectionByAnchor(getAnchorsURL().section);
+            return !destinationSection || typeof destinationSection !=='undefined' && index(destinationSection) === index(startingSection);
+        }
+
+        var isScrolling = false;
+        var lastScroll = 0;
+
+        //when scrolling...
+        function scrollHandler(){
+            var currentSection;
+
+            if(!options.autoScrolling || options.scrollBar){
+                var currentScroll = getScrollTop();
+                var scrollDirection = getScrollDirection(currentScroll);
+                var visibleSectionIndex = 0;
+                var screen_mid = currentScroll + (getWindowHeight() / 2.0);
+                var isAtBottom = $body.offsetHeight - getWindowHeight() === currentScroll;
+                var sections =  $(SECTION_SEL);
+
+                //when using `auto-height` for a small last section it won't be centered in the viewport
+                if(isAtBottom){
+                    visibleSectionIndex = sections.length - 1;
+                }
+                //is at top? when using `auto-height` for a small first section it won't be centered in the viewport
+                else if(!currentScroll){
+                    visibleSectionIndex = 0;
+                }
+
+                //taking the section which is showing more content in the viewport
+                else{
+                    for (var i = 0; i < sections.length; ++i) {
+                        var section = sections[i];
+
+                        // Pick the the last section which passes the middle line of the screen.
+                        if (section.offsetTop <= screen_mid)
+                        {
+                            visibleSectionIndex = i;
+                        }
+                    }
+                }
+
+                if(isCompletelyInViewPort(scrollDirection)){
+                    if(!hasClass($(SECTION_ACTIVE_SEL)[0], COMPLETELY)){
+                        addClass($(SECTION_ACTIVE_SEL)[0], COMPLETELY);
+                        removeClass(siblings($(SECTION_ACTIVE_SEL)[0]), COMPLETELY);
+                    }
+                }
+
+                //geting the last one, the current one on the screen
+                currentSection = sections[visibleSectionIndex];
+
+                //setting the visible section as active when manually scrolling
+                //executing only once the first time we reach the section
+                if(!hasClass(currentSection, ACTIVE)){
+                    isScrolling = true;
+                    var leavingSection = $(SECTION_ACTIVE_SEL)[0];
+                    var leavingSectionIndex = index(leavingSection, SECTION_SEL) + 1;
+                    var yMovement = getYmovement(currentSection);
+                    var anchorLink  = currentSection.getAttribute('data-anchor');
+                    var sectionIndex = index(currentSection, SECTION_SEL) + 1;
+                    var activeSlide = $(SLIDE_ACTIVE_SEL, currentSection)[0];
+                    var slideIndex;
+                    var slideAnchorLink;
+                    var callbacksParams = {
+                        activeSection: leavingSection,
+                        sectionIndex: sectionIndex -1,
+                        anchorLink: anchorLink,
+                        element: currentSection,
+                        leavingSection: leavingSectionIndex,
+                        direction: yMovement
+                    };
+
+                    if(activeSlide){
+                        slideAnchorLink = activeSlide.getAttribute('data-anchor');
+                        slideIndex = index(activeSlide);
+                    }
+
+                    if(canScroll){
+                        addClass(currentSection, ACTIVE);
+                        removeClass(siblings(currentSection), ACTIVE);
+
+                        if(isFunction( options.onLeave )){
+                            fireCallback('onLeave', callbacksParams);
+                        }
+                        if(isFunction( options.afterLoad )){
+                            fireCallback('afterLoad', callbacksParams);
+                        }
+
+                        stopMedia(leavingSection);
+                        lazyLoad(currentSection);
+                        playMedia(currentSection);
+
+                        activateMenuAndNav(anchorLink, sectionIndex - 1);
+
+                        if(options.anchors.length){
+                            //needed to enter in hashChange event when using the menu with anchor links
+                            lastScrolledDestiny = anchorLink;
+                        }
+                        setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex);
+                    }
+
+                    //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet
+                    clearTimeout(scrollId);
+                    scrollId = setTimeout(function(){
+                        isScrolling = false;
+                    }, 100);
+                }
+
+                if(options.fitToSection){
+                    //for the auto adjust of the viewport to fit a whole section
+                    clearTimeout(scrollId2);
+
+                    scrollId2 = setTimeout(function(){
+                        //checking it again in case it changed during the delay
+                        if(options.fitToSection &&
+
+                            //is the destination element bigger than the viewport?
+                            $(SECTION_ACTIVE_SEL)[0].offsetHeight <= windowsHeight
+                        ){
+                            fitToSection();
+                        }
+                    }, options.fitToSectionDelay);
+                }
+            }
+        }
+
+        /**
+        * Fits the site to the nearest active section
+        */
+        function fitToSection(){
+            //checking fitToSection again in case it was set to false before the timeout delay
+            if(canScroll){
+                //allows to scroll to an active section and
+                //if the section is already active, we prevent firing callbacks
+                isResizing = true;
+
+                scrollPage($(SECTION_ACTIVE_SEL)[0]);
+                isResizing = false;
+            }
+        }
+
+        /**
+        * Determines whether the active section has seen in its whole or not.
+        */
+        function isCompletelyInViewPort(movement){
+            var top = $(SECTION_ACTIVE_SEL)[0].offsetTop;
+            var bottom = top + getWindowHeight();
+
+            if(movement == 'up'){
+                return bottom >= (getScrollTop() + getWindowHeight());
+            }
+            return top <= getScrollTop();
+        }
+
+        /**
+        * Gets the directon of the the scrolling fired by the scroll event.
+        */
+        function getScrollDirection(currentScroll){
+            var direction = currentScroll > lastScroll ? 'down' : 'up';
+
+            lastScroll = currentScroll;
+
+            //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination
+            previousDestTop = currentScroll;
+
+            return direction;
+        }
+
+        /**
+        * Determines the way of scrolling up or down:
+        * by 'automatically' scrolling a section or by using the default and normal scrolling.
+        */
+        function scrolling(type){
+            if (!isScrollAllowed.m[type]){
+                return;
+            }
+
+            var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp;
+
+            if(options.scrollOverflow){
+                var scrollable = options.scrollOverflowHandler.scrollable($(SECTION_ACTIVE_SEL)[0]);
+                var check = (type === 'down') ? 'bottom' : 'top';
+
+                if(scrollable != null ){
+                    //is the scrollbar at the start/end of the scroll?
+                    if(options.scrollOverflowHandler.isScrolled(check, scrollable)){
+                        scrollSection();
+                    }else{
+                        return true;
+                    }
+                }else{
+                    // moved up/down
+                    scrollSection();
+                }
+            }else{
+                // moved up/down
+                scrollSection();
+            }
+        }
+
+        /*
+        * Preventing bouncing in iOS #2285
+        */
+        function preventBouncing(e){
+            if(options.autoScrolling && isReallyTouch(e)){
+                //preventing the easing on iOS devices
+                preventDefault(e);
+            }
+        }
+
+        var touchStartY = 0;
+        var touchStartX = 0;
+        var touchEndY = 0;
+        var touchEndX = 0;
+
+        /* Detecting touch events
+
+        * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it.
+        * This way, the touchstart and the touch moves shows an small difference between them which is the
+        * used one to determine the direction.
+        */
+        function touchMoveHandler(e){
+            var activeSection = closest(e.target, SECTION_SEL);
+
+            // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain
+            if (isReallyTouch(e) ) {
+
+                if(options.autoScrolling){
+                    //preventing the easing on iOS devices
+                    preventDefault(e);
+                }
+
+                var touchEvents = getEventsPage(e);
+
+                touchEndY = touchEvents.y;
+                touchEndX = touchEvents.x;
+
+                //if movement in the X axys is greater than in the Y and the currect section has slides...
+                if ($(SLIDES_WRAPPER_SEL, activeSection).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) {
+
+                    //is the movement greater than the minimum resistance to scroll?
+                    if (!slideMoving && Math.abs(touchStartX - touchEndX) > (window.innerWidth / 100 * options.touchSensitivity)) {
+                        if (touchStartX > touchEndX) {
+                            if(isScrollAllowed.m.right){
+                                moveSlideRight(activeSection); //next
+                            }
+                        } else {
+                            if(isScrollAllowed.m.left){
+                                moveSlideLeft(activeSection); //prev
+                            }
+                        }
+                    }
+                }
+
+                //vertical scrolling (only when autoScrolling is enabled)
+                else if(options.autoScrolling && canScroll){
+
+                    //is the movement greater than the minimum resistance to scroll?
+                    if (Math.abs(touchStartY - touchEndY) > (window.innerHeight / 100 * options.touchSensitivity)) {
+                        if (touchStartY > touchEndY) {
+                            scrolling('down');
+                        } else if (touchEndY > touchStartY) {
+                            scrolling('up');
+                        }
+                    }
+                }
+            }
+        }
+
+        /**
+        * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen
+        * this way we make sure that is really a touch event what IE is detecting.
+        */
+        function isReallyTouch(e){
+            //if is not IE   ||  IE is detecting `touch` or `pen`
+            return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse';
+        }
+
+        /**
+        * Handler for the touch start event.
+        */
+        function touchStartHandler(e){
+
+            //stopping the auto scroll to adjust to a section
+            if(options.fitToSection){
+                activeAnimation = false;
+            }
+
+            if(isReallyTouch(e)){
+                var touchEvents = getEventsPage(e);
+                touchStartY = touchEvents.y;
+                touchStartX = touchEvents.x;
+            }
+        }
+
+        /**
+        * Gets the average of the last `number` elements of the given array.
+        */
+        function getAverage(elements, number){
+            var sum = 0;
+
+            //taking `number` elements from the end to make the average, if there are not enought, 1
+            var lastElements = elements.slice(Math.max(elements.length - number, 1));
+
+            for(var i = 0; i < lastElements.length; i++){
+                sum = sum + lastElements[i];
+            }
+
+            return Math.ceil(sum/number);
+        }
+
+        /**
+         * Detecting mousewheel scrolling
+         *
+         * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html
+         * http://www.sitepoint.com/html5-javascript-mouse-wheel/
+         */
+        var prevTime = new Date().getTime();
+
+        function MouseWheelHandler(e) {
+            var curTime = new Date().getTime();
+            var isNormalScroll = hasClass($(COMPLETELY_SEL)[0], NORMAL_SCROLL);
+
+            //is scroll allowed?
+            if (!isScrollAllowed.m.down && !isScrollAllowed.m.up) {
+                preventDefault(e);
+                return false;
+            }
+
+            //autoscrolling and not zooming?
+            if(options.autoScrolling && !controlPressed && !isNormalScroll){
+                // cross-browser wheel delta
+                e = e || window.event;
+                var value = e.wheelDelta || -e.deltaY || -e.detail;
+                var delta = Math.max(-1, Math.min(1, value));
+
+                var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined';
+                var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection);
+
+                //Limiting the array to 150 (lets not waste memory!)
+                if(scrollings.length > 149){
+                    scrollings.shift();
+                }
+
+                //keeping record of the previous scrollings
+                scrollings.push(Math.abs(value));
+
+                //preventing to scroll the site on mouse wheel when scrollbar is present
+                if(options.scrollBar){
+                   preventDefault(e);
+                }
+
+                //time difference between the last scroll and the current one
+                var timeDiff = curTime-prevTime;
+                prevTime = curTime;
+
+                //haven't they scrolled in a while?
+                //(enough to be consider a different scrolling action to scroll another section)
+                if(timeDiff > 200){
+                    //emptying the array, we dont care about old scrollings for our averages
+                    scrollings = [];
+                }
+
+                if(canScroll){
+                    var averageEnd = getAverage(scrollings, 10);
+                    var averageMiddle = getAverage(scrollings, 70);
+                    var isAccelerating = averageEnd >= averageMiddle;
+
+                    //to avoid double swipes...
+                    if(isAccelerating && isScrollingVertically){
+                        //scrolling down?
+                        if (delta < 0) {
+                            scrolling('down');
+
+                        //scrolling up?
+                        }else {
+                            scrolling('up');
+                        }
+                    }
+                }
+
+                return false;
+            }
+
+            if(options.fitToSection){
+                //stopping the auto scroll to adjust to a section
+                activeAnimation = false;
+            }
+        }
+
+        /**
+        * Slides a slider to the given direction.
+        * Optional `section` param.
+        */
+        function moveSlide(direction, section){
+            var activeSection = section == null ? $(SECTION_ACTIVE_SEL)[0] : section;
+            var slides = $(SLIDES_WRAPPER_SEL, activeSection)[0];
+
+            // more than one slide needed and nothing should be sliding
+            if (slides == null || slideMoving || $(SLIDE_SEL, slides).length < 2) {
+                return;
+            }
+
+            var currentSlide = $(SLIDE_ACTIVE_SEL, slides)[0];
+            var destiny = null;
+
+            if(direction === 'left'){
+                destiny = prevUntil(currentSlide, SLIDE_SEL);
+            }else{
+                destiny = nextUntil(currentSlide, SLIDE_SEL);
+            }
+
+            //isn't there a next slide in the secuence?
+            if(destiny == null){
+                //respect loopHorizontal settin
+                if (!options.loopHorizontal) return;
+
+                var slideSiblings = siblings(currentSlide);
+                if(direction === 'left'){
+                    destiny = slideSiblings[slideSiblings.length - 1]; //last
+                }else{
+                    destiny = slideSiblings[0]; //first
+                }
+            }
+
+            slideMoving = true && !FP.test.isTesting;
+            landscapeScroll(slides, destiny, direction);
+        }
+
+        /**
+        * Maintains the active slides in the viewport
+        * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical)
+        */
+        function keepSlidesPosition(){
+            var activeSlides = $(SLIDE_ACTIVE_SEL);
+            for( var i =0; i<activeSlides.length; i++){
+                silentLandscapeScroll(activeSlides[i], 'internal');
+            }
+        }
+
+        var previousDestTop = 0;
+        /**
+        * Returns the destination Y position based on the scrolling direction and
+        * the height of the section.
+        */
+        function getDestinationPosition(element){
+            var elementHeight = element.offsetHeight;
+            var elementTop = element.offsetTop;
+
+            //top of the desination will be at the top of the viewport
+            var position = elementTop;
+            var isScrollingDown =  elementTop > previousDestTop;
+            var sectionBottom = position - windowsHeight + elementHeight;
+            var bigSectionsDestination = options.bigSectionsDestination;
+
+            //is the destination element bigger than the viewport?
+            if(elementHeight > windowsHeight){
+                //scrolling up?
+                if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){
+                    position = sectionBottom;
+                }
+            }
+
+            //sections equal or smaller than the viewport height && scrolling down? ||  is resizing and its in the last section
+            else if(isScrollingDown || (isResizing && next(element) == null) ){
+                //The bottom of the destination will be at the bottom of the viewport
+                position = sectionBottom;
+            }
+
+            /*
+            Keeping record of the last scrolled position to determine the scrolling direction.
+            No conventional methods can be used as the scroll bar might not be present
+            AND the section might not be active if it is auto-height and didnt reach the middle
+            of the viewport.
+            */
+            previousDestTop = position;
+            return position;
+        }
+
+        /**
+        * Scrolls the site to the given element and scrolls to the slide if a callback is given.
+        */
+        function scrollPage(element, callback, isMovementUp){
+            if(element == null){ return; } //there's no element to scroll, leaving the function
+
+            var dtop = getDestinationPosition(element);
+            var slideAnchorLink;
+            var slideIndex;
+
+            //local variables
+            var v = {
+                element: element,
+                callback: callback,
+                isMovementUp: isMovementUp,
+                dtop: dtop,
+                yMovement: getYmovement(element),
+                anchorLink: element.getAttribute('data-anchor'),
+                sectionIndex: index(element, SECTION_SEL),
+                activeSlide: $(SLIDE_ACTIVE_SEL, element)[0],
+                activeSection: $(SECTION_ACTIVE_SEL)[0],
+                leavingSection: index($(SECTION_ACTIVE_SEL), SECTION_SEL) + 1,
+
+                //caching the value of isResizing at the momment the function is called
+                //because it will be checked later inside a setTimeout and the value might change
+                localIsResizing: isResizing
+            };
+
+            //quiting when destination scroll is the same as the current one
+            if((v.activeSection == element && !isResizing) || (options.scrollBar && getScrollTop() === v.dtop && !hasClass(element, AUTO_HEIGHT) )){ return; }
+
+            if(v.activeSlide != null){
+                slideAnchorLink = v.activeSlide.getAttribute('data-anchor');
+                slideIndex = index(v.activeSlide);
+            }
+
+            //callback (onLeave) if the site is not just resizing and readjusting the slides
+            if(isFunction(options.onLeave) && !v.localIsResizing){
+                var direction = v.yMovement;
+
+                //required for continousVertical
+                if(typeof isMovementUp !== 'undefined'){
+                    direction = isMovementUp ? 'up' : 'down';
+                }
+
+                //for the callback
+                v.direction = direction;
+
+                if(fireCallback('onLeave', v) === false){
+                    return;
+                }
+            }
+
+            // If continuousVertical && we need to wrap around
+            if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" &&
+                ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or
+                (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down
+
+                v = createInfiniteSections(v);
+            }
+
+            //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one)
+            if(!v.localIsResizing){
+                stopMedia(v.activeSection);
+            }
+
+            if(options.scrollOverflow){
+                options.scrollOverflowHandler.beforeLeave();
+            }
+
+            addClass(element, ACTIVE);
+            removeClass(siblings(element), ACTIVE);
+            lazyLoad(element);
+
+            if(options.scrollOverflow){
+                options.scrollOverflowHandler.onLeave();
+            }
+
+            //preventing from activating the MouseWheelHandler event
+            //more than once if the page is scrolling
+            canScroll = false || FP.test.isTesting;
+
+            setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex);
+
+            performMovement(v);
+
+            //flag to avoid callingn `scrollPage()` twice in case of using anchor links
+            lastScrolledDestiny = v.anchorLink;
+
+            //avoid firing it twice (as it does also on scroll)
+            activateMenuAndNav(v.anchorLink, v.sectionIndex);
+        }
+
+        /**
+        * Dispatch events & callbacks making sure it does it on the right format, depending on
+        * whether v2compatible is being used or not.
+        */
+        function fireCallback(eventName, v){
+            var eventData = getEventData(eventName, v);
+
+            if(!options.v2compatible){
+                trigger(container, eventName, eventData);
+
+                if(options[eventName].apply(eventData[Object.keys(eventData)[0]], toArray(eventData)) === false){
+                    return false;
+                }
+            }
+            else{
+                if(options[eventName].apply(eventData[0], eventData.slice(1)) === false){
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        /**
+        * Makes sure to only create a Panel object if the element exist
+        */
+        function nullOrSection(el){
+            return el ? new Section(el) : null;
+        }
+
+        function nullOrSlide(el){
+            return el ? new Slide(el) : null;
+        }
+
+        /**
+        * Gets the event's data for the given event on the right format. Depending on whether
+        * v2compatible is being used or not.
+        */
+        function getEventData(eventName, v){
+            var paramsPerEvent;
+
+            if(!options.v2compatible){
+
+                //using functions to run only the necessary bits within the object
+                paramsPerEvent = {
+                    afterRender: function(){
+                        return {
+                            section: nullOrSection($(SECTION_ACTIVE_SEL)[0]),
+                            slide: nullOrSlide($(SLIDE_ACTIVE_SEL, $(SECTION_ACTIVE_SEL)[0])[0])
+                        };
+                    },
+                    onLeave: function(){
+                        return {
+                            origin: nullOrSection(v.activeSection),
+                            destination: nullOrSection(v.element),
+                            direction: v.direction
+                        };
+                    },
+
+                    afterLoad: function(){
+                        return paramsPerEvent.onLeave();
+                    },
+
+                    afterSlideLoad: function(){
+                        return {
+                            section: nullOrSection(v.section),
+                            origin: nullOrSlide(v.prevSlide),
+                            destination: nullOrSlide(v.destiny),
+                            direction: v.direction
+                        };
+                    },
+
+                    onSlideLeave: function(){
+                        return paramsPerEvent.afterSlideLoad();
+                    }
+                };
+            }
+            else{
+                paramsPerEvent = {
+                    afterRender: function(){ return [container]; },
+                    onLeave: function(){ return [v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.direction]; },
+                    afterLoad: function(){ return [v.element, v.anchorLink, (v.sectionIndex + 1)]; },
+                    afterSlideLoad: function(){ return [v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex]; },
+                    onSlideLeave: function(){ return [v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.direction, v.slideIndex]; },
+                };
+            }
+
+            return paramsPerEvent[eventName]();
+        }
+
+        /**
+        * Performs the vertical movement (by CSS3 or by jQuery)
+        */
+        function performMovement(v){
+            // using CSS3 translate functionality
+            if (options.css3 && options.autoScrolling && !options.scrollBar) {
+
+                // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625
+                // that's why we round it to 0.
+                var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)';
+                transformContainer(translate3d, true);
+
+                //even when the scrollingSpeed is 0 there's a little delay, which might cause the
+                //scrollingSpeed to change in case of using silentMoveTo();
+                if(options.scrollingSpeed){
+                    clearTimeout(afterSectionLoadsId);
+                    afterSectionLoadsId = setTimeout(function () {
+                        afterSectionLoads(v);
+                    }, options.scrollingSpeed);
+                }else{
+                    afterSectionLoads(v);
+                }
+            }
+
+            // using JS to animate
+            else{
+                var scrollSettings = getScrollSettings(v.dtop);
+                FP.test.top = -v.dtop + 'px';
+
+                scrollTo(scrollSettings.element, scrollSettings.options, options.scrollingSpeed, function(){
+                    if(options.scrollBar){
+
+                        /* Hack!
+                        The timeout prevents setting the most dominant section in the viewport as "active" when the user
+                        scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar.
+
+                        When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished.
+                        */
+                        setTimeout(function(){
+                            afterSectionLoads(v);
+                        },30);
+                    }else{
+                        afterSectionLoads(v);
+                    }
+                });
+            }
+        }
+
+        /**
+        * Gets the scrolling settings depending on the plugin autoScrolling option
+        */
+        function getScrollSettings(top){
+            var scroll = {};
+
+            //top property animation
+            if(options.autoScrolling && !options.scrollBar){
+                scroll.options = -top;
+                scroll.element = $(WRAPPER_SEL)[0];
+            }
+
+            //window real scrolling
+            else{
+                scroll.options = top;
+                scroll.element = window;
+            }
+
+            return scroll;
+        }
+
+        /**
+        * Adds sections before or after the current one to create the infinite effect.
+        */
+        function createInfiniteSections(v){
+            // Scrolling down
+            if (!v.isMovementUp) {
+                // Move all previous sections to after the active section
+                after($(SECTION_ACTIVE_SEL)[0], prevAll(v.activeSection, SECTION_SEL).reverse());
+            }
+            else { // Scrolling up
+                // Move all next sections to before the active section
+                before($(SECTION_ACTIVE_SEL)[0], nextAll(v.activeSection, SECTION_SEL));
+            }
+
+            // Maintain the displayed position (now that we changed the element order)
+            silentScroll($(SECTION_ACTIVE_SEL)[0].offsetTop);
+
+            // Maintain the active slides visible in the viewport
+            keepSlidesPosition();
+
+            // save for later the elements that still need to be reordered
+            v.wrapAroundElements = v.activeSection;
+
+            // Recalculate animation variables
+            v.dtop = v.element.offsetTop;
+            v.yMovement = getYmovement(v.element);
+
+            //sections will temporally have another position in the DOM
+            //updating this values in case we need them
+            v.leavingSection = index(v.activeSection, SECTION_SEL) + 1;
+            v.sectionIndex = index(v.element, SECTION_SEL);
+
+            return v;
+        }
+
+        /**
+        * Fix section order after continuousVertical changes have been animated
+        */
+        function continuousVerticalFixSectionOrder (v) {
+            // If continuousVertical is in effect (and autoScrolling would also be in effect then),
+            // finish moving the elements around so the direct navigation will function more simply
+            if (v.wrapAroundElements == null) {
+                return;
+            }
+
+            if (v.isMovementUp) {
+                before($(SECTION_SEL)[0], v.wrapAroundElements);
+            }
+            else {
+                after($(SECTION_SEL)[$(SECTION_SEL).length-1], v.wrapAroundElements);
+            }
+
+            silentScroll($(SECTION_ACTIVE_SEL)[0].offsetTop);
+
+            // Maintain the active slides visible in the viewport
+            keepSlidesPosition();
+        }
+
+
+        /**
+        * Actions to do once the section is loaded.
+        */
+        function afterSectionLoads (v){
+            continuousVerticalFixSectionOrder(v);
+
+            //callback (afterLoad) if the site is not just resizing and readjusting the slides
+            if(isFunction(options.afterLoad) && !v.localIsResizing){
+                fireCallback('afterLoad', v);
+            }
+
+            if(options.scrollOverflow){
+                options.scrollOverflowHandler.afterLoad();
+            }
+
+            if(!v.localIsResizing){
+                playMedia(v.element);
+            }
+
+            addClass(v.element, COMPLETELY);
+            removeClass(siblings(v.element), COMPLETELY);
+
+            canScroll = true;
+
+            if(isFunction(v.callback)){
+                v.callback();
+            }
+        }
+
+        /**
+        * Sets the value for the given attribute from the `data-` attribute with the same suffix
+        * ie: data-srcset ==> srcset  |  data-src ==> src
+        */
+        function setSrc(element, attribute){
+            element.setAttribute(attribute, element.getAttribute('data-' + attribute));
+            element.removeAttribute('data-' + attribute);
+        }
+
+        /**
+        * Lazy loads image, video and audio elements.
+        */
+        function lazyLoad(destiny){
+            if (!options.lazyLoading){
+                return;
+            }
+
+            var panel = getSlideOrSection(destiny);
+
+            $('img[data-src], img[data-srcset], source[data-src], source[data-srcset], video[data-src], audio[data-src], iframe[data-src]', panel).forEach(function(element){
+                ['src', 'srcset'].forEach(function(type){
+                    var attribute = element.getAttribute('data-' + type);
+                    if(attribute != null && attribute){
+                        setSrc(element, type);
+                    }
+                });
+
+                if(matches(element, 'source')){
+                    var elementToPlay =  closest(element, 'video, audio');
+                    if(elementToPlay){
+                        elementToPlay.load();
+                    }
+                }
+            });
+        }
+
+        /**
+        * Plays video and audio elements.
+        */
+        function playMedia(destiny){
+            var panel = getSlideOrSection(destiny);
+
+            //playing HTML5 media elements
+            $('video, audio', panel).forEach(function(element){
+                if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) {
+                    element.play();
+                }
+            });
+
+            //youtube videos
+            $('iframe[src*="youtube.com/embed/"]', panel).forEach(function(element){
+                if ( element.hasAttribute('data-autoplay') ){
+                    playYoutube(element);
+                }
+
+                //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load.
+                element.onload = function() {
+                    if ( element.hasAttribute('data-autoplay') ){
+                        playYoutube(element);
+                    }
+                };
+            });
+        }
+
+        /**
+        * Plays a youtube video
+        */
+        function playYoutube(element){
+            element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
+        }
+
+        /**
+        * Stops video and audio elements.
+        */
+        function stopMedia(destiny){
+            var panel = getSlideOrSection(destiny);
+
+            //stopping HTML5 media elements
+            $('video, audio', panel).forEach(function(element){
+                if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) {
+                    element.pause();
+                }
+            });
+
+            //youtube videos
+            $('iframe[src*="youtube.com/embed/"]', panel).forEach(function(element){
+                if( /youtube\.com\/embed\//.test(element.getAttribute('src')) && !element.hasAttribute('data-keepplaying')){
+                    element.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*');
+                }
+            });
+        }
+
+        /**
+        * Gets the active slide (or section) for the given section
+        */
+        function getSlideOrSection(destiny){
+            var slide = $(SLIDE_ACTIVE_SEL, destiny);
+            if( slide.length ) {
+                destiny = slide[0];
+            }
+
+            return destiny;
+        }
+
+        /**
+        * Scrolls to the anchor in the URL when loading the site
+        */
+        function scrollToAnchor(){
+            var anchors =  getAnchorsURL();
+            var sectionAnchor = anchors.section;
+            var slideAnchor = anchors.slide;
+
+            if(sectionAnchor){  //if theres any #
+                if(options.animateAnchor){
+                    scrollPageAndSlide(sectionAnchor, slideAnchor);
+                }else{
+                    silentMoveTo(sectionAnchor, slideAnchor);
+                }
+            }
+        }
+
+        /**
+        * Detecting any change on the URL to scroll to the given anchor link
+        * (a way to detect back history button as we play with the hashes on the URL)
+        */
+        function hashChangeHandler(){
+            if(!isScrolling && !options.lockAnchors){
+                var anchors = getAnchorsURL();
+                var sectionAnchor = anchors.section;
+                var slideAnchor = anchors.slide;
+
+                //when moving to a slide in the first section for the first time (first time to add an anchor to the URL)
+                var isFirstSlideMove =  (typeof lastScrolledDestiny === 'undefined');
+                var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving);
+
+                if(sectionAnchor && sectionAnchor.length){
+                    /*in order to call scrollpage() only once for each destination at a time
+                    It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange`
+                    event is fired on every scroll too.*/
+                    if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove
+                        || isFirstScrollMove
+                        || (!slideMoving && lastScrolledSlide != slideAnchor )){
+
+                        scrollPageAndSlide(sectionAnchor, slideAnchor);
+                    }
+                }
+            }
+        }
+
+        //gets the URL anchors (section and slide)
+        function getAnchorsURL(){
+            var section;
+            var slide;
+            var hash = window.location.hash;
+
+            if(hash.length){
+                //getting the anchor link in the URL and deleting the `#`
+                var anchorsParts =  hash.replace('#', '').split('/');
+
+                //using / for visual reasons and not as a section/slide separator #2803
+                var isFunkyAnchor = hash.indexOf('#/') > -1;
+
+                section = isFunkyAnchor ? '/' + anchorsParts[1] : decodeURIComponent(anchorsParts[0]);
+
+                var slideAnchor = isFunkyAnchor ? anchorsParts[2] : anchorsParts[1];
+                if(slideAnchor && slideAnchor.length){
+                    slide = decodeURIComponent(slideAnchor);
+                }
+            }
+
+            return {
+                section: section,
+                slide: slide
+            };
+        }
+
+        //Sliding with arrow keys, both, vertical and horizontal
+        function keydownHandler(e) {
+            clearTimeout(keydownId);
+
+            var activeElement = document.activeElement;
+            var keyCode = e.keyCode;
+
+            //tab?
+            if(keyCode === 9){
+                onTab(e);
+            }
+
+            else if(!matches(activeElement, 'textarea') && !matches(activeElement, 'input') && !matches(activeElement, 'select') &&
+                activeElement.getAttribute('contentEditable') !== "true" && activeElement.getAttribute('contentEditable') !== '' &&
+                options.keyboardScrolling && options.autoScrolling){
+
+                //preventing the scroll with arrow keys & spacebar & Page Up & Down keys
+                var keyControls = [40, 38, 32, 33, 34];
+                if(keyControls.indexOf(keyCode) > -1){
+                    preventDefault(e);
+                }
+
+                controlPressed = e.ctrlKey;
+
+                keydownId = setTimeout(function(){
+                    onkeydown(e);
+                },150);
+            }
+        }
+
+        function tooltipTextHandler(){
+            /*jshint validthis:true */
+            trigger(prev(this), 'click');
+        }
+
+        //to prevent scrolling while zooming
+        function keyUpHandler(e){
+            if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox
+                controlPressed = e.ctrlKey;
+            }
+        }
+
+        //binding the mousemove when the mouse's middle button is released
+        function mouseDownHandler(e){
+            //middle button
+            if (e.which == 2){
+                oldPageY = e.pageY;
+                container.addEventListener('mousemove', mouseMoveHandler);
+            }
+        }
+
+        //unbinding the mousemove when the mouse's middle button is released
+        function mouseUpHandler(e){
+            //middle button
+            if (e.which == 2){
+                container.removeEventListener('mousemove', mouseMoveHandler);
+            }
+        }
+
+        /**
+        * Makes sure the tab key will only focus elements within the current section/slide
+        * preventing this way from breaking the page.
+        * Based on "Modals and keyboard traps"
+        * from https://developers.google.com/web/fundamentals/accessibility/focus/using-tabindex
+        */
+        function onTab(e){
+            var isShiftPressed = e.shiftKey;
+            var activeElement = document.activeElement;
+            var focusableElements = getFocusables(getSlideOrSection($(SECTION_ACTIVE_SEL)[0]));
+
+            function preventAndFocusFirst(e){
+                preventDefault(e);
+                return focusableElements[0] ? focusableElements[0].focus() : null;
+            }
+
+            //outside any section or slide? Let's not hijack the tab!
+            if(isFocusOutside(e)){
+                return;
+            }
+
+            //is there an element with focus?
+            if(activeElement){
+                if(closest(activeElement, SECTION_ACTIVE_SEL + ',' + SECTION_ACTIVE_SEL + ' ' + SLIDE_ACTIVE_SEL) == null){
+                    activeElement = preventAndFocusFirst(e);
+                }
+            }
+
+            //no element if focused? Let's focus the first one of the section/slide
+            else{
+                preventAndFocusFirst(e);
+            }
+
+            //when reached the first or last focusable element of the section/slide
+            //we prevent the tab action to keep it in the last focusable element
+            if(!isShiftPressed && activeElement == focusableElements[focusableElements.length - 1] ||
+                isShiftPressed && activeElement == focusableElements[0]
+            ){
+                preventDefault(e);
+            }
+        }
+
+        /**
+        * Gets all the focusable elements inside the passed element.
+        */
+        function getFocusables(el){
+            return [].slice.call($(focusableElementsString, el)).filter(function(item) {
+                    return item.getAttribute('tabindex') !== '-1'
+                    //are also not hidden elements (or with hidden parents)
+                    && item.offsetParent !== null;
+            });
+        }
+
+        /**
+        * Determines whether the focus is outside fullpage.js sections/slides or not.
+        */
+        function isFocusOutside(e){
+            var allFocusables = getFocusables(document);
+            var currentFocusIndex = allFocusables.indexOf(document.activeElement);
+            var focusDestinationIndex = e.shiftKey ? currentFocusIndex - 1 : currentFocusIndex + 1;
+            var focusDestination = allFocusables[focusDestinationIndex];
+            var destinationItemSlide = nullOrSlide(closest(focusDestination, SLIDE_SEL));
+            var destinationItemSection = nullOrSection(closest(focusDestination, SECTION_SEL));
+
+            return !destinationItemSlide && !destinationItemSection;
+        }
+
+        //Scrolling horizontally when clicking on the slider controls.
+        function slideArrowHandler(){
+            /*jshint validthis:true */
+            var section = closest(this, SECTION_SEL);
+
+            /*jshint validthis:true */
+            if (hasClass(this, SLIDES_PREV)) {
+                if(isScrollAllowed.m.left){
+                    moveSlideLeft(section);
+                }
+            } else {
+                if(isScrollAllowed.m.right){
+                    moveSlideRight(section);
+                }
+            }
+        }
+
+        //when opening a new tab (ctrl + t), `control` won't be pressed when coming back.
+        function blurHandler(){
+            isWindowFocused = false;
+            controlPressed = false;
+        }
+
+        //Scrolls to the section when clicking the navigation bullet
+        function sectionBulletHandler(e){
+            preventDefault(e);
+
+            /*jshint validthis:true */
+            var indexBullet = index(closest(this, SECTION_NAV_SEL + ' li'));
+            scrollPage($(SECTION_SEL)[indexBullet]);
+        }
+
+        //Scrolls the slider to the given slide destination for the given section
+        function slideBulletHandler(e){
+            preventDefault(e);
+
+            /*jshint validthis:true */
+            var slides = $(SLIDES_WRAPPER_SEL, closest(this, SECTION_SEL))[0];
+            var destiny = $(SLIDE_SEL, slides)[index(closest(this, 'li'))];
+
+            landscapeScroll(slides, destiny);
+        }
+
+        /**
+        * Keydown event
+        */
+        function onkeydown(e){
+            var shiftPressed = e.shiftKey;
+
+            //do nothing if we can not scroll or we are not using horizotnal key arrows.
+            if(!canScroll && [37,39].indexOf(e.keyCode) < 0){
+                return;
+            }
+
+            switch (e.keyCode) {
+                //up
+                case 38:
+                case 33:
+                    if(isScrollAllowed.k.up){
+                        moveSectionUp();
+                    }
+                    break;
+
+                //down
+                case 32: //spacebar
+                    if(shiftPressed && isScrollAllowed.k.up){
+                        moveSectionUp();
+                        break;
+                    }
+                /* falls through */
+                case 40:
+                case 34:
+                    if(isScrollAllowed.k.down){
+                        moveSectionDown();
+                    }
+                    break;
+
+                //Home
+                case 36:
+                    if(isScrollAllowed.k.up){
+                        moveTo(1);
+                    }
+                    break;
+
+                //End
+                case 35:
+                     if(isScrollAllowed.k.down){
+                        moveTo( $(SECTION_SEL).length );
+                    }
+                    break;
+
+                //left
+                case 37:
+                    if(isScrollAllowed.k.left){
+                        moveSlideLeft();
+                    }
+                    break;
+
+                //right
+                case 39:
+                    if(isScrollAllowed.k.right){
+                        moveSlideRight();
+                    }
+                    break;
+
+                default:
+                    return; // exit this handler for other keys
+            }
+        }
+
+        /**
+        * Detecting the direction of the mouse movement.
+        * Used only for the middle button of the mouse.
+        */
+        var oldPageY = 0;
+        function mouseMoveHandler(e){
+            if(canScroll){
+                // moving up
+                if (e.pageY < oldPageY && isScrollAllowed.m.up){
+                    moveSectionUp();
+                }
+
+                // moving down
+                else if(e.pageY > oldPageY && isScrollAllowed.m.down){
+                    moveSectionDown();
+                }
+            }
+            oldPageY = e.pageY;
+        }
+
+        /**
+        * Scrolls horizontal sliders.
+        */
+        function landscapeScroll(slides, destiny, direction){
+            var section = closest(slides, SECTION_SEL);
+            var v = {
+                slides: slides,
+                destiny: destiny,
+                direction: direction,
+                destinyPos: {left: destiny.offsetLeft},
+                slideIndex: index(destiny),
+                section: section,
+                sectionIndex: index(section, SECTION_SEL),
+                anchorLink: section.getAttribute('data-anchor'),
+                slidesNav: $(SLIDES_NAV_SEL, section)[0],
+                slideAnchor: getAnchor(destiny),
+                prevSlide: $(SLIDE_ACTIVE_SEL, section)[0],
+                prevSlideIndex: index($(SLIDE_ACTIVE_SEL, section)[0]),
+
+                //caching the value of isResizing at the momment the function is called
+                //because it will be checked later inside a setTimeout and the value might change
+                localIsResizing: isResizing
+            };
+            v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex);
+
+            //important!! Only do it when not resizing
+            if(!v.localIsResizing){
+                //preventing from scrolling to the next/prev section when using scrollHorizontally
+                canScroll = false;
+            }
+
+            if(options.onSlideLeave){
+
+                //if the site is not just resizing and readjusting the slides
+                if(!v.localIsResizing && v.xMovement!=='none'){
+                    if(isFunction( options.onSlideLeave )){
+                        if( fireCallback('onSlideLeave', v) === false){
+                            slideMoving = false;
+                            return;
+                        }
+                    }
+                }
+            }
+
+            addClass(destiny, ACTIVE);
+            removeClass(siblings(destiny), ACTIVE);
+
+            if(!v.localIsResizing){
+                stopMedia(v.prevSlide);
+                lazyLoad(destiny);
+            }
+
+            if(!options.loopHorizontal && options.controlArrows){
+                //hidding it for the fist slide, showing for the rest
+                toggle($(SLIDES_ARROW_PREV_SEL, section), v.slideIndex!==0);
+
+                //hidding it for the last slide, showing for the rest
+                toggle($(SLIDES_ARROW_NEXT_SEL, section), next(destiny) != null);
+            }
+
+            //only changing the URL if the slides are in the current section (not for resize re-adjusting)
+            if(hasClass(section, ACTIVE) && !v.localIsResizing){
+                setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex);
+            }
+
+            performHorizontalMove(slides, v, true);
+        }
+
+
+        function afterSlideLoads(v){
+            activeSlidesNavigation(v.slidesNav, v.slideIndex);
+
+            //if the site is not just resizing and readjusting the slides
+            if(!v.localIsResizing){
+                if(isFunction( options.afterSlideLoad )){
+                    fireCallback('afterSlideLoad', v);
+                }
+
+                //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally
+                //and to prevent double scroll right after a windows resize
+                canScroll = true;
+
+                playMedia(v.destiny);
+            }
+
+            //letting them slide again
+            slideMoving = false;
+        }
+
+        /**
+        * Performs the horizontal movement. (CSS3 or jQuery)
+        *
+        * @param fireCallback {Bool} - determines whether or not to fire the callback
+        */
+        function performHorizontalMove(slides, v, fireCallback){
+            var destinyPos = v.destinyPos;
+
+            if(options.css3){
+                var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)';
+
+                FP.test.translate3dH[v.sectionIndex] = translate3d;
+                css(addAnimation($(SLIDES_CONTAINER_SEL, slides)), getTransforms(translate3d));
+
+                afterSlideLoadsId = setTimeout(function(){
+                    if(fireCallback){
+                        afterSlideLoads(v);
+                    }
+                }, options.scrollingSpeed);
+            }else{
+                FP.test.left[v.sectionIndex] = Math.round(destinyPos.left);
+
+                scrollTo(slides, Math.round(destinyPos.left), options.scrollingSpeed, function(){
+                    if(fireCallback){
+                        afterSlideLoads(v);
+                    }
+                });
+            }
+        }
+
+        /**
+        * Sets the state for the horizontal bullet navigations.
+        */
+        function activeSlidesNavigation(slidesNav, slideIndex){
+            if(options.slidesNavigation && slidesNav != null){
+                removeClass($(ACTIVE_SEL, slidesNav), ACTIVE);
+                addClass( $('a', $('li', slidesNav)[slideIndex] ), ACTIVE);
+            }
+        }
+
+        var previousHeight = windowsHeight;
+
+        //when resizing the site, we adjust the heights of the sections, slimScroll...
+        function resizeHandler(){
+            //checking if it needs to get responsive
+            responsive();
+
+            // rebuild immediately on touch devices
+            if (isTouchDevice) {
+                var activeElement = document.activeElement;
+
+                //if the keyboard is NOT visible
+                if (!matches(activeElement, 'textarea') && !matches(activeElement, 'input') && !matches(activeElement, 'select')) {
+                    var currentHeight = getWindowHeight();
+
+                    //making sure the change in the viewport size is enough to force a rebuild. (20 % of the window to avoid problems when hidding scroll bars)
+                    if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){
+                        reBuild(true);
+                        previousHeight = currentHeight;
+                    }
+                }
+            }else{
+                //in order to call the functions only when the resize is finished
+                //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing
+                clearTimeout(resizeId);
+
+                resizeId = setTimeout(function(){
+                    reBuild(true);
+                }, 350);
+            }
+        }
+
+        /**
+        * Checks if the site needs to get responsive and disables autoScrolling if so.
+        * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS.
+        */
+        function responsive(){
+            var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity
+            var heightLimit = options.responsiveHeight;
+
+            //only calculating what we need. Remember its called on the resize event.
+            var isBreakingPointWidth = widthLimit && window.innerWidth < widthLimit;
+            var isBreakingPointHeight = heightLimit && window.innerHeight < heightLimit;
+
+            if(widthLimit && heightLimit){
+                setResponsive(isBreakingPointWidth || isBreakingPointHeight);
+            }
+            else if(widthLimit){
+                setResponsive(isBreakingPointWidth);
+            }
+            else if(heightLimit){
+                setResponsive(isBreakingPointHeight);
+            }
+        }
+
+        /**
+        * Adds transition animations for the given element
+        */
+        function addAnimation(element){
+            var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3;
+
+            removeClass(element, NO_TRANSITION);
+            return css(element, {
+                '-webkit-transition': transition,
+                'transition': transition
+            });
+        }
+
+        /**
+        * Remove transition animations for the given element
+        */
+        function removeAnimation(element){
+            return addClass(element, NO_TRANSITION);
+        }
+
+        /**
+        * Activating the vertical navigation bullets according to the given slide name.
+        */
+        function activateNavDots(name, sectionIndex){
+            if(options.navigation && $(SECTION_NAV_SEL)[0] != null){
+                    removeClass($(ACTIVE_SEL, $(SECTION_NAV_SEL)[0]), ACTIVE);
+                if(name){
+                    addClass( $('a[href="#' + name + '"]', $(SECTION_NAV_SEL)[0]), ACTIVE);
+                }else{
+                    addClass($('a', $('li', $(SECTION_NAV_SEL)[0])[sectionIndex]), ACTIVE);
+                }
+            }
+        }
+
+        /**
+        * Activating the website main menu elements according to the given slide name.
+        */
+        function activateMenuElement(name){
+            var menu = $(options.menu)[0];
+            if(options.menu && menu != null){
+                removeClass($(ACTIVE_SEL, menu), ACTIVE);
+                addClass($('[data-menuanchor="'+name+'"]', menu), ACTIVE);
+            }
+        }
+
+        /**
+        * Sets to active the current menu and vertical nav items.
+        */
+        function activateMenuAndNav(anchor, index){
+            activateMenuElement(anchor);
+            activateNavDots(anchor, index);
+        }
+
+        /**
+        * Retuns `up` or `down` depending on the scrolling movement to reach its destination
+        * from the current section.
+        */
+        function getYmovement(destiny){
+            var fromIndex = index($(SECTION_ACTIVE_SEL)[0], SECTION_SEL);
+            var toIndex = index(destiny, SECTION_SEL);
+            if( fromIndex == toIndex){
+                return 'none';
+            }
+            if(fromIndex > toIndex){
+                return 'up';
+            }
+            return 'down';
+        }
+
+        /**
+        * Retuns `right` or `left` depending on the scrolling movement to reach its destination
+        * from the current slide.
+        */
+        function getXmovement(fromIndex, toIndex){
+            if( fromIndex == toIndex){
+                return 'none';
+            }
+            if(fromIndex > toIndex){
+                return 'left';
+            }
+            return 'right';
+        }
+
+        function addTableClass(element){
+            //In case we are styling for the 2nd time as in with reponsiveSlides
+            if(!hasClass(element, TABLE)){
+                var wrapper = document.createElement('div');
+                wrapper.className = TABLE_CELL;
+                wrapper.style.height = getTableHeight(element) + 'px';
+
+                addClass(element, TABLE);
+                wrapInner(element, wrapper);
+            }
+        }
+
+        function getTableHeight(element){
+            var sectionHeight = windowsHeight;
+
+            if(options.paddingTop || options.paddingBottom){
+                var section = element;
+                if(!hasClass(section, SECTION)){
+                    section = closest(element, SECTION_SEL);
+                }
+
+                var paddings = parseInt(getComputedStyle(section)['padding-top']) + parseInt(getComputedStyle(section)['padding-bottom']);
+                sectionHeight = (windowsHeight - paddings);
+            }
+
+            return sectionHeight;
+        }
+
+        /**
+        * Adds a css3 transform property to the container class with or without animation depending on the animated param.
+        */
+        function transformContainer(translate3d, animated){
+            if(animated){
+                addAnimation(container);
+            }else{
+                removeAnimation(container);
+            }
+
+            css(container, getTransforms(translate3d));
+            FP.test.translate3d = translate3d;
+
+            //syncronously removing the class after the animation has been applied.
+            setTimeout(function(){
+                removeClass(container, NO_TRANSITION);
+            },10);
+        }
+
+        /**
+        * Gets a section by its anchor / index
+        */
+        function getSectionByAnchor(sectionAnchor){
+            var section = $(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]', container)[0];
+            if(!section){
+                var sectionIndex = typeof sectionAnchor !== 'undefined' ? sectionAnchor -1 : 0;
+                section = $(SECTION_SEL)[sectionIndex];
+            }
+
+            return section;
+        }
+
+        /**
+        * Gets a slide inside a given section by its anchor / index
+        */
+        function getSlideByAnchor(slideAnchor, section){
+            var slide = $(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]', section)[0];
+            if(slide == null){
+                slideAnchor = typeof slideAnchor !== 'undefined' ? slideAnchor : 0;
+                slide = $(SLIDE_SEL, section)[slideAnchor];
+            }
+
+            return slide;
+        }
+
+        /**
+        * Scrolls to the given section and slide anchors
+        */
+        function scrollPageAndSlide(sectionAnchor, slideAnchor){
+            var section = getSectionByAnchor(sectionAnchor);
+
+            //do nothing if there's no section with the given anchor name
+            if(section == null) return;
+
+            var slide = getSlideByAnchor(slideAnchor, section);
+
+            //we need to scroll to the section and then to the slide
+            if (getAnchor(section) !== lastScrolledDestiny && !hasClass(section, ACTIVE)){
+                scrollPage(section, function(){
+                    scrollSlider(slide);
+                });
+            }
+            //if we were already in the section
+            else{
+                scrollSlider(slide);
+            }
+        }
+
+        /**
+        * Scrolls the slider to the given slide destination for the given section
+        */
+        function scrollSlider(slide){
+            if(slide != null){
+                landscapeScroll(closest(slide, SLIDES_WRAPPER_SEL), slide);
+            }
+        }
+
+        /**
+        * Creates a landscape navigation bar with dots for horizontal sliders.
+        */
+        function addSlidesNavigation(section, numSlides){
+            appendTo(createElementFromHTML('<div class="' + SLIDES_NAV + '"><ul></ul></div>'), section);
+            var nav = $(SLIDES_NAV_SEL, section)[0];
+
+            //top or bottom
+            addClass(nav, 'fp-' + options.slidesNavPosition);
+
+            for(var i=0; i< numSlides; i++){
+                appendTo(createElementFromHTML('<li><a href="#"><span class="fp-sr-only">'+ getBulletLinkName(i, 'Slide') +'</span><span></span></a></li>'), $('ul', nav)[0] );
+            }
+
+            //centering it
+            css(nav, {'margin-left': '-' + (nav.innerWidth/2) + 'px'});
+
+            addClass($('a', $('li', nav)[0] ), ACTIVE);
+        }
+
+
+        /**
+        * Sets the state of the website depending on the active section/slide.
+        * It changes the URL hash when needed and updates the body class.
+        */
+        function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){
+            var sectionHash = '';
+
+            if(options.anchors.length && !options.lockAnchors){
+
+                //isn't it the first slide?
+                if(slideIndex){
+                    if(anchorLink != null){
+                        sectionHash = anchorLink;
+                    }
+
+                    //slide without anchor link? We take the index instead.
+                    if(slideAnchor == null){
+                        slideAnchor = slideIndex;
+                    }
+
+                    lastScrolledSlide = slideAnchor;
+                    setUrlHash(sectionHash + '/' + slideAnchor);
+
+                //first slide won't have slide anchor, just the section one
+                }else if(slideIndex != null){
+                    lastScrolledSlide = slideAnchor;
+                    setUrlHash(anchorLink);
+                }
+
+                //section without slides
+                else{
+                    setUrlHash(anchorLink);
+                }
+            }
+
+            setBodyClass();
+        }
+
+        /**
+        * Sets the URL hash.
+        */
+        function setUrlHash(url){
+            if(options.recordHistory){
+                location.hash = url;
+            }else{
+                //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :)
+                if(isTouchDevice || isTouch){
+                    window.history.replaceState(undefined, undefined, '#' + url);
+                }else{
+                    var baseUrl = window.location.href.split('#')[0];
+                    window.location.replace( baseUrl + '#' + url );
+                }
+            }
+        }
+
+        /**
+        * Gets the anchor for the given slide / section. Its index will be used if there's none.
+        */
+        function getAnchor(element){
+            if(!element){
+                return null;
+            }
+            var anchor = element.getAttribute('data-anchor');
+            var elementIndex = index(element);
+
+            //Slide without anchor link? We take the index instead.
+            if(anchor == null){
+                anchor = elementIndex;
+            }
+
+            return anchor;
+        }
+
+        /**
+        * Sets a class for the body of the page depending on the active section / slide
+        */
+        function setBodyClass(){
+            var section = $(SECTION_ACTIVE_SEL)[0];
+            var slide = $(SLIDE_ACTIVE_SEL, section)[0];
+
+            var sectionAnchor = getAnchor(section);
+            var slideAnchor = getAnchor(slide);
+
+            var text = String(sectionAnchor);
+
+            if(slide){
+                text = text + '-' + slideAnchor;
+            }
+
+            //changing slash for dash to make it a valid CSS style
+            text = text.replace('/', '-').replace('#','');
+
+            //removing previous anchor classes
+            var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g");
+            $body.className = $body.className.replace(classRe, '');
+
+            //adding the current anchor
+            addClass($body, VIEWING_PREFIX + '-' + text);
+        }
+
+        /**
+        * Checks for translate3d support
+        * @return boolean
+        * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support
+        */
+        function support3d() {
+            var el = document.createElement('p'),
+                has3d,
+                transforms = {
+                    'webkitTransform':'-webkit-transform',
+                    'OTransform':'-o-transform',
+                    'msTransform':'-ms-transform',
+                    'MozTransform':'-moz-transform',
+                    'transform':'transform'
+                };
+
+            //preventing the style p:empty{display: none;} from returning the wrong result
+            el.style.display = 'block'
+
+            // Add it to the body to get the computed style.
+            document.body.insertBefore(el, null);
+
+            for (var t in transforms) {
+                if (el.style[t] !== undefined) {
+                    el.style[t] = 'translate3d(1px,1px,1px)';
+                    has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
+                }
+            }
+
+            document.body.removeChild(el);
+
+            return (has3d !== undefined && has3d.length > 0 && has3d !== 'none');
+        }
+
+        /**
+        * Removes the auto scrolling action fired by the mouse wheel and trackpad.
+        * After this function is called, the mousewheel and trackpad movements won't scroll through sections.
+        */
+        function removeMouseWheelHandler(){
+            if (document.addEventListener) {
+                document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper
+                document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox
+                document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox
+            } else {
+                document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8
+            }
+        }
+
+        /**
+        * Adds the auto scrolling action for the mouse wheel and trackpad.
+        * After this function is called, the mousewheel and trackpad movements will scroll through sections
+        * https://developer.mozilla.org/en-US/docs/Web/Events/wheel
+        */
+        function addMouseWheelHandler(){
+            var prefix = '';
+            var _addEventListener;
+
+            if (window.addEventListener){
+                _addEventListener = "addEventListener";
+            }else{
+                _addEventListener = "attachEvent";
+                prefix = 'on';
+            }
+
+             // detect available wheel event
+            var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel"
+                      document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel"
+                      'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox
+
+
+            if(support == 'DOMMouseScroll'){
+                document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, false);
+            }
+
+            //handle MozMousePixelScroll in older Firefox
+            else{
+                document[ _addEventListener ](prefix + support, MouseWheelHandler, false);
+            }
+        }
+
+        /**
+        * Binding the mousemove when the mouse's middle button is pressed
+        */
+        function addMiddleWheelHandler(){
+            container.addEventListener('mousedown', mouseDownHandler);
+            container.addEventListener('mouseup', mouseUpHandler);
+        }
+
+        /**
+        * Unbinding the mousemove when the mouse's middle button is released
+        */
+        function removeMiddleWheelHandler(){
+            container.removeEventListener('mousedown', mouseDownHandler);
+            container.removeEventListener('mouseup', mouseUpHandler);
+        }
+
+        /**
+        * Adds the possibility to auto scroll through sections on touch devices.
+        */
+        function addTouchHandler(){
+            if(isTouchDevice || isTouch){
+                if(options.autoScrolling){
+                    $body.removeEventListener(events.touchmove, preventBouncing, {passive: false});
+                    $body.addEventListener(events.touchmove, preventBouncing, {passive: false});
+                }
+
+                $(WRAPPER_SEL)[0].removeEventListener(events.touchstart, touchStartHandler);
+                $(WRAPPER_SEL)[0].removeEventListener(events.touchmove, touchMoveHandler, {passive: false});
+
+                $(WRAPPER_SEL)[0].addEventListener(events.touchstart, touchStartHandler);
+                $(WRAPPER_SEL)[0].addEventListener(events.touchmove, touchMoveHandler, {passive: false});
+            }
+        }
+
+        /**
+        * Removes the auto scrolling for touch devices.
+        */
+        function removeTouchHandler(){
+            if(isTouchDevice || isTouch){
+                // normalScrollElements requires it off #2691
+                if(options.autoScrolling){
+                    $body.removeEventListener(events.touchmove, touchMoveHandler, {passive: false});
+                    $body.removeEventListener(events.touchmove, preventBouncing, {passive: false});
+                }
+
+                $(WRAPPER_SEL)[0].removeEventListener(events.touchstart, touchStartHandler);
+                $(WRAPPER_SEL)[0].removeEventListener(events.touchmove, touchMoveHandler, {passive: false});
+            }
+        }
+
+        /*
+        * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11)
+        * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx
+        */
+        function getMSPointer(){
+            var pointer;
+
+            //IE >= 11 & rest of browsers
+            if(window.PointerEvent){
+                pointer = { down: 'pointerdown', move: 'pointermove'};
+            }
+
+            //IE < 11
+            else{
+                pointer = { down: 'MSPointerDown', move: 'MSPointerMove'};
+            }
+
+            return pointer;
+        }
+
+        /**
+        * Gets the pageX and pageY properties depending on the browser.
+        * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854
+        */
+        function getEventsPage(e){
+            var events = [];
+
+            events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY);
+            events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX);
+
+            //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008
+            if(isTouch && isReallyTouch(e) && options.scrollBar && typeof e.touches !== 'undefined'){
+                events.y = e.touches[0].pageY;
+                events.x = e.touches[0].pageX;
+            }
+
+            return events;
+        }
+
+        /**
+        * Slides silently (with no animation) the active slider to the given slide.
+        * @param noCallback {bool} true or defined -> no callbacks
+        */
+        function silentLandscapeScroll(activeSlide, noCallbacks){
+            setScrollingSpeed(0, 'internal');
+
+            if(typeof noCallbacks !== 'undefined'){
+                //preventing firing callbacks afterSlideLoad etc.
+                isResizing = true;
+            }
+
+            landscapeScroll(closest(activeSlide, SLIDES_WRAPPER_SEL), activeSlide);
+
+            if(typeof noCallbacks !== 'undefined'){
+                isResizing = false;
+            }
+
+            setScrollingSpeed(originals.scrollingSpeed, 'internal');
+        }
+
+        /**
+        * Scrolls silently (with no animation) the page to the given Y position.
+        */
+        function silentScroll(top){
+            // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625
+            // that's why we round it to 0.
+            var roundedTop = Math.round(top);
+
+            if (options.css3 && options.autoScrolling && !options.scrollBar){
+                var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)';
+                transformContainer(translate3d, false);
+            }
+            else if(options.autoScrolling && !options.scrollBar){
+                css(container, {'top': -roundedTop + 'px'});
+                FP.test.top = -roundedTop + 'px';
+            }
+            else{
+                var scrollSettings = getScrollSettings(roundedTop);
+                setScrolling(scrollSettings.element, scrollSettings.options);
+            }
+        }
+
+        /**
+        * Returns the cross-browser transform string.
+        */
+        function getTransforms(translate3d){
+            return {
+                '-webkit-transform': translate3d,
+                '-moz-transform': translate3d,
+                '-ms-transform':translate3d,
+                'transform': translate3d
+            };
+        }
+
+        /**
+        * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard)
+        * @type  m (mouse) or k (keyboard)
+        */
+        function setIsScrollAllowed(value, direction, type){
+            //up, down, left, right
+            if(direction !== 'all'){
+                isScrollAllowed[type][direction] = value;
+            }
+
+            //all directions?
+            else{
+                Object.keys(isScrollAllowed[type]).forEach(function(key){
+                    isScrollAllowed[type][key] = value;
+                });
+            }
+        }
+
+        /*
+        * Destroys fullpage.js plugin events and optinally its html markup and styles
+        */
+        function destroy(all){
+            setAutoScrolling(false, 'internal');
+            setAllowScrolling(true);
+            setMouseHijack(false);
+            setKeyboardScrolling(false);
+            addClass(container, DESTROYED);
+
+            clearTimeout(afterSlideLoadsId);
+            clearTimeout(afterSectionLoadsId);
+            clearTimeout(resizeId);
+            clearTimeout(scrollId);
+            clearTimeout(scrollId2);
+
+
+            window.removeEventListener('scroll', scrollHandler);
+            window.removeEventListener('hashchange', hashChangeHandler);
+            window.removeEventListener('resize', resizeHandler);
+
+            document.removeEventListener('keydown', keydownHandler);
+            document.removeEventListener('keyup', keyUpHandler);
+
+            ['click', 'touchstart'].forEach(function(eventName){
+                document.removeEventListener(eventName, delegatedEvents);
+            });
+
+            ['mouseenter', 'touchstart', 'mouseleave', 'touchend'].forEach(function(eventName){
+                document.removeEventListener(eventName, onMouseEnterOrLeave, true); //true is required!
+            });
+
+            clearTimeout(afterSlideLoadsId);
+            clearTimeout(afterSectionLoadsId);
+
+            //lets make a mess!
+            if(all){
+                destroyStructure();
+            }
+        }
+
+        /*
+        * Removes inline styles added by fullpage.js
+        */
+        function destroyStructure(){
+            //reseting the `top` or `translate` properties to 0
+            silentScroll(0);
+
+            //loading all the lazy load content
+            $('img[data-src], source[data-src], audio[data-src], iframe[data-src]', container).forEach(function(item){
+                setSrc(item, 'src');
+            });
+
+            $('img[data-srcset]').forEach(function(item){
+                setSrc(item, 'srcset');
+            });
+
+            remove($(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL +  ', ' + SLIDES_ARROW_SEL));
+
+            //removing inline styles
+            css($(SECTION_SEL), {
+                'height': '',
+                'background-color' : '',
+                'padding': ''
+            });
+
+            css($(SLIDE_SEL), {
+                'width': ''
+            });
+
+            css(container, {
+                'height': '',
+                'position': '',
+                '-ms-touch-action': '',
+                'touch-action': ''
+            });
+
+            css($htmlBody, {
+                'overflow': '',
+                'height': ''
+            });
+
+            // remove .fp-enabled class
+            removeClass($('html'), ENABLED);
+
+            // remove .fp-responsive class
+            removeClass($body, RESPONSIVE);
+
+            // remove all of the .fp-viewing- classes
+            $body.className.split(/\s+/).forEach(function (className) {
+                if (className.indexOf(VIEWING_PREFIX) === 0) {
+                    removeClass($body, className);
+                }
+            });
+
+            //removing added classes
+            $(SECTION_SEL + ', ' + SLIDE_SEL).forEach(function(item){
+                if(options.scrollOverflowHandler){
+                    options.scrollOverflowHandler.remove(item);
+                }
+                removeClass(item, TABLE + ' ' + ACTIVE + ' ' + COMPLETELY);
+                var previousStyles = item.getAttribute('data-fp-styles');
+                if(previousStyles){
+                    item.setAttribute('style', item.getAttribute('data-fp-styles'));
+                }
+            });
+
+            //removing the applied transition from the fullpage wrapper
+            removeAnimation(container);
+
+            //Unwrapping content
+            [TABLE_CELL_SEL, SLIDES_CONTAINER_SEL,SLIDES_WRAPPER_SEL].forEach(function(selector){
+                $(selector, container).forEach(function(item){
+                    //unwrap not being use in case there's no child element inside and its just text
+                    item.outerHTML = item.innerHTML;
+                });
+            });
+
+            //removing the applied transition from the fullpage wrapper
+            css(container, {
+                '-webkit-transition': 'none',
+                'transition': 'none'
+            });
+
+            //scrolling the page to the top with no animation
+            window.scrollTo(0, 0);
+
+            //removing selectors
+            var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER];
+            usedSelectors.forEach(function(item){
+                removeClass($('.' + item), item);
+            });
+        }
+
+        /*
+        * Sets the state for a variable with multiple states (original, and temporal)
+        * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`.
+        * This function is used to keep track of both states, the original and the temporal one.
+        * If type is not 'internal', then we assume the user is globally changing the variable.
+        */
+        function setVariableState(variable, value, type){
+            options[variable] = value;
+            if(type !== 'internal'){
+                originals[variable] = value;
+            }
+        }
+
+        /**
+        * Displays warnings
+        */
+        function displayWarnings(){
+            if(!isLicenseValid){
+                showError('error', 'Fullpage.js version 3 has changed its license to GPLv3 and it requires a `licenseKey` option. Read about it here:');
+                showError('error', 'https://github.com/alvarotrigo/fullPage.js#options.');
+            }
+
+            var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax'];
+            if(hasClass($('html'), ENABLED)){
+                showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!');
+                return;
+            }
+
+            // Disable mutually exclusive settings
+            if (options.continuousVertical &&
+                (options.loopTop || options.loopBottom)) {
+                options.continuousVertical = false;
+                showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled');
+            }
+
+            if(options.scrollOverflow &&
+               (options.scrollBar || !options.autoScrolling)){
+                showError('warn', 'Options scrollBar:true and autoScrolling:false are mutually exclusive with scrollOverflow:true. Sections with scrollOverflow might not work well in Firefox');
+            }
+
+            if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){
+                options.continuousVertical = false;
+                showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled');
+            }
+
+            if(options.scrollOverflow && options.scrollOverflowHandler == null){
+                options.scrollOverflow = false;
+                showError('error', 'The option `scrollOverflow:true` requires the file `scrolloverflow.min.js`. Please include it before fullPage.js.');
+            }
+
+            //using extensions? Wrong file!
+            extensions.forEach(function(extension){
+                //is the option set to true?
+                if(options[extension]){
+                    showError('warn', 'fullpage.js extensions require fullpage.extensions.min.js file instead of the usual fullpage.js. Requested: '+ extension);
+                }
+            });
+
+            //anchors can not have the same value as any element ID or NAME
+            options.anchors.forEach(function(name){
+
+                //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396)
+                var nameAttr =  [].slice.call($('[name]')).filter(function(item) {
+                    return item.getAttribute('name') && item.getAttribute('name').toLowerCase() == name.toLowerCase();
+                });
+
+                var idAttr =  [].slice.call($('[id]')).filter(function(item) {
+                    return item.getAttribute('id') && item.getAttribute('id').toLowerCase() == name.toLowerCase();
+                });
+
+                if(idAttr.length || nameAttr.length ){
+                    showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).');
+                    if(idAttr.length){
+                        showError('error', '"' + name + '" is is being used by another element `id` property');
+                    }
+                    if(nameAttr.length){
+                        showError('error', '"' + name + '" is is being used by another element `name` property');
+                    }
+                }
+            });
+        }
+
+        /**
+        * Getting the position of the element to scroll when using jQuery animations
+        */
+        function getScrolledPosition(element){
+            var position;
+
+            //is not the window element and is a slide?
+            if(element.self != window && hasClass(element, SLIDES_WRAPPER)){
+                position = element.scrollLeft;
+            }
+            else if(!options.autoScrolling  || options.scrollBar){
+                position = getScrollTop();
+            }
+            else{
+                position = element.offsetTop;
+            }
+
+            //gets the top property of the wrapper
+            return position;
+        }
+
+        /**
+        * Simulates the animated scrollTop of jQuery. Used when css3:false or scrollBar:true or autoScrolling:false
+        * http://stackoverflow.com/a/16136789/1081396
+        */
+        function scrollTo(element, to, duration, callback) {
+            var start = getScrolledPosition(element);
+            var change = to - start;
+            var currentTime = 0;
+            var increment = 20;
+            activeAnimation = true;
+
+            var animateScroll = function(){
+                if(activeAnimation){ //in order to stope it from other function whenever we want
+                    var val = to;
+
+                    currentTime += increment;
+
+                    if(duration){
+                        val = window.fp_easings[options.easing](currentTime, start, change, duration);
+                    }
+
+                    setScrolling(element, val);
+
+                    if(currentTime < duration) {
+                        setTimeout(animateScroll, increment);
+                    }else if(typeof callback !== 'undefined'){
+                        callback();
+                    }
+                }else if (currentTime < duration){
+                    callback();
+                }
+            };
+
+            animateScroll();
+        }
+
+        /**
+        * Scrolls the page / slider the given number of pixels.
+        * It will do it one or another way dependiong on the library's config.
+        */
+        function setScrolling(element, val){
+            if(!options.autoScrolling || options.scrollBar || (element.self != window && hasClass(element, SLIDES_WRAPPER))){
+
+                //scrolling horizontally through the slides?
+                if(element.self != window  && hasClass(element, SLIDES_WRAPPER)){
+                    element.scrollLeft = val;
+                }
+                //vertical scroll
+                else{
+                    element.scrollTo(0, val);
+                }
+            }else{
+                 element.style.top = val + 'px';
+            }
+        }
+
+        /**
+        * Gets the active slide.
+        */
+        function getActiveSlide(){
+            var activeSlide = $(SLIDE_ACTIVE_SEL, $(SECTION_ACTIVE_SEL)[0])[0];
+            return nullOrSlide(activeSlide);
+        }
+
+        /**
+        * Gets the active section.
+        */
+        function getActiveSection(){
+            return new Section($(SECTION_ACTIVE_SEL)[0]);
+        }
+
+        /**
+        * Item. Slide or Section objects share the same properties.
+        */
+        function Item(el, selector){
+            this.anchor = el.getAttribute('data-anchor');
+            this.item = el;
+            this.index = index(el, selector);
+            this.isLast = this.index === $(selector).length -1;
+            this.isFirst = !this.index;
+        }
+
+        /**
+        * Section object
+        */
+        function Section(el){
+            Item.call(this, el, SECTION_SEL);
+        }
+
+        /**
+        * Slide object
+        */
+        function Slide(el){
+            Item.call(this, el, SLIDE_SEL);
+        }
+
+        return FP;
+    } //end of $.fn.fullpage
+
+
+    //utils
+    /**
+    * Shows a message in the console of the given type.
+    */
+    function showError(type, text){
+        window.console && window.console[type] && window.console[type]('fullPage: ' + text);
+    }
+
+    /**
+    * Equivalent or jQuery function $().
+    */
+    function $(selector, context){
+        context = arguments.length > 1 ? context : document;
+        return context ? context.querySelectorAll(selector) : null;
+    }
+
+    /**
+    * Extends a given Object properties and its childs.
+    */
+    function deepExtend(out) {
+      out = out || {};
+
+      for (var i = 1; i < arguments.length; i++) {
+        var obj = arguments[i];
+
+        if (!obj)
+          continue;
+
+        for (var key in obj) {
+          if (obj.hasOwnProperty(key)) {
+            if (typeof obj[key] === 'object' && obj[key] != null)
+              out[key] = deepExtend(out[key], obj[key]);
+            else
+              out[key] = obj[key];
+          }
+        }
+      }
+
+      return out;
+    }
+
+    /**
+    * Checks if the passed element contains the passed class.
+    */
+    function hasClass(el, className){
+        if(el == null){
+            return false;
+        }
+        if (el.classList){
+            return el.classList.contains(className);
+        }
+        return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
+    }
+
+    /**
+    * Gets the window height. Crossbrowser.
+    */
+    function getWindowHeight(){
+        return  'innerHeight' in window ? window.innerHeight : document.documentElement.offsetHeight;
+    }
+
+    /**
+    * Set's the CSS properties for the passed item/s.
+    * @param {NodeList|HTMLElement} items
+    * @param {Object} props css properties and values.
+    */
+    function css(items, props) {
+        items = getList(items);
+
+        var key;
+        for (key in props) {
+            if (props.hasOwnProperty(key)) {
+                if (key !== null) {
+                    for (var i = 0; i < items.length; i++) {
+                        var item = items[i];
+                        item.style[key] = props[key];
+                    }
+                }
+            }
+        }
+
+        return items;
+    }
+
+    /**
+    * Generic function to get the previous or next element.
+    */
+    function until(item, selector, fn){
+        var sibling = item[fn];
+        while(sibling && !matches(sibling, selector)){
+            sibling = sibling[fn];
+        }
+
+        return sibling;
+    }
+
+    /**
+    * Gets the previous element to the passed element that matches the passed selector.
+    */
+    function prevUntil(item, selector){
+        return until(item, selector, 'previousElementSibling');
+    }
+
+    /**
+    * Gets the next element to the passed element that matches the passed selector.
+    */
+    function nextUntil(item, selector){
+        return until(item, selector, 'nextElementSibling');
+    }
+
+    /**
+    * Gets the previous element to the passed element.
+    */
+    function prev(item){
+        return item.previousElementSibling;
+    }
+
+    /**
+    * Gets the next element to the passed element.
+    */
+    function next(item){
+        return item.nextElementSibling;
+    }
+
+    /**
+    * Gets the last element from the passed list of elements.
+    */
+    function last(item){
+        return item[item.length-1];
+    }
+
+    /**
+    * Gets index from the passed element.
+    * @param {String} selector is optional.
+    */
+    function index(item, selector) {
+        item = isArrayOrList(item) ? item[0] : item;
+        var children = selector != null? $(selector, item.parentNode) : item.parentNode.childNodes;
+        var num = 0;
+        for (var i=0; i<children.length; i++) {
+             if (children[i] == item) return num;
+             if (children[i].nodeType==1) num++;
+        }
+        return -1;
+    }
+
+    /**
+    * Gets an iterable element for the passed element/s
+    */
+    function getList(item){
+        return !isArrayOrList(item) ? [item] : item;
+    }
+
+    /**
+    * Adds the display=none property for the passed element/s
+    */
+    function hide(el){
+        el = getList(el);
+
+        for(var i = 0; i<el.length; i++){
+            el[i].style.display = 'none';
+        }
+        return el;
+    }
+
+    /**
+    * Adds the display=block property for the passed element/s
+    */
+    function show(el){
+        el = getList(el);
+
+        for(var i = 0; i<el.length; i++){
+            el[i].style.display = 'block';
+        }
+        return el;
+    }
+
+    /**
+    * Checks if the passed element is an iterable element or not
+    */
+    function isArrayOrList(el){
+        return Object.prototype.toString.call( el ) === '[object Array]' ||
+            Object.prototype.toString.call( el ) === '[object NodeList]';
+    }
+
+    /**
+    * Adds the passed class to the passed element/s
+    */
+    function addClass(el, className) {
+        el = getList(el);
+
+        for(var i = 0; i<el.length; i++){
+            var item = el[i];
+            if (item.classList){
+                item.classList.add(className);
+            }
+            else{
+              item.className += ' ' + className;
+            }
+        }
+        return el;
+    }
+
+    /**
+    * Removes the passed class to the passed element/s
+    * @param {String} `className` can be multiple classnames separated by whitespace
+    */
+    function removeClass(el, className){
+        el = getList(el);
+
+        var classNames = className.split(' ');
+
+        for(var a = 0; a<classNames.length; a++){
+            className = classNames[a];
+            for(var i = 0; i<el.length; i++){
+                var item = el[i];
+                if (item.classList){
+                    item.classList.remove(className);
+                }
+                else{
+                    item.className = item.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
+                }
+            }
+        }
+        return el;
+    }
+
+    /**
+    * Appends the given element ot the given parent.
+    */
+    function appendTo(el, parent){
+        parent.appendChild(el);
+    }
+
+    /**
+    Usage:
+
+    var wrapper = document.createElement('div');
+    wrapper.className = 'fp-slides';
+    wrap($('.slide'), wrapper);
+
+    https://jsfiddle.net/qwzc7oy3/15/ (vanilla)
+    https://jsfiddle.net/oya6ndka/1/ (jquery equivalent)
+    */
+    function wrap(toWrap, wrapper, isWrapAll) {
+        var newParent;
+        wrapper = wrapper || document.createElement('div');
+        for(var i = 0; i < toWrap.length; i++){
+            var item = toWrap[i];
+            if(isWrapAll && !i || !isWrapAll){
+                newParent = wrapper.cloneNode(true);
+                item.parentNode.insertBefore(newParent, item);
+            }
+            newParent.appendChild(item);
+        }
+        return toWrap;
+    }
+
+    /**
+    Usage:
+    var wrapper = document.createElement('div');
+    wrapper.className = 'fp-slides';
+    wrap($('.slide'), wrapper);
+
+    https://jsfiddle.net/qwzc7oy3/27/ (vanilla)
+    https://jsfiddle.net/oya6ndka/4/ (jquery equivalent)
+    */
+    function wrapAll(toWrap, wrapper) {
+        wrap(toWrap, wrapper, true);
+    }
+
+    /**
+    * Usage:
+    * wrapInner(document.querySelector('#pepe'), '<div class="test">afdas</div>');
+    * wrapInner(document.querySelector('#pepe'), element);
+    *
+    * https://jsfiddle.net/zexxz0tw/6/
+    *
+    * https://stackoverflow.com/a/21817590/1081396
+    */
+    function wrapInner(parent, wrapper) {
+        if (typeof wrapper === "string"){
+            wrapper = createElementFromHTML(wrapper);
+        }
+
+        parent.appendChild(wrapper);
+
+        while(parent.firstChild !== wrapper){
+            wrapper.appendChild(parent.firstChild);
+       }
+    }
+
+    /**
+    * http://stackoverflow.com/questions/22100853/dom-pure-javascript-solution-to-jquery-closest-implementation
+    * Returns the element or `false` if there's none
+    */
+    function closest(el, selector) {
+        if(el && el.nodeType === 1){
+            if(matches(el, selector)){
+                return el;
+            }
+            return closest(el.parentNode, selector);
+        }
+        return null;
+    }
+
+    /**
+    * Places one element (rel) after another one or group of them (reference).
+    * @param {HTMLElement} reference
+    * @param {HTMLElement|NodeList|String} el
+    * https://jsfiddle.net/9s97hhzv/1/
+    */
+    function after(reference, el) {
+        insertBefore(reference, reference.nextSibling, el);
+    }
+
+    /**
+    * Places one element (rel) before another one or group of them (reference).
+    * @param {HTMLElement} reference
+    * @param {HTMLElement|NodeList|String} el
+    * https://jsfiddle.net/9s97hhzv/1/
+    */
+    function before(reference, el) {
+        insertBefore(reference, reference, el);
+    }
+
+    /**
+    * Based in https://stackoverflow.com/a/19316024/1081396
+    * and https://stackoverflow.com/a/4793630/1081396
+    */
+    function insertBefore(reference, beforeElement, el){
+        if(!isArrayOrList(el)){
+            if(typeof el == 'string'){
+                el = createElementFromHTML(el);
+            }
+            el = [el];
+        }
+
+        for(var i = 0; i<el.length; i++){
+            reference.parentNode.insertBefore(el[i], beforeElement);
+        }
+    }
+
+    //http://stackoverflow.com/questions/3464876/javascript-get-window-x-y-position-for-scroll
+    function getScrollTop(){
+        var doc = document.documentElement;
+        return (window.pageYOffset || doc.scrollTop)  - (doc.clientTop || 0);
+    }
+
+    /**
+    * Gets the siblings of the passed element
+    */
+    function siblings(el){
+        return Array.prototype.filter.call(el.parentNode.children, function(child){
+          return child !== el;
+        });
+    }
+
+    //for IE 9 ?
+    function preventDefault(event){
+        if(event.preventDefault){
+            event.preventDefault();
+        }
+        else{
+            event.returnValue = false;
+        }
+    }
+
+    /**
+    * Determines whether the passed item is of function type.
+    */
+    function isFunction(item) {
+      if (typeof item === 'function') {
+        return true;
+      }
+      var type = Object.prototype.toString(item);
+      return type === '[object Function]' || type === '[object GeneratorFunction]';
+    }
+
+    /**
+    * Trigger custom events
+    */
+    function trigger(el, eventName, data){
+        var event;
+        data = typeof data === 'undefined' ? {} : data;
+
+        // Native
+        if(typeof window.CustomEvent === "function" ){
+            event = new CustomEvent(eventName, {detail: data});
+        }
+        else{
+            event = document.createEvent('CustomEvent');
+            event.initCustomEvent(eventName, true, true, data);
+        }
+
+        el.dispatchEvent(event);
+    }
+
+    /**
+    * Polyfill of .matches()
+    */
+    function matches(el, selector) {
+        return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector);
+    }
+
+    /**
+    * Toggles the visibility of the passed element el.
+    */
+    function toggle(el, value){
+        if(typeof value === "boolean"){
+            for(var i = 0; i<el.length; i++){
+                el[i].style.display = value ? 'block' : 'none';
+            }
+        }
+        //we don't use it in other way, so no else :)
+
+        return el;
+    }
+
+    /**
+    * Creates a HTMLElement from the passed HTML string.
+    * https://stackoverflow.com/a/494348/1081396
+    */
+    function createElementFromHTML(htmlString) {
+        var div = document.createElement('div');
+        div.innerHTML = htmlString.trim();
+
+        // Change this to div.childNodes to support multiple top-level nodes
+        return div.firstChild;
+    }
+
+    /**
+    * Removes the passed item/s from the DOM.
+    */
+    function remove(items){
+        items = getList(items);
+        for(var i = 0; i<items.length; i++){
+            var item = items[i];
+            if(item && item.parentElement) {
+                item.parentNode.removeChild(item);
+            }
+        }
+    }
+
+    /**
+    * Filters an array by the passed filter funtion.
+    */
+    function filter(el, filterFn){
+        Array.prototype.filter.call(el, filterFn);
+    }
+
+    //https://jsfiddle.net/w1rktecz/
+    function untilAll(item, selector, fn){
+        var sibling = item[fn];
+        var siblings = [];
+        while(sibling){
+            if(matches(sibling, selector) || selector == null) {
+                siblings.push(sibling);
+            }
+            sibling = sibling[fn];
+        }
+
+        return siblings;
+    }
+
+    /**
+    * Gets all next elements matching the passed selector.
+    */
+    function nextAll(item, selector){
+        return untilAll(item, selector, 'nextElementSibling');
+    }
+
+    /**
+    * Gets all previous elements matching the passed selector.
+    */
+    function prevAll(item, selector){
+        return untilAll(item, selector, 'previousElementSibling');
+    }
+
+    /**
+    * Converts an object to an array.
+    */
+    function toArray(objectData){
+        return Object.keys(objectData).map(function(key) {
+           return objectData[key];
+        });
+    }
+
+    /**
+    * forEach polyfill for IE
+    * https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach#Browser_Compatibility
+    */
+    if (window.NodeList && !NodeList.prototype.forEach) {
+        NodeList.prototype.forEach = function (callback, thisArg) {
+            thisArg = thisArg || window;
+            for (var i = 0; i < this.length; i++) {
+                callback.call(thisArg, this[i], i, this);
+            }
+        };
+    }
+
+    //utils are public, so we can use it wherever we want
+    window.fp_utils = {
+        $: $,
+        deepExtend: deepExtend,
+        hasClass: hasClass,
+        getWindowHeight: getWindowHeight,
+        css: css,
+        until: until,
+        prevUntil: prevUntil,
+        nextUntil: nextUntil,
+        prev: prev,
+        next: next,
+        last: last,
+        index: index,
+        getList: getList,
+        hide: hide,
+        show: show,
+        isArrayOrList: isArrayOrList,
+        addClass: addClass,
+        removeClass: removeClass,
+        appendTo: appendTo,
+        wrap: wrap,
+        wrapAll: wrapAll,
+        wrapInner: wrapInner,
+        closest: closest,
+        after: after,
+        before: before,
+        insertBefore: insertBefore,
+        getScrollTop: getScrollTop,
+        siblings: siblings,
+        preventDefault: preventDefault,
+        isFunction: isFunction,
+        trigger: trigger,
+        matches: matches,
+        toggle: toggle,
+        createElementFromHTML: createElementFromHTML,
+        remove: remove,
+        filter: filter,
+        untilAll: untilAll,
+        nextAll: nextAll,
+        prevAll: prevAll,
+        showError: showError
+    };
+
+    return initialise;
+}));
+
+/**
+ * jQuery adapter for fullPage.js 3.0.0
+ */
+if(window.jQuery && window.fullpage){
+    (function ($, fullpage) {
+        'use strict';
+
+        // No jQuery No Go
+        if (!$ || !fullpage) {
+            window.fp_utils.showError('error', 'jQuery is required to use the jQuery fullpage adapter!');
+            return;
+        }
+
+        $.fn.fullpage = function(options) {
+            var FP = new fullpage('#' + $(this).attr('id'), options);
+
+            //Static API
+            Object.keys(FP).forEach(function (key) {
+                $.fn.fullpage[key] = FP[key];
+            });
+        };
+    })(window.jQuery, window.fullpage);
+}

File diff suppressed because it is too large
+ 1 - 0
script/jquery.min.js


+ 10 - 0
script/script.js

@@ -0,0 +1,10 @@
+$(document).ready(function() {
+	$('#fullpage').fullpage({
+		autoScrolling: false,
+		scrollOverflow: true
+	});
+
+	$('#gal').each(element, new SimpleBar);
+
+	//methods
+});

File diff suppressed because it is too large
+ 5 - 0
script/scrolloverflow.min.js


+ 4182 - 0
script/simplebar.js

@@ -0,0 +1,4182 @@
+/**
+ * SimpleBar.js - v3.1.0
+ * Scrollbars, simpler.
+ * https://grsmto.github.io/simplebar/
+ * 
+ * Made by Adrien Denat from a fork by Jonathan Nicol
+ * Under MIT License
+ */
+
+(function (global, factory) {
+  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+  typeof define === 'function' && define.amd ? define(factory) :
+  (global.SimpleBar = factory());
+}(this, (function () { 'use strict';
+
+  var _isObject = function (it) {
+    return typeof it === 'object' ? it !== null : typeof it === 'function';
+  };
+
+  var _anObject = function (it) {
+    if (!_isObject(it)) throw TypeError(it + ' is not an object!');
+    return it;
+  };
+
+  var _fails = function (exec) {
+    try {
+      return !!exec();
+    } catch (e) {
+      return true;
+    }
+  };
+
+  // Thank's IE8 for his funny defineProperty
+  var _descriptors = !_fails(function () {
+    return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
+  });
+
+  var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+
+  function createCommonjsModule(fn, module) {
+  	return module = { exports: {} }, fn(module, module.exports), module.exports;
+  }
+
+  var _global = createCommonjsModule(function (module) {
+  // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
+  var global = module.exports = typeof window != 'undefined' && window.Math == Math
+    ? window : typeof self != 'undefined' && self.Math == Math ? self
+    // eslint-disable-next-line no-new-func
+    : Function('return this')();
+  if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
+  });
+
+  var document$1 = _global.document;
+  // typeof document.createElement is 'object' in old IE
+  var is = _isObject(document$1) && _isObject(document$1.createElement);
+  var _domCreate = function (it) {
+    return is ? document$1.createElement(it) : {};
+  };
+
+  var _ie8DomDefine = !_descriptors && !_fails(function () {
+    return Object.defineProperty(_domCreate('div'), 'a', { get: function () { return 7; } }).a != 7;
+  });
+
+  // 7.1.1 ToPrimitive(input [, PreferredType])
+
+  // instead of the ES6 spec version, we didn't implement @@toPrimitive case
+  // and the second argument - flag - preferred type is a string
+  var _toPrimitive = function (it, S) {
+    if (!_isObject(it)) return it;
+    var fn, val;
+    if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
+    if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) return val;
+    if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val;
+    throw TypeError("Can't convert object to primitive value");
+  };
+
+  var dP = Object.defineProperty;
+
+  var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) {
+    _anObject(O);
+    P = _toPrimitive(P, true);
+    _anObject(Attributes);
+    if (_ie8DomDefine) try {
+      return dP(O, P, Attributes);
+    } catch (e) { /* empty */ }
+    if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
+    if ('value' in Attributes) O[P] = Attributes.value;
+    return O;
+  };
+
+  var _objectDp = {
+  	f: f
+  };
+
+  var _propertyDesc = function (bitmap, value) {
+    return {
+      enumerable: !(bitmap & 1),
+      configurable: !(bitmap & 2),
+      writable: !(bitmap & 4),
+      value: value
+    };
+  };
+
+  var _hide = _descriptors ? function (object, key, value) {
+    return _objectDp.f(object, key, _propertyDesc(1, value));
+  } : function (object, key, value) {
+    object[key] = value;
+    return object;
+  };
+
+  var hasOwnProperty = {}.hasOwnProperty;
+  var _has = function (it, key) {
+    return hasOwnProperty.call(it, key);
+  };
+
+  var id = 0;
+  var px = Math.random();
+  var _uid = function (key) {
+    return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
+  };
+
+  var _core = createCommonjsModule(function (module) {
+  var core = module.exports = { version: '2.5.7' };
+  if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
+  });
+  var _core_1 = _core.version;
+
+  var _redefine = createCommonjsModule(function (module) {
+  var SRC = _uid('src');
+  var TO_STRING = 'toString';
+  var $toString = Function[TO_STRING];
+  var TPL = ('' + $toString).split(TO_STRING);
+
+  _core.inspectSource = function (it) {
+    return $toString.call(it);
+  };
+
+  (module.exports = function (O, key, val, safe) {
+    var isFunction = typeof val == 'function';
+    if (isFunction) _has(val, 'name') || _hide(val, 'name', key);
+    if (O[key] === val) return;
+    if (isFunction) _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key)));
+    if (O === _global) {
+      O[key] = val;
+    } else if (!safe) {
+      delete O[key];
+      _hide(O, key, val);
+    } else if (O[key]) {
+      O[key] = val;
+    } else {
+      _hide(O, key, val);
+    }
+  // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
+  })(Function.prototype, TO_STRING, function toString() {
+    return typeof this == 'function' && this[SRC] || $toString.call(this);
+  });
+  });
+
+  // 7.2.1 RequireObjectCoercible(argument)
+  var _defined = function (it) {
+    if (it == undefined) throw TypeError("Can't call method on  " + it);
+    return it;
+  };
+
+  var _library = false;
+
+  var _shared = createCommonjsModule(function (module) {
+  var SHARED = '__core-js_shared__';
+  var store = _global[SHARED] || (_global[SHARED] = {});
+
+  (module.exports = function (key, value) {
+    return store[key] || (store[key] = value !== undefined ? value : {});
+  })('versions', []).push({
+    version: _core.version,
+    mode: _library ? 'pure' : 'global',
+    copyright: '© 2018 Denis Pushkarev (zloirock.ru)'
+  });
+  });
+
+  var _wks = createCommonjsModule(function (module) {
+  var store = _shared('wks');
+
+  var Symbol = _global.Symbol;
+  var USE_SYMBOL = typeof Symbol == 'function';
+
+  var $exports = module.exports = function (name) {
+    return store[name] || (store[name] =
+      USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : _uid)('Symbol.' + name));
+  };
+
+  $exports.store = store;
+  });
+
+  var _fixReWks = function (KEY, length, exec) {
+    var SYMBOL = _wks(KEY);
+    var fns = exec(_defined, SYMBOL, ''[KEY]);
+    var strfn = fns[0];
+    var rxfn = fns[1];
+    if (_fails(function () {
+      var O = {};
+      O[SYMBOL] = function () { return 7; };
+      return ''[KEY](O) != 7;
+    })) {
+      _redefine(String.prototype, KEY, strfn);
+      _hide(RegExp.prototype, SYMBOL, length == 2
+        // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
+        // 21.2.5.11 RegExp.prototype[@@split](string, limit)
+        ? function (string, arg) { return rxfn.call(string, this, arg); }
+        // 21.2.5.6 RegExp.prototype[@@match](string)
+        // 21.2.5.9 RegExp.prototype[@@search](string)
+        : function (string) { return rxfn.call(string, this); }
+      );
+    }
+  };
+
+  // @@replace logic
+  _fixReWks('replace', 2, function (defined, REPLACE, $replace) {
+    // 21.1.3.14 String.prototype.replace(searchValue, replaceValue)
+    return [function replace(searchValue, replaceValue) {
+      var O = defined(this);
+      var fn = searchValue == undefined ? undefined : searchValue[REPLACE];
+      return fn !== undefined
+        ? fn.call(searchValue, O, replaceValue)
+        : $replace.call(String(O), searchValue, replaceValue);
+    }, $replace];
+  });
+
+  var dP$1 = _objectDp.f;
+  var FProto = Function.prototype;
+  var nameRE = /^\s*function ([^ (]*)/;
+  var NAME = 'name';
+
+  // 19.2.4.2 name
+  NAME in FProto || _descriptors && dP$1(FProto, NAME, {
+    configurable: true,
+    get: function () {
+      try {
+        return ('' + this).match(nameRE)[1];
+      } catch (e) {
+        return '';
+      }
+    }
+  });
+
+  // @@match logic
+  _fixReWks('match', 1, function (defined, MATCH, $match) {
+    // 21.1.3.11 String.prototype.match(regexp)
+    return [function match(regexp) {
+      var O = defined(this);
+      var fn = regexp == undefined ? undefined : regexp[MATCH];
+      return fn !== undefined ? fn.call(regexp, O) : new RegExp(regexp)[MATCH](String(O));
+    }, $match];
+  });
+
+  // 22.1.3.31 Array.prototype[@@unscopables]
+  var UNSCOPABLES = _wks('unscopables');
+  var ArrayProto = Array.prototype;
+  if (ArrayProto[UNSCOPABLES] == undefined) _hide(ArrayProto, UNSCOPABLES, {});
+  var _addToUnscopables = function (key) {
+    ArrayProto[UNSCOPABLES][key] = true;
+  };
+
+  var _iterStep = function (done, value) {
+    return { value: value, done: !!done };
+  };
+
+  var _iterators = {};
+
+  var toString = {}.toString;
+
+  var _cof = function (it) {
+    return toString.call(it).slice(8, -1);
+  };
+
+  // fallback for non-array-like ES3 and non-enumerable old V8 strings
+
+  // eslint-disable-next-line no-prototype-builtins
+  var _iobject = Object('z').propertyIsEnumerable(0) ? Object : function (it) {
+    return _cof(it) == 'String' ? it.split('') : Object(it);
+  };
+
+  // to indexed object, toObject with fallback for non-array-like ES3 strings
+
+
+  var _toIobject = function (it) {
+    return _iobject(_defined(it));
+  };
+
+  var _aFunction = function (it) {
+    if (typeof it != 'function') throw TypeError(it + ' is not a function!');
+    return it;
+  };
+
+  // optional / simple context binding
+
+  var _ctx = function (fn, that, length) {
+    _aFunction(fn);
+    if (that === undefined) return fn;
+    switch (length) {
+      case 1: return function (a) {
+        return fn.call(that, a);
+      };
+      case 2: return function (a, b) {
+        return fn.call(that, a, b);
+      };
+      case 3: return function (a, b, c) {
+        return fn.call(that, a, b, c);
+      };
+    }
+    return function (/* ...args */) {
+      return fn.apply(that, arguments);
+    };
+  };
+
+  var PROTOTYPE = 'prototype';
+
+  var $export = function (type, name, source) {
+    var IS_FORCED = type & $export.F;
+    var IS_GLOBAL = type & $export.G;
+    var IS_STATIC = type & $export.S;
+    var IS_PROTO = type & $export.P;
+    var IS_BIND = type & $export.B;
+    var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE];
+    var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {});
+    var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});
+    var key, own, out, exp;
+    if (IS_GLOBAL) source = name;
+    for (key in source) {
+      // contains in native
+      own = !IS_FORCED && target && target[key] !== undefined;
+      // export native or passed
+      out = (own ? target : source)[key];
+      // bind timers to global for call from export context
+      exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out;
+      // extend global
+      if (target) _redefine(target, key, out, type & $export.U);
+      // export
+      if (exports[key] != out) _hide(exports, key, exp);
+      if (IS_PROTO && expProto[key] != out) expProto[key] = out;
+    }
+  };
+  _global.core = _core;
+  // type bitmap
+  $export.F = 1;   // forced
+  $export.G = 2;   // global
+  $export.S = 4;   // static
+  $export.P = 8;   // proto
+  $export.B = 16;  // bind
+  $export.W = 32;  // wrap
+  $export.U = 64;  // safe
+  $export.R = 128; // real proto method for `library`
+  var _export = $export;
+
+  // 7.1.4 ToInteger
+  var ceil = Math.ceil;
+  var floor = Math.floor;
+  var _toInteger = function (it) {
+    return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
+  };
+
+  // 7.1.15 ToLength
+
+  var min = Math.min;
+  var _toLength = function (it) {
+    return it > 0 ? min(_toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
+  };
+
+  var max = Math.max;
+  var min$1 = Math.min;
+  var _toAbsoluteIndex = function (index, length) {
+    index = _toInteger(index);
+    return index < 0 ? max(index + length, 0) : min$1(index, length);
+  };
+
+  // false -> Array#indexOf
+  // true  -> Array#includes
+
+
+
+  var _arrayIncludes = function (IS_INCLUDES) {
+    return function ($this, el, fromIndex) {
+      var O = _toIobject($this);
+      var length = _toLength(O.length);
+      var index = _toAbsoluteIndex(fromIndex, length);
+      var value;
+      // Array#includes uses SameValueZero equality algorithm
+      // eslint-disable-next-line no-self-compare
+      if (IS_INCLUDES && el != el) while (length > index) {
+        value = O[index++];
+        // eslint-disable-next-line no-self-compare
+        if (value != value) return true;
+      // Array#indexOf ignores holes, Array#includes - not
+      } else for (;length > index; index++) if (IS_INCLUDES || index in O) {
+        if (O[index] === el) return IS_INCLUDES || index || 0;
+      } return !IS_INCLUDES && -1;
+    };
+  };
+
+  var shared = _shared('keys');
+
+  var _sharedKey = function (key) {
+    return shared[key] || (shared[key] = _uid(key));
+  };
+
+  var arrayIndexOf = _arrayIncludes(false);
+  var IE_PROTO = _sharedKey('IE_PROTO');
+
+  var _objectKeysInternal = function (object, names) {
+    var O = _toIobject(object);
+    var i = 0;
+    var result = [];
+    var key;
+    for (key in O) if (key != IE_PROTO) _has(O, key) && result.push(key);
+    // Don't enum bug & hidden keys
+    while (names.length > i) if (_has(O, key = names[i++])) {
+      ~arrayIndexOf(result, key) || result.push(key);
+    }
+    return result;
+  };
+
+  // IE 8- don't enum bug keys
+  var _enumBugKeys = (
+    'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'
+  ).split(',');
+
+  // 19.1.2.14 / 15.2.3.14 Object.keys(O)
+
+
+
+  var _objectKeys = Object.keys || function keys(O) {
+    return _objectKeysInternal(O, _enumBugKeys);
+  };
+
+  var _objectDps = _descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
+    _anObject(O);
+    var keys = _objectKeys(Properties);
+    var length = keys.length;
+    var i = 0;
+    var P;
+    while (length > i) _objectDp.f(O, P = keys[i++], Properties[P]);
+    return O;
+  };
+
+  var document$2 = _global.document;
+  var _html = document$2 && document$2.documentElement;
+
+  // 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])
+
+
+
+  var IE_PROTO$1 = _sharedKey('IE_PROTO');
+  var Empty = function () { /* empty */ };
+  var PROTOTYPE$1 = 'prototype';
+
+  // Create object with fake `null` prototype: use iframe Object with cleared prototype
+  var createDict = function () {
+    // Thrash, waste and sodomy: IE GC bug
+    var iframe = _domCreate('iframe');
+    var i = _enumBugKeys.length;
+    var lt = '<';
+    var gt = '>';
+    var iframeDocument;
+    iframe.style.display = 'none';
+    _html.appendChild(iframe);
+    iframe.src = 'javascript:'; // eslint-disable-line no-script-url
+    // createDict = iframe.contentWindow.Object;
+    // html.removeChild(iframe);
+    iframeDocument = iframe.contentWindow.document;
+    iframeDocument.open();
+    iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);
+    iframeDocument.close();
+    createDict = iframeDocument.F;
+    while (i--) delete createDict[PROTOTYPE$1][_enumBugKeys[i]];
+    return createDict();
+  };
+
+  var _objectCreate = Object.create || function create(O, Properties) {
+    var result;
+    if (O !== null) {
+      Empty[PROTOTYPE$1] = _anObject(O);
+      result = new Empty();
+      Empty[PROTOTYPE$1] = null;
+      // add "__proto__" for Object.getPrototypeOf polyfill
+      result[IE_PROTO$1] = O;
+    } else result = createDict();
+    return Properties === undefined ? result : _objectDps(result, Properties);
+  };
+
+  var def = _objectDp.f;
+
+  var TAG = _wks('toStringTag');
+
+  var _setToStringTag = function (it, tag, stat) {
+    if (it && !_has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });
+  };
+
+  var IteratorPrototype = {};
+
+  // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
+  _hide(IteratorPrototype, _wks('iterator'), function () { return this; });
+
+  var _iterCreate = function (Constructor, NAME, next) {
+    Constructor.prototype = _objectCreate(IteratorPrototype, { next: _propertyDesc(1, next) });
+    _setToStringTag(Constructor, NAME + ' Iterator');
+  };
+
+  // 7.1.13 ToObject(argument)
+
+  var _toObject = function (it) {
+    return Object(_defined(it));
+  };
+
+  // 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)
+
+
+  var IE_PROTO$2 = _sharedKey('IE_PROTO');
+  var ObjectProto = Object.prototype;
+
+  var _objectGpo = Object.getPrototypeOf || function (O) {
+    O = _toObject(O);
+    if (_has(O, IE_PROTO$2)) return O[IE_PROTO$2];
+    if (typeof O.constructor == 'function' && O instanceof O.constructor) {
+      return O.constructor.prototype;
+    } return O instanceof Object ? ObjectProto : null;
+  };
+
+  var ITERATOR = _wks('iterator');
+  var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`
+  var FF_ITERATOR = '@@iterator';
+  var KEYS = 'keys';
+  var VALUES = 'values';
+
+  var returnThis = function () { return this; };
+
+  var _iterDefine = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {
+    _iterCreate(Constructor, NAME, next);
+    var getMethod = function (kind) {
+      if (!BUGGY && kind in proto) return proto[kind];
+      switch (kind) {
+        case KEYS: return function keys() { return new Constructor(this, kind); };
+        case VALUES: return function values() { return new Constructor(this, kind); };
+      } return function entries() { return new Constructor(this, kind); };
+    };
+    var TAG = NAME + ' Iterator';
+    var DEF_VALUES = DEFAULT == VALUES;
+    var VALUES_BUG = false;
+    var proto = Base.prototype;
+    var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];
+    var $default = $native || getMethod(DEFAULT);
+    var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;
+    var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;
+    var methods, key, IteratorPrototype;
+    // Fix native
+    if ($anyNative) {
+      IteratorPrototype = _objectGpo($anyNative.call(new Base()));
+      if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {
+        // Set @@toStringTag to native iterators
+        _setToStringTag(IteratorPrototype, TAG, true);
+        // fix for some old engines
+        if (!_library && typeof IteratorPrototype[ITERATOR] != 'function') _hide(IteratorPrototype, ITERATOR, returnThis);
+      }
+    }
+    // fix Array#{values, @@iterator}.name in V8 / FF
+    if (DEF_VALUES && $native && $native.name !== VALUES) {
+      VALUES_BUG = true;
+      $default = function values() { return $native.call(this); };
+    }
+    // Define iterator
+    if ((!_library || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {
+      _hide(proto, ITERATOR, $default);
+    }
+    // Plug for library
+    _iterators[NAME] = $default;
+    _iterators[TAG] = returnThis;
+    if (DEFAULT) {
+      methods = {
+        values: DEF_VALUES ? $default : getMethod(VALUES),
+        keys: IS_SET ? $default : getMethod(KEYS),
+        entries: $entries
+      };
+      if (FORCED) for (key in methods) {
+        if (!(key in proto)) _redefine(proto, key, methods[key]);
+      } else _export(_export.P + _export.F * (BUGGY || VALUES_BUG), NAME, methods);
+    }
+    return methods;
+  };
+
+  // 22.1.3.4 Array.prototype.entries()
+  // 22.1.3.13 Array.prototype.keys()
+  // 22.1.3.29 Array.prototype.values()
+  // 22.1.3.30 Array.prototype[@@iterator]()
+  var es6_array_iterator = _iterDefine(Array, 'Array', function (iterated, kind) {
+    this._t = _toIobject(iterated); // target
+    this._i = 0;                   // next index
+    this._k = kind;                // kind
+  // 22.1.5.2.1 %ArrayIteratorPrototype%.next()
+  }, function () {
+    var O = this._t;
+    var kind = this._k;
+    var index = this._i++;
+    if (!O || index >= O.length) {
+      this._t = undefined;
+      return _iterStep(1);
+    }
+    if (kind == 'keys') return _iterStep(0, index);
+    if (kind == 'values') return _iterStep(0, O[index]);
+    return _iterStep(0, [index, O[index]]);
+  }, 'values');
+
+  // argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)
+  _iterators.Arguments = _iterators.Array;
+
+  _addToUnscopables('keys');
+  _addToUnscopables('values');
+  _addToUnscopables('entries');
+
+  var ITERATOR$1 = _wks('iterator');
+  var TO_STRING_TAG = _wks('toStringTag');
+  var ArrayValues = _iterators.Array;
+
+  var DOMIterables = {
+    CSSRuleList: true, // TODO: Not spec compliant, should be false.
+    CSSStyleDeclaration: false,
+    CSSValueList: false,
+    ClientRectList: false,
+    DOMRectList: false,
+    DOMStringList: false,
+    DOMTokenList: true,
+    DataTransferItemList: false,
+    FileList: false,
+    HTMLAllCollection: false,
+    HTMLCollection: false,
+    HTMLFormElement: false,
+    HTMLSelectElement: false,
+    MediaList: true, // TODO: Not spec compliant, should be false.
+    MimeTypeArray: false,
+    NamedNodeMap: false,
+    NodeList: true,
+    PaintRequestList: false,
+    Plugin: false,
+    PluginArray: false,
+    SVGLengthList: false,
+    SVGNumberList: false,
+    SVGPathSegList: false,
+    SVGPointList: false,
+    SVGStringList: false,
+    SVGTransformList: false,
+    SourceBufferList: false,
+    StyleSheetList: true, // TODO: Not spec compliant, should be false.
+    TextTrackCueList: false,
+    TextTrackList: false,
+    TouchList: false
+  };
+
+  for (var collections = _objectKeys(DOMIterables), i = 0; i < collections.length; i++) {
+    var NAME$1 = collections[i];
+    var explicit = DOMIterables[NAME$1];
+    var Collection = _global[NAME$1];
+    var proto = Collection && Collection.prototype;
+    var key;
+    if (proto) {
+      if (!proto[ITERATOR$1]) _hide(proto, ITERATOR$1, ArrayValues);
+      if (!proto[TO_STRING_TAG]) _hide(proto, TO_STRING_TAG, NAME$1);
+      _iterators[NAME$1] = ArrayValues;
+      if (explicit) for (key in es6_array_iterator) if (!proto[key]) _redefine(proto, key, es6_array_iterator[key], true);
+    }
+  }
+
+  // true  -> String#at
+  // false -> String#codePointAt
+  var _stringAt = function (TO_STRING) {
+    return function (that, pos) {
+      var s = String(_defined(that));
+      var i = _toInteger(pos);
+      var l = s.length;
+      var a, b;
+      if (i < 0 || i >= l) return TO_STRING ? '' : undefined;
+      a = s.charCodeAt(i);
+      return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
+        ? TO_STRING ? s.charAt(i) : a
+        : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
+    };
+  };
+
+  var $at = _stringAt(true);
+
+  // 21.1.3.27 String.prototype[@@iterator]()
+  _iterDefine(String, 'String', function (iterated) {
+    this._t = String(iterated); // target
+    this._i = 0;                // next index
+  // 21.1.5.2.1 %StringIteratorPrototype%.next()
+  }, function () {
+    var O = this._t;
+    var index = this._i;
+    var point;
+    if (index >= O.length) return { value: undefined, done: true };
+    point = $at(O, index);
+    this._i += point.length;
+    return { value: point, done: false };
+  });
+
+  // call something on iterator step with safe closing on error
+
+  var _iterCall = function (iterator, fn, value, entries) {
+    try {
+      return entries ? fn(_anObject(value)[0], value[1]) : fn(value);
+    // 7.4.6 IteratorClose(iterator, completion)
+    } catch (e) {
+      var ret = iterator['return'];
+      if (ret !== undefined) _anObject(ret.call(iterator));
+      throw e;
+    }
+  };
+
+  // check on default Array iterator
+
+  var ITERATOR$2 = _wks('iterator');
+  var ArrayProto$1 = Array.prototype;
+
+  var _isArrayIter = function (it) {
+    return it !== undefined && (_iterators.Array === it || ArrayProto$1[ITERATOR$2] === it);
+  };
+
+  var _createProperty = function (object, index, value) {
+    if (index in object) _objectDp.f(object, index, _propertyDesc(0, value));
+    else object[index] = value;
+  };
+
+  // getting tag from 19.1.3.6 Object.prototype.toString()
+
+  var TAG$1 = _wks('toStringTag');
+  // ES3 wrong here
+  var ARG = _cof(function () { return arguments; }()) == 'Arguments';
+
+  // fallback for IE11 Script Access Denied error
+  var tryGet = function (it, key) {
+    try {
+      return it[key];
+    } catch (e) { /* empty */ }
+  };
+
+  var _classof = function (it) {
+    var O, T, B;
+    return it === undefined ? 'Undefined' : it === null ? 'Null'
+      // @@toStringTag case
+      : typeof (T = tryGet(O = Object(it), TAG$1)) == 'string' ? T
+      // builtinTag case
+      : ARG ? _cof(O)
+      // ES3 arguments fallback
+      : (B = _cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;
+  };
+
+  var ITERATOR$3 = _wks('iterator');
+
+  var core_getIteratorMethod = _core.getIteratorMethod = function (it) {
+    if (it != undefined) return it[ITERATOR$3]
+      || it['@@iterator']
+      || _iterators[_classof(it)];
+  };
+
+  var ITERATOR$4 = _wks('iterator');
+  var SAFE_CLOSING = false;
+
+  try {
+    var riter = [7][ITERATOR$4]();
+    riter['return'] = function () { SAFE_CLOSING = true; };
+  } catch (e) { /* empty */ }
+
+  var _iterDetect = function (exec, skipClosing) {
+    if (!skipClosing && !SAFE_CLOSING) return false;
+    var safe = false;
+    try {
+      var arr = [7];
+      var iter = arr[ITERATOR$4]();
+      iter.next = function () { return { done: safe = true }; };
+      arr[ITERATOR$4] = function () { return iter; };
+      exec(arr);
+    } catch (e) { /* empty */ }
+    return safe;
+  };
+
+  _export(_export.S + _export.F * !_iterDetect(function (iter) { }), 'Array', {
+    // 22.1.2.1 Array.from(arrayLike, mapfn = undefined, thisArg = undefined)
+    from: function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
+      var O = _toObject(arrayLike);
+      var C = typeof this == 'function' ? this : Array;
+      var aLen = arguments.length;
+      var mapfn = aLen > 1 ? arguments[1] : undefined;
+      var mapping = mapfn !== undefined;
+      var index = 0;
+      var iterFn = core_getIteratorMethod(O);
+      var length, result, step, iterator;
+      if (mapping) mapfn = _ctx(mapfn, aLen > 2 ? arguments[2] : undefined, 2);
+      // if object isn't iterable or it's array with default iterator - use simple case
+      if (iterFn != undefined && !(C == Array && _isArrayIter(iterFn))) {
+        for (iterator = iterFn.call(O), result = new C(); !(step = iterator.next()).done; index++) {
+          _createProperty(result, index, mapping ? _iterCall(iterator, mapfn, [step.value, index], true) : step.value);
+        }
+      } else {
+        length = _toLength(O.length);
+        for (result = new C(length); length > index; index++) {
+          _createProperty(result, index, mapping ? mapfn(O[index], index) : O[index]);
+        }
+      }
+      result.length = index;
+      return result;
+    }
+  });
+
+  function _classCallCheck(instance, Constructor) {
+    if (!(instance instanceof Constructor)) {
+      throw new TypeError("Cannot call a class as a function");
+    }
+  }
+
+  function _defineProperties(target, props) {
+    for (var i = 0; i < props.length; i++) {
+      var descriptor = props[i];
+      descriptor.enumerable = descriptor.enumerable || false;
+      descriptor.configurable = true;
+      if ("value" in descriptor) descriptor.writable = true;
+      Object.defineProperty(target, descriptor.key, descriptor);
+    }
+  }
+
+  function _createClass(Constructor, protoProps, staticProps) {
+    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+    if (staticProps) _defineProperties(Constructor, staticProps);
+    return Constructor;
+  }
+
+  function _defineProperty(obj, key, value) {
+    if (key in obj) {
+      Object.defineProperty(obj, key, {
+        value: value,
+        enumerable: true,
+        configurable: true,
+        writable: true
+      });
+    } else {
+      obj[key] = value;
+    }
+
+    return obj;
+  }
+
+  function _objectSpread(target) {
+    for (var i = 1; i < arguments.length; i++) {
+      var source = arguments[i] != null ? arguments[i] : {};
+      var ownKeys = Object.keys(source);
+
+      if (typeof Object.getOwnPropertySymbols === 'function') {
+        ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
+          return Object.getOwnPropertyDescriptor(source, sym).enumerable;
+        }));
+      }
+
+      ownKeys.forEach(function (key) {
+        _defineProperty(target, key, source[key]);
+      });
+    }
+
+    return target;
+  }
+
+  var scrollbarWidth = createCommonjsModule(function (module, exports) {
+  /*! scrollbarWidth.js v0.1.3 | felixexter | MIT | https://github.com/felixexter/scrollbarWidth */
+  (function (root, factory) {
+  	{
+  		module.exports = factory();
+  	}
+  }(commonjsGlobal, function () {
+
+  	function scrollbarWidth() {
+  		if (typeof document === 'undefined') {
+  			return 0
+  		}
+
+  		var
+  			body = document.body,
+  			box = document.createElement('div'),
+  			boxStyle = box.style,
+  			width;
+
+  		boxStyle.position = 'absolute';
+  		boxStyle.top = boxStyle.left = '-9999px';
+  		boxStyle.width = boxStyle.height = '100px';
+  		boxStyle.overflow = 'scroll';
+
+  		body.appendChild(box);
+
+  		width = box.offsetWidth - box.clientWidth;
+
+  		body.removeChild(box);
+
+  		return width;
+  	}
+
+  	return scrollbarWidth;
+  }));
+  });
+
+  /**
+   * lodash (Custom Build) <https://lodash.com/>
+   * Build: `lodash modularize exports="npm" -o ./`
+   * Copyright jQuery Foundation and other contributors <https://jquery.org/>
+   * Released under MIT license <https://lodash.com/license>
+   * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
+   * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+   */
+
+  /** Used as the `TypeError` message for "Functions" methods. */
+  var FUNC_ERROR_TEXT = 'Expected a function';
+
+  /** Used as references for various `Number` constants. */
+  var NAN = 0 / 0;
+
+  /** `Object#toString` result references. */
+  var symbolTag = '[object Symbol]';
+
+  /** Used to match leading and trailing whitespace. */
+  var reTrim = /^\s+|\s+$/g;
+
+  /** Used to detect bad signed hexadecimal string values. */
+  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
+
+  /** Used to detect binary string values. */
+  var reIsBinary = /^0b[01]+$/i;
+
+  /** Used to detect octal string values. */
+  var reIsOctal = /^0o[0-7]+$/i;
+
+  /** Built-in method references without a dependency on `root`. */
+  var freeParseInt = parseInt;
+
+  /** Detect free variable `global` from Node.js. */
+  var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
+
+  /** Detect free variable `self`. */
+  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
+
+  /** Used as a reference to the global object. */
+  var root = freeGlobal || freeSelf || Function('return this')();
+
+  /** Used for built-in method references. */
+  var objectProto = Object.prototype;
+
+  /**
+   * Used to resolve the
+   * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
+   * of values.
+   */
+  var objectToString = objectProto.toString;
+
+  /* Built-in method references for those with the same name as other `lodash` methods. */
+  var nativeMax = Math.max,
+      nativeMin = Math.min;
+
+  /**
+   * Gets the timestamp of the number of milliseconds that have elapsed since
+   * the Unix epoch (1 January 1970 00:00:00 UTC).
+   *
+   * @static
+   * @memberOf _
+   * @since 2.4.0
+   * @category Date
+   * @returns {number} Returns the timestamp.
+   * @example
+   *
+   * _.defer(function(stamp) {
+   *   console.log(_.now() - stamp);
+   * }, _.now());
+   * // => Logs the number of milliseconds it took for the deferred invocation.
+   */
+  var now = function() {
+    return root.Date.now();
+  };
+
+  /**
+   * Creates a debounced function that delays invoking `func` until after `wait`
+   * milliseconds have elapsed since the last time the debounced function was
+   * invoked. The debounced function comes with a `cancel` method to cancel
+   * delayed `func` invocations and a `flush` method to immediately invoke them.
+   * Provide `options` to indicate whether `func` should be invoked on the
+   * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
+   * with the last arguments provided to the debounced function. Subsequent
+   * calls to the debounced function return the result of the last `func`
+   * invocation.
+   *
+   * **Note:** If `leading` and `trailing` options are `true`, `func` is
+   * invoked on the trailing edge of the timeout only if the debounced function
+   * is invoked more than once during the `wait` timeout.
+   *
+   * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
+   * until to the next tick, similar to `setTimeout` with a timeout of `0`.
+   *
+   * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+   * for details over the differences between `_.debounce` and `_.throttle`.
+   *
+   * @static
+   * @memberOf _
+   * @since 0.1.0
+   * @category Function
+   * @param {Function} func The function to debounce.
+   * @param {number} [wait=0] The number of milliseconds to delay.
+   * @param {Object} [options={}] The options object.
+   * @param {boolean} [options.leading=false]
+   *  Specify invoking on the leading edge of the timeout.
+   * @param {number} [options.maxWait]
+   *  The maximum time `func` is allowed to be delayed before it's invoked.
+   * @param {boolean} [options.trailing=true]
+   *  Specify invoking on the trailing edge of the timeout.
+   * @returns {Function} Returns the new debounced function.
+   * @example
+   *
+   * // Avoid costly calculations while the window size is in flux.
+   * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
+   *
+   * // Invoke `sendMail` when clicked, debouncing subsequent calls.
+   * jQuery(element).on('click', _.debounce(sendMail, 300, {
+   *   'leading': true,
+   *   'trailing': false
+   * }));
+   *
+   * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
+   * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
+   * var source = new EventSource('/stream');
+   * jQuery(source).on('message', debounced);
+   *
+   * // Cancel the trailing debounced invocation.
+   * jQuery(window).on('popstate', debounced.cancel);
+   */
+  function debounce(func, wait, options) {
+    var lastArgs,
+        lastThis,
+        maxWait,
+        result,
+        timerId,
+        lastCallTime,
+        lastInvokeTime = 0,
+        leading = false,
+        maxing = false,
+        trailing = true;
+
+    if (typeof func != 'function') {
+      throw new TypeError(FUNC_ERROR_TEXT);
+    }
+    wait = toNumber(wait) || 0;
+    if (isObject(options)) {
+      leading = !!options.leading;
+      maxing = 'maxWait' in options;
+      maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
+      trailing = 'trailing' in options ? !!options.trailing : trailing;
+    }
+
+    function invokeFunc(time) {
+      var args = lastArgs,
+          thisArg = lastThis;
+
+      lastArgs = lastThis = undefined;
+      lastInvokeTime = time;
+      result = func.apply(thisArg, args);
+      return result;
+    }
+
+    function leadingEdge(time) {
+      // Reset any `maxWait` timer.
+      lastInvokeTime = time;
+      // Start the timer for the trailing edge.
+      timerId = setTimeout(timerExpired, wait);
+      // Invoke the leading edge.
+      return leading ? invokeFunc(time) : result;
+    }
+
+    function remainingWait(time) {
+      var timeSinceLastCall = time - lastCallTime,
+          timeSinceLastInvoke = time - lastInvokeTime,
+          result = wait - timeSinceLastCall;
+
+      return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
+    }
+
+    function shouldInvoke(time) {
+      var timeSinceLastCall = time - lastCallTime,
+          timeSinceLastInvoke = time - lastInvokeTime;
+
+      // Either this is the first call, activity has stopped and we're at the
+      // trailing edge, the system time has gone backwards and we're treating
+      // it as the trailing edge, or we've hit the `maxWait` limit.
+      return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
+        (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
+    }
+
+    function timerExpired() {
+      var time = now();
+      if (shouldInvoke(time)) {
+        return trailingEdge(time);
+      }
+      // Restart the timer.
+      timerId = setTimeout(timerExpired, remainingWait(time));
+    }
+
+    function trailingEdge(time) {
+      timerId = undefined;
+
+      // Only invoke if we have `lastArgs` which means `func` has been
+      // debounced at least once.
+      if (trailing && lastArgs) {
+        return invokeFunc(time);
+      }
+      lastArgs = lastThis = undefined;
+      return result;
+    }
+
+    function cancel() {
+      if (timerId !== undefined) {
+        clearTimeout(timerId);
+      }
+      lastInvokeTime = 0;
+      lastArgs = lastCallTime = lastThis = timerId = undefined;
+    }
+
+    function flush() {
+      return timerId === undefined ? result : trailingEdge(now());
+    }
+
+    function debounced() {
+      var time = now(),
+          isInvoking = shouldInvoke(time);
+
+      lastArgs = arguments;
+      lastThis = this;
+      lastCallTime = time;
+
+      if (isInvoking) {
+        if (timerId === undefined) {
+          return leadingEdge(lastCallTime);
+        }
+        if (maxing) {
+          // Handle invocations in a tight loop.
+          timerId = setTimeout(timerExpired, wait);
+          return invokeFunc(lastCallTime);
+        }
+      }
+      if (timerId === undefined) {
+        timerId = setTimeout(timerExpired, wait);
+      }
+      return result;
+    }
+    debounced.cancel = cancel;
+    debounced.flush = flush;
+    return debounced;
+  }
+
+  /**
+   * Creates a throttled function that only invokes `func` at most once per
+   * every `wait` milliseconds. The throttled function comes with a `cancel`
+   * method to cancel delayed `func` invocations and a `flush` method to
+   * immediately invoke them. Provide `options` to indicate whether `func`
+   * should be invoked on the leading and/or trailing edge of the `wait`
+   * timeout. The `func` is invoked with the last arguments provided to the
+   * throttled function. Subsequent calls to the throttled function return the
+   * result of the last `func` invocation.
+   *
+   * **Note:** If `leading` and `trailing` options are `true`, `func` is
+   * invoked on the trailing edge of the timeout only if the throttled function
+   * is invoked more than once during the `wait` timeout.
+   *
+   * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
+   * until to the next tick, similar to `setTimeout` with a timeout of `0`.
+   *
+   * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+   * for details over the differences between `_.throttle` and `_.debounce`.
+   *
+   * @static
+   * @memberOf _
+   * @since 0.1.0
+   * @category Function
+   * @param {Function} func The function to throttle.
+   * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
+   * @param {Object} [options={}] The options object.
+   * @param {boolean} [options.leading=true]
+   *  Specify invoking on the leading edge of the timeout.
+   * @param {boolean} [options.trailing=true]
+   *  Specify invoking on the trailing edge of the timeout.
+   * @returns {Function} Returns the new throttled function.
+   * @example
+   *
+   * // Avoid excessively updating the position while scrolling.
+   * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
+   *
+   * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
+   * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
+   * jQuery(element).on('click', throttled);
+   *
+   * // Cancel the trailing throttled invocation.
+   * jQuery(window).on('popstate', throttled.cancel);
+   */
+  function throttle(func, wait, options) {
+    var leading = true,
+        trailing = true;
+
+    if (typeof func != 'function') {
+      throw new TypeError(FUNC_ERROR_TEXT);
+    }
+    if (isObject(options)) {
+      leading = 'leading' in options ? !!options.leading : leading;
+      trailing = 'trailing' in options ? !!options.trailing : trailing;
+    }
+    return debounce(func, wait, {
+      'leading': leading,
+      'maxWait': wait,
+      'trailing': trailing
+    });
+  }
+
+  /**
+   * Checks if `value` is the
+   * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
+   * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+   *
+   * @static
+   * @memberOf _
+   * @since 0.1.0
+   * @category Lang
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+   * @example
+   *
+   * _.isObject({});
+   * // => true
+   *
+   * _.isObject([1, 2, 3]);
+   * // => true
+   *
+   * _.isObject(_.noop);
+   * // => true
+   *
+   * _.isObject(null);
+   * // => false
+   */
+  function isObject(value) {
+    var type = typeof value;
+    return !!value && (type == 'object' || type == 'function');
+  }
+
+  /**
+   * Checks if `value` is object-like. A value is object-like if it's not `null`
+   * and has a `typeof` result of "object".
+   *
+   * @static
+   * @memberOf _
+   * @since 4.0.0
+   * @category Lang
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+   * @example
+   *
+   * _.isObjectLike({});
+   * // => true
+   *
+   * _.isObjectLike([1, 2, 3]);
+   * // => true
+   *
+   * _.isObjectLike(_.noop);
+   * // => false
+   *
+   * _.isObjectLike(null);
+   * // => false
+   */
+  function isObjectLike(value) {
+    return !!value && typeof value == 'object';
+  }
+
+  /**
+   * Checks if `value` is classified as a `Symbol` primitive or object.
+   *
+   * @static
+   * @memberOf _
+   * @since 4.0.0
+   * @category Lang
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
+   * @example
+   *
+   * _.isSymbol(Symbol.iterator);
+   * // => true
+   *
+   * _.isSymbol('abc');
+   * // => false
+   */
+  function isSymbol(value) {
+    return typeof value == 'symbol' ||
+      (isObjectLike(value) && objectToString.call(value) == symbolTag);
+  }
+
+  /**
+   * Converts `value` to a number.
+   *
+   * @static
+   * @memberOf _
+   * @since 4.0.0
+   * @category Lang
+   * @param {*} value The value to process.
+   * @returns {number} Returns the number.
+   * @example
+   *
+   * _.toNumber(3.2);
+   * // => 3.2
+   *
+   * _.toNumber(Number.MIN_VALUE);
+   * // => 5e-324
+   *
+   * _.toNumber(Infinity);
+   * // => Infinity
+   *
+   * _.toNumber('3.2');
+   * // => 3.2
+   */
+  function toNumber(value) {
+    if (typeof value == 'number') {
+      return value;
+    }
+    if (isSymbol(value)) {
+      return NAN;
+    }
+    if (isObject(value)) {
+      var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
+      value = isObject(other) ? (other + '') : other;
+    }
+    if (typeof value != 'string') {
+      return value === 0 ? value : +value;
+    }
+    value = value.replace(reTrim, '');
+    var isBinary = reIsBinary.test(value);
+    return (isBinary || reIsOctal.test(value))
+      ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
+      : (reIsBadHex.test(value) ? NAN : +value);
+  }
+
+  var lodash_throttle = throttle;
+
+  /**
+   * lodash (Custom Build) <https://lodash.com/>
+   * Build: `lodash modularize exports="npm" -o ./`
+   * Copyright jQuery Foundation and other contributors <https://jquery.org/>
+   * Released under MIT license <https://lodash.com/license>
+   * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
+   * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+   */
+
+  /** Used as the `TypeError` message for "Functions" methods. */
+  var FUNC_ERROR_TEXT$1 = 'Expected a function';
+
+  /** Used as references for various `Number` constants. */
+  var NAN$1 = 0 / 0;
+
+  /** `Object#toString` result references. */
+  var symbolTag$1 = '[object Symbol]';
+
+  /** Used to match leading and trailing whitespace. */
+  var reTrim$1 = /^\s+|\s+$/g;
+
+  /** Used to detect bad signed hexadecimal string values. */
+  var reIsBadHex$1 = /^[-+]0x[0-9a-f]+$/i;
+
+  /** Used to detect binary string values. */
+  var reIsBinary$1 = /^0b[01]+$/i;
+
+  /** Used to detect octal string values. */
+  var reIsOctal$1 = /^0o[0-7]+$/i;
+
+  /** Built-in method references without a dependency on `root`. */
+  var freeParseInt$1 = parseInt;
+
+  /** Detect free variable `global` from Node.js. */
+  var freeGlobal$1 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
+
+  /** Detect free variable `self`. */
+  var freeSelf$1 = typeof self == 'object' && self && self.Object === Object && self;
+
+  /** Used as a reference to the global object. */
+  var root$1 = freeGlobal$1 || freeSelf$1 || Function('return this')();
+
+  /** Used for built-in method references. */
+  var objectProto$1 = Object.prototype;
+
+  /**
+   * Used to resolve the
+   * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
+   * of values.
+   */
+  var objectToString$1 = objectProto$1.toString;
+
+  /* Built-in method references for those with the same name as other `lodash` methods. */
+  var nativeMax$1 = Math.max,
+      nativeMin$1 = Math.min;
+
+  /**
+   * Gets the timestamp of the number of milliseconds that have elapsed since
+   * the Unix epoch (1 January 1970 00:00:00 UTC).
+   *
+   * @static
+   * @memberOf _
+   * @since 2.4.0
+   * @category Date
+   * @returns {number} Returns the timestamp.
+   * @example
+   *
+   * _.defer(function(stamp) {
+   *   console.log(_.now() - stamp);
+   * }, _.now());
+   * // => Logs the number of milliseconds it took for the deferred invocation.
+   */
+  var now$1 = function() {
+    return root$1.Date.now();
+  };
+
+  /**
+   * Creates a debounced function that delays invoking `func` until after `wait`
+   * milliseconds have elapsed since the last time the debounced function was
+   * invoked. The debounced function comes with a `cancel` method to cancel
+   * delayed `func` invocations and a `flush` method to immediately invoke them.
+   * Provide `options` to indicate whether `func` should be invoked on the
+   * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
+   * with the last arguments provided to the debounced function. Subsequent
+   * calls to the debounced function return the result of the last `func`
+   * invocation.
+   *
+   * **Note:** If `leading` and `trailing` options are `true`, `func` is
+   * invoked on the trailing edge of the timeout only if the debounced function
+   * is invoked more than once during the `wait` timeout.
+   *
+   * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
+   * until to the next tick, similar to `setTimeout` with a timeout of `0`.
+   *
+   * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
+   * for details over the differences between `_.debounce` and `_.throttle`.
+   *
+   * @static
+   * @memberOf _
+   * @since 0.1.0
+   * @category Function
+   * @param {Function} func The function to debounce.
+   * @param {number} [wait=0] The number of milliseconds to delay.
+   * @param {Object} [options={}] The options object.
+   * @param {boolean} [options.leading=false]
+   *  Specify invoking on the leading edge of the timeout.
+   * @param {number} [options.maxWait]
+   *  The maximum time `func` is allowed to be delayed before it's invoked.
+   * @param {boolean} [options.trailing=true]
+   *  Specify invoking on the trailing edge of the timeout.
+   * @returns {Function} Returns the new debounced function.
+   * @example
+   *
+   * // Avoid costly calculations while the window size is in flux.
+   * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
+   *
+   * // Invoke `sendMail` when clicked, debouncing subsequent calls.
+   * jQuery(element).on('click', _.debounce(sendMail, 300, {
+   *   'leading': true,
+   *   'trailing': false
+   * }));
+   *
+   * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
+   * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
+   * var source = new EventSource('/stream');
+   * jQuery(source).on('message', debounced);
+   *
+   * // Cancel the trailing debounced invocation.
+   * jQuery(window).on('popstate', debounced.cancel);
+   */
+  function debounce$1(func, wait, options) {
+    var lastArgs,
+        lastThis,
+        maxWait,
+        result,
+        timerId,
+        lastCallTime,
+        lastInvokeTime = 0,
+        leading = false,
+        maxing = false,
+        trailing = true;
+
+    if (typeof func != 'function') {
+      throw new TypeError(FUNC_ERROR_TEXT$1);
+    }
+    wait = toNumber$1(wait) || 0;
+    if (isObject$1(options)) {
+      leading = !!options.leading;
+      maxing = 'maxWait' in options;
+      maxWait = maxing ? nativeMax$1(toNumber$1(options.maxWait) || 0, wait) : maxWait;
+      trailing = 'trailing' in options ? !!options.trailing : trailing;
+    }
+
+    function invokeFunc(time) {
+      var args = lastArgs,
+          thisArg = lastThis;
+
+      lastArgs = lastThis = undefined;
+      lastInvokeTime = time;
+      result = func.apply(thisArg, args);
+      return result;
+    }
+
+    function leadingEdge(time) {
+      // Reset any `maxWait` timer.
+      lastInvokeTime = time;
+      // Start the timer for the trailing edge.
+      timerId = setTimeout(timerExpired, wait);
+      // Invoke the leading edge.
+      return leading ? invokeFunc(time) : result;
+    }
+
+    function remainingWait(time) {
+      var timeSinceLastCall = time - lastCallTime,
+          timeSinceLastInvoke = time - lastInvokeTime,
+          result = wait - timeSinceLastCall;
+
+      return maxing ? nativeMin$1(result, maxWait - timeSinceLastInvoke) : result;
+    }
+
+    function shouldInvoke(time) {
+      var timeSinceLastCall = time - lastCallTime,
+          timeSinceLastInvoke = time - lastInvokeTime;
+
+      // Either this is the first call, activity has stopped and we're at the
+      // trailing edge, the system time has gone backwards and we're treating
+      // it as the trailing edge, or we've hit the `maxWait` limit.
+      return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
+        (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
+    }
+
+    function timerExpired() {
+      var time = now$1();
+      if (shouldInvoke(time)) {
+        return trailingEdge(time);
+      }
+      // Restart the timer.
+      timerId = setTimeout(timerExpired, remainingWait(time));
+    }
+
+    function trailingEdge(time) {
+      timerId = undefined;
+
+      // Only invoke if we have `lastArgs` which means `func` has been
+      // debounced at least once.
+      if (trailing && lastArgs) {
+        return invokeFunc(time);
+      }
+      lastArgs = lastThis = undefined;
+      return result;
+    }
+
+    function cancel() {
+      if (timerId !== undefined) {
+        clearTimeout(timerId);
+      }
+      lastInvokeTime = 0;
+      lastArgs = lastCallTime = lastThis = timerId = undefined;
+    }
+
+    function flush() {
+      return timerId === undefined ? result : trailingEdge(now$1());
+    }
+
+    function debounced() {
+      var time = now$1(),
+          isInvoking = shouldInvoke(time);
+
+      lastArgs = arguments;
+      lastThis = this;
+      lastCallTime = time;
+
+      if (isInvoking) {
+        if (timerId === undefined) {
+          return leadingEdge(lastCallTime);
+        }
+        if (maxing) {
+          // Handle invocations in a tight loop.
+          timerId = setTimeout(timerExpired, wait);
+          return invokeFunc(lastCallTime);
+        }
+      }
+      if (timerId === undefined) {
+        timerId = setTimeout(timerExpired, wait);
+      }
+      return result;
+    }
+    debounced.cancel = cancel;
+    debounced.flush = flush;
+    return debounced;
+  }
+
+  /**
+   * Checks if `value` is the
+   * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
+   * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+   *
+   * @static
+   * @memberOf _
+   * @since 0.1.0
+   * @category Lang
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+   * @example
+   *
+   * _.isObject({});
+   * // => true
+   *
+   * _.isObject([1, 2, 3]);
+   * // => true
+   *
+   * _.isObject(_.noop);
+   * // => true
+   *
+   * _.isObject(null);
+   * // => false
+   */
+  function isObject$1(value) {
+    var type = typeof value;
+    return !!value && (type == 'object' || type == 'function');
+  }
+
+  /**
+   * Checks if `value` is object-like. A value is object-like if it's not `null`
+   * and has a `typeof` result of "object".
+   *
+   * @static
+   * @memberOf _
+   * @since 4.0.0
+   * @category Lang
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+   * @example
+   *
+   * _.isObjectLike({});
+   * // => true
+   *
+   * _.isObjectLike([1, 2, 3]);
+   * // => true
+   *
+   * _.isObjectLike(_.noop);
+   * // => false
+   *
+   * _.isObjectLike(null);
+   * // => false
+   */
+  function isObjectLike$1(value) {
+    return !!value && typeof value == 'object';
+  }
+
+  /**
+   * Checks if `value` is classified as a `Symbol` primitive or object.
+   *
+   * @static
+   * @memberOf _
+   * @since 4.0.0
+   * @category Lang
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
+   * @example
+   *
+   * _.isSymbol(Symbol.iterator);
+   * // => true
+   *
+   * _.isSymbol('abc');
+   * // => false
+   */
+  function isSymbol$1(value) {
+    return typeof value == 'symbol' ||
+      (isObjectLike$1(value) && objectToString$1.call(value) == symbolTag$1);
+  }
+
+  /**
+   * Converts `value` to a number.
+   *
+   * @static
+   * @memberOf _
+   * @since 4.0.0
+   * @category Lang
+   * @param {*} value The value to process.
+   * @returns {number} Returns the number.
+   * @example
+   *
+   * _.toNumber(3.2);
+   * // => 3.2
+   *
+   * _.toNumber(Number.MIN_VALUE);
+   * // => 5e-324
+   *
+   * _.toNumber(Infinity);
+   * // => Infinity
+   *
+   * _.toNumber('3.2');
+   * // => 3.2
+   */
+  function toNumber$1(value) {
+    if (typeof value == 'number') {
+      return value;
+    }
+    if (isSymbol$1(value)) {
+      return NAN$1;
+    }
+    if (isObject$1(value)) {
+      var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
+      value = isObject$1(other) ? (other + '') : other;
+    }
+    if (typeof value != 'string') {
+      return value === 0 ? value : +value;
+    }
+    value = value.replace(reTrim$1, '');
+    var isBinary = reIsBinary$1.test(value);
+    return (isBinary || reIsOctal$1.test(value))
+      ? freeParseInt$1(value.slice(2), isBinary ? 2 : 8)
+      : (reIsBadHex$1.test(value) ? NAN$1 : +value);
+  }
+
+  var lodash_debounce = debounce$1;
+
+  /**
+   * lodash (Custom Build) <https://lodash.com/>
+   * Build: `lodash modularize exports="npm" -o ./`
+   * Copyright jQuery Foundation and other contributors <https://jquery.org/>
+   * Released under MIT license <https://lodash.com/license>
+   * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
+   * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+   */
+
+  /** Used as the `TypeError` message for "Functions" methods. */
+  var FUNC_ERROR_TEXT$2 = 'Expected a function';
+
+  /** Used to stand-in for `undefined` hash values. */
+  var HASH_UNDEFINED = '__lodash_hash_undefined__';
+
+  /** `Object#toString` result references. */
+  var funcTag = '[object Function]',
+      genTag = '[object GeneratorFunction]';
+
+  /**
+   * Used to match `RegExp`
+   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
+   */
+  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
+
+  /** Used to detect host constructors (Safari). */
+  var reIsHostCtor = /^\[object .+?Constructor\]$/;
+
+  /** Detect free variable `global` from Node.js. */
+  var freeGlobal$2 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
+
+  /** Detect free variable `self`. */
+  var freeSelf$2 = typeof self == 'object' && self && self.Object === Object && self;
+
+  /** Used as a reference to the global object. */
+  var root$2 = freeGlobal$2 || freeSelf$2 || Function('return this')();
+
+  /**
+   * Gets the value at `key` of `object`.
+   *
+   * @private
+   * @param {Object} [object] The object to query.
+   * @param {string} key The key of the property to get.
+   * @returns {*} Returns the property value.
+   */
+  function getValue(object, key) {
+    return object == null ? undefined : object[key];
+  }
+
+  /**
+   * Checks if `value` is a host object in IE < 9.
+   *
+   * @private
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
+   */
+  function isHostObject(value) {
+    // Many host objects are `Object` objects that can coerce to strings
+    // despite having improperly defined `toString` methods.
+    var result = false;
+    if (value != null && typeof value.toString != 'function') {
+      try {
+        result = !!(value + '');
+      } catch (e) {}
+    }
+    return result;
+  }
+
+  /** Used for built-in method references. */
+  var arrayProto = Array.prototype,
+      funcProto = Function.prototype,
+      objectProto$2 = Object.prototype;
+
+  /** Used to detect overreaching core-js shims. */
+  var coreJsData = root$2['__core-js_shared__'];
+
+  /** Used to detect methods masquerading as native. */
+  var maskSrcKey = (function() {
+    var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
+    return uid ? ('Symbol(src)_1.' + uid) : '';
+  }());
+
+  /** Used to resolve the decompiled source of functions. */
+  var funcToString = funcProto.toString;
+
+  /** Used to check objects for own properties. */
+  var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
+
+  /**
+   * Used to resolve the
+   * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
+   * of values.
+   */
+  var objectToString$2 = objectProto$2.toString;
+
+  /** Used to detect if a method is native. */
+  var reIsNative = RegExp('^' +
+    funcToString.call(hasOwnProperty$1).replace(reRegExpChar, '\\$&')
+    .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+  );
+
+  /** Built-in value references. */
+  var splice = arrayProto.splice;
+
+  /* Built-in method references that are verified to be native. */
+  var Map$1 = getNative(root$2, 'Map'),
+      nativeCreate = getNative(Object, 'create');
+
+  /**
+   * Creates a hash object.
+   *
+   * @private
+   * @constructor
+   * @param {Array} [entries] The key-value pairs to cache.
+   */
+  function Hash(entries) {
+    var index = -1,
+        length = entries ? entries.length : 0;
+
+    this.clear();
+    while (++index < length) {
+      var entry = entries[index];
+      this.set(entry[0], entry[1]);
+    }
+  }
+
+  /**
+   * Removes all key-value entries from the hash.
+   *
+   * @private
+   * @name clear
+   * @memberOf Hash
+   */
+  function hashClear() {
+    this.__data__ = nativeCreate ? nativeCreate(null) : {};
+  }
+
+  /**
+   * Removes `key` and its value from the hash.
+   *
+   * @private
+   * @name delete
+   * @memberOf Hash
+   * @param {Object} hash The hash to modify.
+   * @param {string} key The key of the value to remove.
+   * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+   */
+  function hashDelete(key) {
+    return this.has(key) && delete this.__data__[key];
+  }
+
+  /**
+   * Gets the hash value for `key`.
+   *
+   * @private
+   * @name get
+   * @memberOf Hash
+   * @param {string} key The key of the value to get.
+   * @returns {*} Returns the entry value.
+   */
+  function hashGet(key) {
+    var data = this.__data__;
+    if (nativeCreate) {
+      var result = data[key];
+      return result === HASH_UNDEFINED ? undefined : result;
+    }
+    return hasOwnProperty$1.call(data, key) ? data[key] : undefined;
+  }
+
+  /**
+   * Checks if a hash value for `key` exists.
+   *
+   * @private
+   * @name has
+   * @memberOf Hash
+   * @param {string} key The key of the entry to check.
+   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+   */
+  function hashHas(key) {
+    var data = this.__data__;
+    return nativeCreate ? data[key] !== undefined : hasOwnProperty$1.call(data, key);
+  }
+
+  /**
+   * Sets the hash `key` to `value`.
+   *
+   * @private
+   * @name set
+   * @memberOf Hash
+   * @param {string} key The key of the value to set.
+   * @param {*} value The value to set.
+   * @returns {Object} Returns the hash instance.
+   */
+  function hashSet(key, value) {
+    var data = this.__data__;
+    data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
+    return this;
+  }
+
+  // Add methods to `Hash`.
+  Hash.prototype.clear = hashClear;
+  Hash.prototype['delete'] = hashDelete;
+  Hash.prototype.get = hashGet;
+  Hash.prototype.has = hashHas;
+  Hash.prototype.set = hashSet;
+
+  /**
+   * Creates an list cache object.
+   *
+   * @private
+   * @constructor
+   * @param {Array} [entries] The key-value pairs to cache.
+   */
+  function ListCache(entries) {
+    var index = -1,
+        length = entries ? entries.length : 0;
+
+    this.clear();
+    while (++index < length) {
+      var entry = entries[index];
+      this.set(entry[0], entry[1]);
+    }
+  }
+
+  /**
+   * Removes all key-value entries from the list cache.
+   *
+   * @private
+   * @name clear
+   * @memberOf ListCache
+   */
+  function listCacheClear() {
+    this.__data__ = [];
+  }
+
+  /**
+   * Removes `key` and its value from the list cache.
+   *
+   * @private
+   * @name delete
+   * @memberOf ListCache
+   * @param {string} key The key of the value to remove.
+   * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+   */
+  function listCacheDelete(key) {
+    var data = this.__data__,
+        index = assocIndexOf(data, key);
+
+    if (index < 0) {
+      return false;
+    }
+    var lastIndex = data.length - 1;
+    if (index == lastIndex) {
+      data.pop();
+    } else {
+      splice.call(data, index, 1);
+    }
+    return true;
+  }
+
+  /**
+   * Gets the list cache value for `key`.
+   *
+   * @private
+   * @name get
+   * @memberOf ListCache
+   * @param {string} key The key of the value to get.
+   * @returns {*} Returns the entry value.
+   */
+  function listCacheGet(key) {
+    var data = this.__data__,
+        index = assocIndexOf(data, key);
+
+    return index < 0 ? undefined : data[index][1];
+  }
+
+  /**
+   * Checks if a list cache value for `key` exists.
+   *
+   * @private
+   * @name has
+   * @memberOf ListCache
+   * @param {string} key The key of the entry to check.
+   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+   */
+  function listCacheHas(key) {
+    return assocIndexOf(this.__data__, key) > -1;
+  }
+
+  /**
+   * Sets the list cache `key` to `value`.
+   *
+   * @private
+   * @name set
+   * @memberOf ListCache
+   * @param {string} key The key of the value to set.
+   * @param {*} value The value to set.
+   * @returns {Object} Returns the list cache instance.
+   */
+  function listCacheSet(key, value) {
+    var data = this.__data__,
+        index = assocIndexOf(data, key);
+
+    if (index < 0) {
+      data.push([key, value]);
+    } else {
+      data[index][1] = value;
+    }
+    return this;
+  }
+
+  // Add methods to `ListCache`.
+  ListCache.prototype.clear = listCacheClear;
+  ListCache.prototype['delete'] = listCacheDelete;
+  ListCache.prototype.get = listCacheGet;
+  ListCache.prototype.has = listCacheHas;
+  ListCache.prototype.set = listCacheSet;
+
+  /**
+   * Creates a map cache object to store key-value pairs.
+   *
+   * @private
+   * @constructor
+   * @param {Array} [entries] The key-value pairs to cache.
+   */
+  function MapCache(entries) {
+    var index = -1,
+        length = entries ? entries.length : 0;
+
+    this.clear();
+    while (++index < length) {
+      var entry = entries[index];
+      this.set(entry[0], entry[1]);
+    }
+  }
+
+  /**
+   * Removes all key-value entries from the map.
+   *
+   * @private
+   * @name clear
+   * @memberOf MapCache
+   */
+  function mapCacheClear() {
+    this.__data__ = {
+      'hash': new Hash,
+      'map': new (Map$1 || ListCache),
+      'string': new Hash
+    };
+  }
+
+  /**
+   * Removes `key` and its value from the map.
+   *
+   * @private
+   * @name delete
+   * @memberOf MapCache
+   * @param {string} key The key of the value to remove.
+   * @returns {boolean} Returns `true` if the entry was removed, else `false`.
+   */
+  function mapCacheDelete(key) {
+    return getMapData(this, key)['delete'](key);
+  }
+
+  /**
+   * Gets the map value for `key`.
+   *
+   * @private
+   * @name get
+   * @memberOf MapCache
+   * @param {string} key The key of the value to get.
+   * @returns {*} Returns the entry value.
+   */
+  function mapCacheGet(key) {
+    return getMapData(this, key).get(key);
+  }
+
+  /**
+   * Checks if a map value for `key` exists.
+   *
+   * @private
+   * @name has
+   * @memberOf MapCache
+   * @param {string} key The key of the entry to check.
+   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
+   */
+  function mapCacheHas(key) {
+    return getMapData(this, key).has(key);
+  }
+
+  /**
+   * Sets the map `key` to `value`.
+   *
+   * @private
+   * @name set
+   * @memberOf MapCache
+   * @param {string} key The key of the value to set.
+   * @param {*} value The value to set.
+   * @returns {Object} Returns the map cache instance.
+   */
+  function mapCacheSet(key, value) {
+    getMapData(this, key).set(key, value);
+    return this;
+  }
+
+  // Add methods to `MapCache`.
+  MapCache.prototype.clear = mapCacheClear;
+  MapCache.prototype['delete'] = mapCacheDelete;
+  MapCache.prototype.get = mapCacheGet;
+  MapCache.prototype.has = mapCacheHas;
+  MapCache.prototype.set = mapCacheSet;
+
+  /**
+   * Gets the index at which the `key` is found in `array` of key-value pairs.
+   *
+   * @private
+   * @param {Array} array The array to inspect.
+   * @param {*} key The key to search for.
+   * @returns {number} Returns the index of the matched value, else `-1`.
+   */
+  function assocIndexOf(array, key) {
+    var length = array.length;
+    while (length--) {
+      if (eq(array[length][0], key)) {
+        return length;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * The base implementation of `_.isNative` without bad shim checks.
+   *
+   * @private
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is a native function,
+   *  else `false`.
+   */
+  function baseIsNative(value) {
+    if (!isObject$2(value) || isMasked(value)) {
+      return false;
+    }
+    var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
+    return pattern.test(toSource(value));
+  }
+
+  /**
+   * Gets the data for `map`.
+   *
+   * @private
+   * @param {Object} map The map to query.
+   * @param {string} key The reference key.
+   * @returns {*} Returns the map data.
+   */
+  function getMapData(map, key) {
+    var data = map.__data__;
+    return isKeyable(key)
+      ? data[typeof key == 'string' ? 'string' : 'hash']
+      : data.map;
+  }
+
+  /**
+   * Gets the native function at `key` of `object`.
+   *
+   * @private
+   * @param {Object} object The object to query.
+   * @param {string} key The key of the method to get.
+   * @returns {*} Returns the function if it's native, else `undefined`.
+   */
+  function getNative(object, key) {
+    var value = getValue(object, key);
+    return baseIsNative(value) ? value : undefined;
+  }
+
+  /**
+   * Checks if `value` is suitable for use as unique object key.
+   *
+   * @private
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
+   */
+  function isKeyable(value) {
+    var type = typeof value;
+    return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
+      ? (value !== '__proto__')
+      : (value === null);
+  }
+
+  /**
+   * Checks if `func` has its source masked.
+   *
+   * @private
+   * @param {Function} func The function to check.
+   * @returns {boolean} Returns `true` if `func` is masked, else `false`.
+   */
+  function isMasked(func) {
+    return !!maskSrcKey && (maskSrcKey in func);
+  }
+
+  /**
+   * Converts `func` to its source code.
+   *
+   * @private
+   * @param {Function} func The function to process.
+   * @returns {string} Returns the source code.
+   */
+  function toSource(func) {
+    if (func != null) {
+      try {
+        return funcToString.call(func);
+      } catch (e) {}
+      try {
+        return (func + '');
+      } catch (e) {}
+    }
+    return '';
+  }
+
+  /**
+   * Creates a function that memoizes the result of `func`. If `resolver` is
+   * provided, it determines the cache key for storing the result based on the
+   * arguments provided to the memoized function. By default, the first argument
+   * provided to the memoized function is used as the map cache key. The `func`
+   * is invoked with the `this` binding of the memoized function.
+   *
+   * **Note:** The cache is exposed as the `cache` property on the memoized
+   * function. Its creation may be customized by replacing the `_.memoize.Cache`
+   * constructor with one whose instances implement the
+   * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
+   * method interface of `delete`, `get`, `has`, and `set`.
+   *
+   * @static
+   * @memberOf _
+   * @since 0.1.0
+   * @category Function
+   * @param {Function} func The function to have its output memoized.
+   * @param {Function} [resolver] The function to resolve the cache key.
+   * @returns {Function} Returns the new memoized function.
+   * @example
+   *
+   * var object = { 'a': 1, 'b': 2 };
+   * var other = { 'c': 3, 'd': 4 };
+   *
+   * var values = _.memoize(_.values);
+   * values(object);
+   * // => [1, 2]
+   *
+   * values(other);
+   * // => [3, 4]
+   *
+   * object.a = 2;
+   * values(object);
+   * // => [1, 2]
+   *
+   * // Modify the result cache.
+   * values.cache.set(object, ['a', 'b']);
+   * values(object);
+   * // => ['a', 'b']
+   *
+   * // Replace `_.memoize.Cache`.
+   * _.memoize.Cache = WeakMap;
+   */
+  function memoize(func, resolver) {
+    if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
+      throw new TypeError(FUNC_ERROR_TEXT$2);
+    }
+    var memoized = function() {
+      var args = arguments,
+          key = resolver ? resolver.apply(this, args) : args[0],
+          cache = memoized.cache;
+
+      if (cache.has(key)) {
+        return cache.get(key);
+      }
+      var result = func.apply(this, args);
+      memoized.cache = cache.set(key, result);
+      return result;
+    };
+    memoized.cache = new (memoize.Cache || MapCache);
+    return memoized;
+  }
+
+  // Assign cache to `_.memoize`.
+  memoize.Cache = MapCache;
+
+  /**
+   * Performs a
+   * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
+   * comparison between two values to determine if they are equivalent.
+   *
+   * @static
+   * @memberOf _
+   * @since 4.0.0
+   * @category Lang
+   * @param {*} value The value to compare.
+   * @param {*} other The other value to compare.
+   * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
+   * @example
+   *
+   * var object = { 'a': 1 };
+   * var other = { 'a': 1 };
+   *
+   * _.eq(object, object);
+   * // => true
+   *
+   * _.eq(object, other);
+   * // => false
+   *
+   * _.eq('a', 'a');
+   * // => true
+   *
+   * _.eq('a', Object('a'));
+   * // => false
+   *
+   * _.eq(NaN, NaN);
+   * // => true
+   */
+  function eq(value, other) {
+    return value === other || (value !== value && other !== other);
+  }
+
+  /**
+   * Checks if `value` is classified as a `Function` object.
+   *
+   * @static
+   * @memberOf _
+   * @since 0.1.0
+   * @category Lang
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is a function, else `false`.
+   * @example
+   *
+   * _.isFunction(_);
+   * // => true
+   *
+   * _.isFunction(/abc/);
+   * // => false
+   */
+  function isFunction(value) {
+    // The use of `Object#toString` avoids issues with the `typeof` operator
+    // in Safari 8-9 which returns 'object' for typed array and other constructors.
+    var tag = isObject$2(value) ? objectToString$2.call(value) : '';
+    return tag == funcTag || tag == genTag;
+  }
+
+  /**
+   * Checks if `value` is the
+   * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
+   * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+   *
+   * @static
+   * @memberOf _
+   * @since 0.1.0
+   * @category Lang
+   * @param {*} value The value to check.
+   * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+   * @example
+   *
+   * _.isObject({});
+   * // => true
+   *
+   * _.isObject([1, 2, 3]);
+   * // => true
+   *
+   * _.isObject(_.noop);
+   * // => true
+   *
+   * _.isObject(null);
+   * // => false
+   */
+  function isObject$2(value) {
+    var type = typeof value;
+    return !!value && (type == 'object' || type == 'function');
+  }
+
+  var lodash_memoize = memoize;
+
+  /**
+   * A collection of shims that provide minimal functionality of the ES6 collections.
+   *
+   * These implementations are not meant to be used outside of the ResizeObserver
+   * modules as they cover only a limited range of use cases.
+   */
+  /* eslint-disable require-jsdoc, valid-jsdoc */
+  var MapShim = (function () {
+      if (typeof Map !== 'undefined') {
+          return Map;
+      }
+
+      /**
+       * Returns index in provided array that matches the specified key.
+       *
+       * @param {Array<Array>} arr
+       * @param {*} key
+       * @returns {number}
+       */
+      function getIndex(arr, key) {
+          var result = -1;
+
+          arr.some(function (entry, index) {
+              if (entry[0] === key) {
+                  result = index;
+
+                  return true;
+              }
+
+              return false;
+          });
+
+          return result;
+      }
+
+      return (function () {
+          function anonymous() {
+              this.__entries__ = [];
+          }
+
+          var prototypeAccessors = { size: { configurable: true } };
+
+          /**
+           * @returns {boolean}
+           */
+          prototypeAccessors.size.get = function () {
+              return this.__entries__.length;
+          };
+
+          /**
+           * @param {*} key
+           * @returns {*}
+           */
+          anonymous.prototype.get = function (key) {
+              var index = getIndex(this.__entries__, key);
+              var entry = this.__entries__[index];
+
+              return entry && entry[1];
+          };
+
+          /**
+           * @param {*} key
+           * @param {*} value
+           * @returns {void}
+           */
+          anonymous.prototype.set = function (key, value) {
+              var index = getIndex(this.__entries__, key);
+
+              if (~index) {
+                  this.__entries__[index][1] = value;
+              } else {
+                  this.__entries__.push([key, value]);
+              }
+          };
+
+          /**
+           * @param {*} key
+           * @returns {void}
+           */
+          anonymous.prototype.delete = function (key) {
+              var entries = this.__entries__;
+              var index = getIndex(entries, key);
+
+              if (~index) {
+                  entries.splice(index, 1);
+              }
+          };
+
+          /**
+           * @param {*} key
+           * @returns {void}
+           */
+          anonymous.prototype.has = function (key) {
+              return !!~getIndex(this.__entries__, key);
+          };
+
+          /**
+           * @returns {void}
+           */
+          anonymous.prototype.clear = function () {
+              this.__entries__.splice(0);
+          };
+
+          /**
+           * @param {Function} callback
+           * @param {*} [ctx=null]
+           * @returns {void}
+           */
+          anonymous.prototype.forEach = function (callback, ctx) {
+              var this$1 = this;
+              if ( ctx === void 0 ) ctx = null;
+
+              for (var i = 0, list = this$1.__entries__; i < list.length; i += 1) {
+                  var entry = list[i];
+
+                  callback.call(ctx, entry[1], entry[0]);
+              }
+          };
+
+          Object.defineProperties( anonymous.prototype, prototypeAccessors );
+
+          return anonymous;
+      }());
+  })();
+
+  /**
+   * Detects whether window and document objects are available in current environment.
+   */
+  var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && window.document === document;
+
+  // Returns global object of a current environment.
+  var global$1 = (function () {
+      if (typeof global !== 'undefined' && global.Math === Math) {
+          return global;
+      }
+
+      if (typeof self !== 'undefined' && self.Math === Math) {
+          return self;
+      }
+
+      if (typeof window !== 'undefined' && window.Math === Math) {
+          return window;
+      }
+
+      // eslint-disable-next-line no-new-func
+      return Function('return this')();
+  })();
+
+  /**
+   * A shim for the requestAnimationFrame which falls back to the setTimeout if
+   * first one is not supported.
+   *
+   * @returns {number} Requests' identifier.
+   */
+  var requestAnimationFrame$1 = (function () {
+      if (typeof requestAnimationFrame === 'function') {
+          // It's required to use a bounded function because IE sometimes throws
+          // an "Invalid calling object" error if rAF is invoked without the global
+          // object on the left hand side.
+          return requestAnimationFrame.bind(global$1);
+      }
+
+      return function (callback) { return setTimeout(function () { return callback(Date.now()); }, 1000 / 60); };
+  })();
+
+  // Defines minimum timeout before adding a trailing call.
+  var trailingTimeout = 2;
+
+  /**
+   * Creates a wrapper function which ensures that provided callback will be
+   * invoked only once during the specified delay period.
+   *
+   * @param {Function} callback - Function to be invoked after the delay period.
+   * @param {number} delay - Delay after which to invoke callback.
+   * @returns {Function}
+   */
+  var throttle$1 = function (callback, delay) {
+      var leadingCall = false,
+          trailingCall = false,
+          lastCallTime = 0;
+
+      /**
+       * Invokes the original callback function and schedules new invocation if
+       * the "proxy" was called during current request.
+       *
+       * @returns {void}
+       */
+      function resolvePending() {
+          if (leadingCall) {
+              leadingCall = false;
+
+              callback();
+          }
+
+          if (trailingCall) {
+              proxy();
+          }
+      }
+
+      /**
+       * Callback invoked after the specified delay. It will further postpone
+       * invocation of the original function delegating it to the
+       * requestAnimationFrame.
+       *
+       * @returns {void}
+       */
+      function timeoutCallback() {
+          requestAnimationFrame$1(resolvePending);
+      }
+
+      /**
+       * Schedules invocation of the original function.
+       *
+       * @returns {void}
+       */
+      function proxy() {
+          var timeStamp = Date.now();
+
+          if (leadingCall) {
+              // Reject immediately following calls.
+              if (timeStamp - lastCallTime < trailingTimeout) {
+                  return;
+              }
+
+              // Schedule new call to be in invoked when the pending one is resolved.
+              // This is important for "transitions" which never actually start
+              // immediately so there is a chance that we might miss one if change
+              // happens amids the pending invocation.
+              trailingCall = true;
+          } else {
+              leadingCall = true;
+              trailingCall = false;
+
+              setTimeout(timeoutCallback, delay);
+          }
+
+          lastCallTime = timeStamp;
+      }
+
+      return proxy;
+  };
+
+  // Minimum delay before invoking the update of observers.
+  var REFRESH_DELAY = 20;
+
+  // A list of substrings of CSS properties used to find transition events that
+  // might affect dimensions of observed elements.
+  var transitionKeys = ['top', 'right', 'bottom', 'left', 'width', 'height', 'size', 'weight'];
+
+  // Check if MutationObserver is available.
+  var mutationObserverSupported = typeof MutationObserver !== 'undefined';
+
+  /**
+   * Singleton controller class which handles updates of ResizeObserver instances.
+   */
+  var ResizeObserverController = function() {
+      this.connected_ = false;
+      this.mutationEventsAdded_ = false;
+      this.mutationsObserver_ = null;
+      this.observers_ = [];
+
+      this.onTransitionEnd_ = this.onTransitionEnd_.bind(this);
+      this.refresh = throttle$1(this.refresh.bind(this), REFRESH_DELAY);
+  };
+
+  /**
+   * Adds observer to observers list.
+   *
+   * @param {ResizeObserverSPI} observer - Observer to be added.
+   * @returns {void}
+   */
+
+
+  /**
+   * Holds reference to the controller's instance.
+   *
+   * @private {ResizeObserverController}
+   */
+
+
+  /**
+   * Keeps reference to the instance of MutationObserver.
+   *
+   * @private {MutationObserver}
+   */
+
+  /**
+   * Indicates whether DOM listeners have been added.
+   *
+   * @private {boolean}
+   */
+  ResizeObserverController.prototype.addObserver = function (observer) {
+      if (!~this.observers_.indexOf(observer)) {
+          this.observers_.push(observer);
+      }
+
+      // Add listeners if they haven't been added yet.
+      if (!this.connected_) {
+          this.connect_();
+      }
+  };
+
+  /**
+   * Removes observer from observers list.
+   *
+   * @param {ResizeObserverSPI} observer - Observer to be removed.
+   * @returns {void}
+   */
+  ResizeObserverController.prototype.removeObserver = function (observer) {
+      var observers = this.observers_;
+      var index = observers.indexOf(observer);
+
+      // Remove observer if it's present in registry.
+      if (~index) {
+          observers.splice(index, 1);
+      }
+
+      // Remove listeners if controller has no connected observers.
+      if (!observers.length && this.connected_) {
+          this.disconnect_();
+      }
+  };
+
+  /**
+   * Invokes the update of observers. It will continue running updates insofar
+   * it detects changes.
+   *
+   * @returns {void}
+   */
+  ResizeObserverController.prototype.refresh = function () {
+      var changesDetected = this.updateObservers_();
+
+      // Continue running updates if changes have been detected as there might
+      // be future ones caused by CSS transitions.
+      if (changesDetected) {
+          this.refresh();
+      }
+  };
+
+  /**
+   * Updates every observer from observers list and notifies them of queued
+   * entries.
+   *
+   * @private
+   * @returns {boolean} Returns "true" if any observer has detected changes in
+   *  dimensions of it's elements.
+   */
+  ResizeObserverController.prototype.updateObservers_ = function () {
+      // Collect observers that have active observations.
+      var activeObservers = this.observers_.filter(function (observer) {
+          return observer.gatherActive(), observer.hasActive();
+      });
+
+      // Deliver notifications in a separate cycle in order to avoid any
+      // collisions between observers, e.g. when multiple instances of
+      // ResizeObserver are tracking the same element and the callback of one
+      // of them changes content dimensions of the observed target. Sometimes
+      // this may result in notifications being blocked for the rest of observers.
+      activeObservers.forEach(function (observer) { return observer.broadcastActive(); });
+
+      return activeObservers.length > 0;
+  };
+
+  /**
+   * Initializes DOM listeners.
+   *
+   * @private
+   * @returns {void}
+   */
+  ResizeObserverController.prototype.connect_ = function () {
+      // Do nothing if running in a non-browser environment or if listeners
+      // have been already added.
+      if (!isBrowser || this.connected_) {
+          return;
+      }
+
+      // Subscription to the "Transitionend" event is used as a workaround for
+      // delayed transitions. This way it's possible to capture at least the
+      // final state of an element.
+      document.addEventListener('transitionend', this.onTransitionEnd_);
+
+      window.addEventListener('resize', this.refresh);
+
+      if (mutationObserverSupported) {
+          this.mutationsObserver_ = new MutationObserver(this.refresh);
+
+          this.mutationsObserver_.observe(document, {
+              attributes: true,
+              childList: true,
+              characterData: true,
+              subtree: true
+          });
+      } else {
+          document.addEventListener('DOMSubtreeModified', this.refresh);
+
+          this.mutationEventsAdded_ = true;
+      }
+
+      this.connected_ = true;
+  };
+
+  /**
+   * Removes DOM listeners.
+   *
+   * @private
+   * @returns {void}
+   */
+  ResizeObserverController.prototype.disconnect_ = function () {
+      // Do nothing if running in a non-browser environment or if listeners
+      // have been already removed.
+      if (!isBrowser || !this.connected_) {
+          return;
+      }
+
+      document.removeEventListener('transitionend', this.onTransitionEnd_);
+      window.removeEventListener('resize', this.refresh);
+
+      if (this.mutationsObserver_) {
+          this.mutationsObserver_.disconnect();
+      }
+
+      if (this.mutationEventsAdded_) {
+          document.removeEventListener('DOMSubtreeModified', this.refresh);
+      }
+
+      this.mutationsObserver_ = null;
+      this.mutationEventsAdded_ = false;
+      this.connected_ = false;
+  };
+
+  /**
+   * "Transitionend" event handler.
+   *
+   * @private
+   * @param {TransitionEvent} event
+   * @returns {void}
+   */
+  ResizeObserverController.prototype.onTransitionEnd_ = function (ref) {
+          var propertyName = ref.propertyName; if ( propertyName === void 0 ) propertyName = '';
+
+      // Detect whether transition may affect dimensions of an element.
+      var isReflowProperty = transitionKeys.some(function (key) {
+          return !!~propertyName.indexOf(key);
+      });
+
+      if (isReflowProperty) {
+          this.refresh();
+      }
+  };
+
+  /**
+   * Returns instance of the ResizeObserverController.
+   *
+   * @returns {ResizeObserverController}
+   */
+  ResizeObserverController.getInstance = function () {
+      if (!this.instance_) {
+          this.instance_ = new ResizeObserverController();
+      }
+
+      return this.instance_;
+  };
+
+  ResizeObserverController.instance_ = null;
+
+  /**
+   * Defines non-writable/enumerable properties of the provided target object.
+   *
+   * @param {Object} target - Object for which to define properties.
+   * @param {Object} props - Properties to be defined.
+   * @returns {Object} Target object.
+   */
+  var defineConfigurable = (function (target, props) {
+      for (var i = 0, list = Object.keys(props); i < list.length; i += 1) {
+          var key = list[i];
+
+          Object.defineProperty(target, key, {
+              value: props[key],
+              enumerable: false,
+              writable: false,
+              configurable: true
+          });
+      }
+
+      return target;
+  });
+
+  /**
+   * Returns the global object associated with provided element.
+   *
+   * @param {Object} target
+   * @returns {Object}
+   */
+  var getWindowOf = (function (target) {
+      // Assume that the element is an instance of Node, which means that it
+      // has the "ownerDocument" property from which we can retrieve a
+      // corresponding global object.
+      var ownerGlobal = target && target.ownerDocument && target.ownerDocument.defaultView;
+
+      // Return the local global object if it's not possible extract one from
+      // provided element.
+      return ownerGlobal || global$1;
+  });
+
+  // Placeholder of an empty content rectangle.
+  var emptyRect = createRectInit(0, 0, 0, 0);
+
+  /**
+   * Converts provided string to a number.
+   *
+   * @param {number|string} value
+   * @returns {number}
+   */
+  function toFloat(value) {
+      return parseFloat(value) || 0;
+  }
+
+  /**
+   * Extracts borders size from provided styles.
+   *
+   * @param {CSSStyleDeclaration} styles
+   * @param {...string} positions - Borders positions (top, right, ...)
+   * @returns {number}
+   */
+  function getBordersSize(styles) {
+      var positions = [], len = arguments.length - 1;
+      while ( len-- > 0 ) positions[ len ] = arguments[ len + 1 ];
+
+      return positions.reduce(function (size, position) {
+          var value = styles['border-' + position + '-width'];
+
+          return size + toFloat(value);
+      }, 0);
+  }
+
+  /**
+   * Extracts paddings sizes from provided styles.
+   *
+   * @param {CSSStyleDeclaration} styles
+   * @returns {Object} Paddings box.
+   */
+  function getPaddings(styles) {
+      var positions = ['top', 'right', 'bottom', 'left'];
+      var paddings = {};
+
+      for (var i = 0, list = positions; i < list.length; i += 1) {
+          var position = list[i];
+
+          var value = styles['padding-' + position];
+
+          paddings[position] = toFloat(value);
+      }
+
+      return paddings;
+  }
+
+  /**
+   * Calculates content rectangle of provided SVG element.
+   *
+   * @param {SVGGraphicsElement} target - Element content rectangle of which needs
+   *      to be calculated.
+   * @returns {DOMRectInit}
+   */
+  function getSVGContentRect(target) {
+      var bbox = target.getBBox();
+
+      return createRectInit(0, 0, bbox.width, bbox.height);
+  }
+
+  /**
+   * Calculates content rectangle of provided HTMLElement.
+   *
+   * @param {HTMLElement} target - Element for which to calculate the content rectangle.
+   * @returns {DOMRectInit}
+   */
+  function getHTMLElementContentRect(target) {
+      // Client width & height properties can't be
+      // used exclusively as they provide rounded values.
+      var clientWidth = target.clientWidth;
+      var clientHeight = target.clientHeight;
+
+      // By this condition we can catch all non-replaced inline, hidden and
+      // detached elements. Though elements with width & height properties less
+      // than 0.5 will be discarded as well.
+      //
+      // Without it we would need to implement separate methods for each of
+      // those cases and it's not possible to perform a precise and performance
+      // effective test for hidden elements. E.g. even jQuery's ':visible' filter
+      // gives wrong results for elements with width & height less than 0.5.
+      if (!clientWidth && !clientHeight) {
+          return emptyRect;
+      }
+
+      var styles = getWindowOf(target).getComputedStyle(target);
+      var paddings = getPaddings(styles);
+      var horizPad = paddings.left + paddings.right;
+      var vertPad = paddings.top + paddings.bottom;
+
+      // Computed styles of width & height are being used because they are the
+      // only dimensions available to JS that contain non-rounded values. It could
+      // be possible to utilize the getBoundingClientRect if only it's data wasn't
+      // affected by CSS transformations let alone paddings, borders and scroll bars.
+      var width = toFloat(styles.width),
+          height = toFloat(styles.height);
+
+      // Width & height include paddings and borders when the 'border-box' box
+      // model is applied (except for IE).
+      if (styles.boxSizing === 'border-box') {
+          // Following conditions are required to handle Internet Explorer which
+          // doesn't include paddings and borders to computed CSS dimensions.
+          //
+          // We can say that if CSS dimensions + paddings are equal to the "client"
+          // properties then it's either IE, and thus we don't need to subtract
+          // anything, or an element merely doesn't have paddings/borders styles.
+          if (Math.round(width + horizPad) !== clientWidth) {
+              width -= getBordersSize(styles, 'left', 'right') + horizPad;
+          }
+
+          if (Math.round(height + vertPad) !== clientHeight) {
+              height -= getBordersSize(styles, 'top', 'bottom') + vertPad;
+          }
+      }
+
+      // Following steps can't be applied to the document's root element as its
+      // client[Width/Height] properties represent viewport area of the window.
+      // Besides, it's as well not necessary as the <html> itself neither has
+      // rendered scroll bars nor it can be clipped.
+      if (!isDocumentElement(target)) {
+          // In some browsers (only in Firefox, actually) CSS width & height
+          // include scroll bars size which can be removed at this step as scroll
+          // bars are the only difference between rounded dimensions + paddings
+          // and "client" properties, though that is not always true in Chrome.
+          var vertScrollbar = Math.round(width + horizPad) - clientWidth;
+          var horizScrollbar = Math.round(height + vertPad) - clientHeight;
+
+          // Chrome has a rather weird rounding of "client" properties.
+          // E.g. for an element with content width of 314.2px it sometimes gives
+          // the client width of 315px and for the width of 314.7px it may give
+          // 314px. And it doesn't happen all the time. So just ignore this delta
+          // as a non-relevant.
+          if (Math.abs(vertScrollbar) !== 1) {
+              width -= vertScrollbar;
+          }
+
+          if (Math.abs(horizScrollbar) !== 1) {
+              height -= horizScrollbar;
+          }
+      }
+
+      return createRectInit(paddings.left, paddings.top, width, height);
+  }
+
+  /**
+   * Checks whether provided element is an instance of the SVGGraphicsElement.
+   *
+   * @param {Element} target - Element to be checked.
+   * @returns {boolean}
+   */
+  var isSVGGraphicsElement = (function () {
+      // Some browsers, namely IE and Edge, don't have the SVGGraphicsElement
+      // interface.
+      if (typeof SVGGraphicsElement !== 'undefined') {
+          return function (target) { return target instanceof getWindowOf(target).SVGGraphicsElement; };
+      }
+
+      // If it's so, then check that element is at least an instance of the
+      // SVGElement and that it has the "getBBox" method.
+      // eslint-disable-next-line no-extra-parens
+      return function (target) { return target instanceof getWindowOf(target).SVGElement && typeof target.getBBox === 'function'; };
+  })();
+
+  /**
+   * Checks whether provided element is a document element (<html>).
+   *
+   * @param {Element} target - Element to be checked.
+   * @returns {boolean}
+   */
+  function isDocumentElement(target) {
+      return target === getWindowOf(target).document.documentElement;
+  }
+
+  /**
+   * Calculates an appropriate content rectangle for provided html or svg element.
+   *
+   * @param {Element} target - Element content rectangle of which needs to be calculated.
+   * @returns {DOMRectInit}
+   */
+  function getContentRect(target) {
+      if (!isBrowser) {
+          return emptyRect;
+      }
+
+      if (isSVGGraphicsElement(target)) {
+          return getSVGContentRect(target);
+      }
+
+      return getHTMLElementContentRect(target);
+  }
+
+  /**
+   * Creates rectangle with an interface of the DOMRectReadOnly.
+   * Spec: https://drafts.fxtf.org/geometry/#domrectreadonly
+   *
+   * @param {DOMRectInit} rectInit - Object with rectangle's x/y coordinates and dimensions.
+   * @returns {DOMRectReadOnly}
+   */
+  function createReadOnlyRect(ref) {
+      var x = ref.x;
+      var y = ref.y;
+      var width = ref.width;
+      var height = ref.height;
+
+      // If DOMRectReadOnly is available use it as a prototype for the rectangle.
+      var Constr = typeof DOMRectReadOnly !== 'undefined' ? DOMRectReadOnly : Object;
+      var rect = Object.create(Constr.prototype);
+
+      // Rectangle's properties are not writable and non-enumerable.
+      defineConfigurable(rect, {
+          x: x, y: y, width: width, height: height,
+          top: y,
+          right: x + width,
+          bottom: height + y,
+          left: x
+      });
+
+      return rect;
+  }
+
+  /**
+   * Creates DOMRectInit object based on the provided dimensions and the x/y coordinates.
+   * Spec: https://drafts.fxtf.org/geometry/#dictdef-domrectinit
+   *
+   * @param {number} x - X coordinate.
+   * @param {number} y - Y coordinate.
+   * @param {number} width - Rectangle's width.
+   * @param {number} height - Rectangle's height.
+   * @returns {DOMRectInit}
+   */
+  function createRectInit(x, y, width, height) {
+      return { x: x, y: y, width: width, height: height };
+  }
+
+  /**
+   * Class that is responsible for computations of the content rectangle of
+   * provided DOM element and for keeping track of it's changes.
+   */
+  var ResizeObservation = function(target) {
+      this.broadcastWidth = 0;
+      this.broadcastHeight = 0;
+      this.contentRect_ = createRectInit(0, 0, 0, 0);
+
+      this.target = target;
+  };
+
+  /**
+   * Updates content rectangle and tells whether it's width or height properties
+   * have changed since the last broadcast.
+   *
+   * @returns {boolean}
+   */
+
+
+  /**
+   * Reference to the last observed content rectangle.
+   *
+   * @private {DOMRectInit}
+   */
+
+
+  /**
+   * Broadcasted width of content rectangle.
+   *
+   * @type {number}
+   */
+  ResizeObservation.prototype.isActive = function () {
+      var rect = getContentRect(this.target);
+
+      this.contentRect_ = rect;
+
+      return rect.width !== this.broadcastWidth || rect.height !== this.broadcastHeight;
+  };
+
+  /**
+   * Updates 'broadcastWidth' and 'broadcastHeight' properties with a data
+   * from the corresponding properties of the last observed content rectangle.
+   *
+   * @returns {DOMRectInit} Last observed content rectangle.
+   */
+  ResizeObservation.prototype.broadcastRect = function () {
+      var rect = this.contentRect_;
+
+      this.broadcastWidth = rect.width;
+      this.broadcastHeight = rect.height;
+
+      return rect;
+  };
+
+  var ResizeObserverEntry = function(target, rectInit) {
+      var contentRect = createReadOnlyRect(rectInit);
+
+      // According to the specification following properties are not writable
+      // and are also not enumerable in the native implementation.
+      //
+      // Property accessors are not being used as they'd require to define a
+      // private WeakMap storage which may cause memory leaks in browsers that
+      // don't support this type of collections.
+      defineConfigurable(this, { target: target, contentRect: contentRect });
+  };
+
+  var ResizeObserverSPI = function(callback, controller, callbackCtx) {
+      this.activeObservations_ = [];
+      this.observations_ = new MapShim();
+
+      if (typeof callback !== 'function') {
+          throw new TypeError('The callback provided as parameter 1 is not a function.');
+      }
+
+      this.callback_ = callback;
+      this.controller_ = controller;
+      this.callbackCtx_ = callbackCtx;
+  };
+
+  /**
+   * Starts observing provided element.
+   *
+   * @param {Element} target - Element to be observed.
+   * @returns {void}
+   */
+
+
+  /**
+   * Registry of the ResizeObservation instances.
+   *
+   * @private {Map<Element, ResizeObservation>}
+   */
+
+
+  /**
+   * Public ResizeObserver instance which will be passed to the callback
+   * function and used as a value of it's "this" binding.
+   *
+   * @private {ResizeObserver}
+   */
+
+  /**
+   * Collection of resize observations that have detected changes in dimensions
+   * of elements.
+   *
+   * @private {Array<ResizeObservation>}
+   */
+  ResizeObserverSPI.prototype.observe = function (target) {
+      if (!arguments.length) {
+          throw new TypeError('1 argument required, but only 0 present.');
+      }
+
+      // Do nothing if current environment doesn't have the Element interface.
+      if (typeof Element === 'undefined' || !(Element instanceof Object)) {
+          return;
+      }
+
+      if (!(target instanceof getWindowOf(target).Element)) {
+          throw new TypeError('parameter 1 is not of type "Element".');
+      }
+
+      var observations = this.observations_;
+
+      // Do nothing if element is already being observed.
+      if (observations.has(target)) {
+          return;
+      }
+
+      observations.set(target, new ResizeObservation(target));
+
+      this.controller_.addObserver(this);
+
+      // Force the update of observations.
+      this.controller_.refresh();
+  };
+
+  /**
+   * Stops observing provided element.
+   *
+   * @param {Element} target - Element to stop observing.
+   * @returns {void}
+   */
+  ResizeObserverSPI.prototype.unobserve = function (target) {
+      if (!arguments.length) {
+          throw new TypeError('1 argument required, but only 0 present.');
+      }
+
+      // Do nothing if current environment doesn't have the Element interface.
+      if (typeof Element === 'undefined' || !(Element instanceof Object)) {
+          return;
+      }
+
+      if (!(target instanceof getWindowOf(target).Element)) {
+          throw new TypeError('parameter 1 is not of type "Element".');
+      }
+
+      var observations = this.observations_;
+
+      // Do nothing if element is not being observed.
+      if (!observations.has(target)) {
+          return;
+      }
+
+      observations.delete(target);
+
+      if (!observations.size) {
+          this.controller_.removeObserver(this);
+      }
+  };
+
+  /**
+   * Stops observing all elements.
+   *
+   * @returns {void}
+   */
+  ResizeObserverSPI.prototype.disconnect = function () {
+      this.clearActive();
+      this.observations_.clear();
+      this.controller_.removeObserver(this);
+  };
+
+  /**
+   * Collects observation instances the associated element of which has changed
+   * it's content rectangle.
+   *
+   * @returns {void}
+   */
+  ResizeObserverSPI.prototype.gatherActive = function () {
+          var this$1 = this;
+
+      this.clearActive();
+
+      this.observations_.forEach(function (observation) {
+          if (observation.isActive()) {
+              this$1.activeObservations_.push(observation);
+          }
+      });
+  };
+
+  /**
+   * Invokes initial callback function with a list of ResizeObserverEntry
+   * instances collected from active resize observations.
+   *
+   * @returns {void}
+   */
+  ResizeObserverSPI.prototype.broadcastActive = function () {
+      // Do nothing if observer doesn't have active observations.
+      if (!this.hasActive()) {
+          return;
+      }
+
+      var ctx = this.callbackCtx_;
+
+      // Create ResizeObserverEntry instance for every active observation.
+      var entries = this.activeObservations_.map(function (observation) {
+          return new ResizeObserverEntry(observation.target, observation.broadcastRect());
+      });
+
+      this.callback_.call(ctx, entries, ctx);
+      this.clearActive();
+  };
+
+  /**
+   * Clears the collection of active observations.
+   *
+   * @returns {void}
+   */
+  ResizeObserverSPI.prototype.clearActive = function () {
+      this.activeObservations_.splice(0);
+  };
+
+  /**
+   * Tells whether observer has active observations.
+   *
+   * @returns {boolean}
+   */
+  ResizeObserverSPI.prototype.hasActive = function () {
+      return this.activeObservations_.length > 0;
+  };
+
+  // Registry of internal observers. If WeakMap is not available use current shim
+  // for the Map collection as it has all required methods and because WeakMap
+  // can't be fully polyfilled anyway.
+  var observers = typeof WeakMap !== 'undefined' ? new WeakMap() : new MapShim();
+
+  /**
+   * ResizeObserver API. Encapsulates the ResizeObserver SPI implementation
+   * exposing only those methods and properties that are defined in the spec.
+   */
+  var ResizeObserver = function(callback) {
+      if (!(this instanceof ResizeObserver)) {
+          throw new TypeError('Cannot call a class as a function.');
+      }
+      if (!arguments.length) {
+          throw new TypeError('1 argument required, but only 0 present.');
+      }
+
+      var controller = ResizeObserverController.getInstance();
+      var observer = new ResizeObserverSPI(callback, controller, this);
+
+      observers.set(this, observer);
+  };
+
+  // Expose public methods of ResizeObserver.
+  ['observe', 'unobserve', 'disconnect'].forEach(function (method) {
+      ResizeObserver.prototype[method] = function () {
+          return (ref = observers.get(this))[method].apply(ref, arguments);
+          var ref;
+      };
+  });
+
+  var index = (function () {
+      // Export existing implementation if available.
+      if (typeof global$1.ResizeObserver !== 'undefined') {
+          return global$1.ResizeObserver;
+      }
+
+      return ResizeObserver;
+  })();
+
+  var canUseDOM = !!(
+    typeof window !== 'undefined' &&
+    window.document &&
+    window.document.createElement
+  );
+
+  var canUseDom = canUseDOM;
+
+  var SimpleBar =
+  /*#__PURE__*/
+  function () {
+    function SimpleBar(element, options) {
+      var _this = this;
+
+      _classCallCheck(this, SimpleBar);
+
+      this.onScroll = function () {
+        if (!_this.scrollXTicking) {
+          window.requestAnimationFrame(_this.scrollX);
+          _this.scrollXTicking = true;
+        }
+
+        if (!_this.scrollYTicking) {
+          window.requestAnimationFrame(_this.scrollY);
+          _this.scrollYTicking = true;
+        }
+      };
+
+      this.scrollX = function () {
+        if (_this.axis.x.isOverflowing) {
+          _this.showScrollbar('x');
+
+          _this.positionScrollbar('x');
+        }
+
+        _this.scrollXTicking = false;
+      };
+
+      this.scrollY = function () {
+        if (_this.axis.y.isOverflowing) {
+          _this.showScrollbar('y');
+
+          _this.positionScrollbar('y');
+        }
+
+        _this.scrollYTicking = false;
+      };
+
+      this.onMouseEnter = function () {
+        _this.showScrollbar('x');
+
+        _this.showScrollbar('y');
+      };
+
+      this.onMouseMove = function (e) {
+        _this.mouseX = e.clientX;
+        _this.mouseY = e.clientY;
+
+        if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
+          _this.onMouseMoveForAxis('x');
+        }
+
+        if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
+          _this.onMouseMoveForAxis('y');
+        }
+      };
+
+      this.onMouseLeave = function () {
+        _this.onMouseMove.cancel();
+
+        if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
+          _this.onMouseLeaveForAxis('x');
+        }
+
+        if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
+          _this.onMouseLeaveForAxis('y');
+        }
+
+        _this.mouseX = -1;
+        _this.mouseY = -1;
+      };
+
+      this.onWindowResize = function () {
+        // Recalculate scrollbarWidth in case it's a zoom
+        _this.scrollbarWidth = scrollbarWidth();
+
+        _this.hideNativeScrollbar();
+      };
+
+      this.hideScrollbars = function () {
+        _this.axis.x.track.rect = _this.axis.x.track.el.getBoundingClientRect();
+        _this.axis.y.track.rect = _this.axis.y.track.el.getBoundingClientRect();
+
+        if (!_this.isWithinBounds(_this.axis.y.track.rect)) {
+          _this.axis.y.scrollbar.el.classList.remove(_this.classNames.visible);
+
+          _this.axis.y.isVisible = false;
+        }
+
+        if (!_this.isWithinBounds(_this.axis.x.track.rect)) {
+          _this.axis.x.scrollbar.el.classList.remove(_this.classNames.visible);
+
+          _this.axis.x.isVisible = false;
+        }
+      };
+
+      this.onPointerEvent = function (e) {
+        var isWithinBoundsY, isWithinBoundsX;
+
+        if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
+          isWithinBoundsX = _this.isWithinBounds(_this.axis.x.scrollbar.rect);
+        }
+
+        if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
+          isWithinBoundsY = _this.isWithinBounds(_this.axis.y.scrollbar.rect);
+        } // If any pointer event is called on the scrollbar
+
+
+        if (isWithinBoundsY || isWithinBoundsX) {
+          // Preventing the event's default action stops text being
+          // selectable during the drag.
+          e.preventDefault(); // Prevent event leaking
+
+          e.stopPropagation();
+
+          if (e.type === 'mousedown') {
+            if (isWithinBoundsY) {
+              _this.onDragStart(e, 'y');
+            }
+
+            if (isWithinBoundsX) {
+              _this.onDragStart(e, 'x');
+            }
+          }
+        }
+      };
+
+      this.drag = function (e) {
+        var eventOffset;
+        var track = _this.axis[_this.draggedAxis].track;
+        var trackSize = track.rect[_this.axis[_this.draggedAxis].sizeAttr];
+        var scrollbar = _this.axis[_this.draggedAxis].scrollbar;
+        e.preventDefault();
+        e.stopPropagation();
+
+        if (_this.draggedAxis === 'y') {
+          eventOffset = e.pageY;
+        } else {
+          eventOffset = e.pageX;
+        } // Calculate how far the user's mouse is from the top/left of the scrollbar (minus the dragOffset).
+
+
+        var dragPos = eventOffset - track.rect[_this.axis[_this.draggedAxis].offsetAttr] - _this.axis[_this.draggedAxis].dragOffset; // Convert the mouse position into a percentage of the scrollbar height/width.
+
+        var dragPerc = dragPos / track.rect[_this.axis[_this.draggedAxis].sizeAttr]; // Scroll the content by the same percentage.
+
+        var scrollPos = dragPerc * _this.contentEl[_this.axis[_this.draggedAxis].scrollSizeAttr]; // Fix browsers inconsistency on RTL
+
+        if (_this.draggedAxis === 'x') {
+          scrollPos = _this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollbarInverted ? scrollPos - (trackSize + scrollbar.size) : scrollPos;
+          scrollPos = _this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollingInverted ? -scrollPos : scrollPos;
+        }
+
+        _this.contentEl[_this.axis[_this.draggedAxis].scrollOffsetAttr] = scrollPos;
+      };
+
+      this.onEndDrag = function (e) {
+        e.preventDefault();
+        e.stopPropagation();
+        document.removeEventListener('mousemove', _this.drag);
+        document.removeEventListener('mouseup', _this.onEndDrag);
+      };
+
+      this.el = element;
+      this.flashTimeout;
+      this.contentEl;
+      this.offsetEl;
+      this.maskEl;
+      this.globalObserver;
+      this.mutationObserver;
+      this.resizeObserver;
+      this.scrollbarWidth;
+      this.minScrollbarWidth = 20;
+      this.options = _objectSpread({}, SimpleBar.defaultOptions, options);
+      this.classNames = _objectSpread({}, SimpleBar.defaultOptions.classNames, this.options.classNames);
+      this.isRtl;
+      this.axis = {
+        x: {
+          scrollOffsetAttr: 'scrollLeft',
+          sizeAttr: 'width',
+          scrollSizeAttr: 'scrollWidth',
+          offsetAttr: 'left',
+          overflowAttr: 'overflowX',
+          dragOffset: 0,
+          isOverflowing: true,
+          isVisible: false,
+          forceVisible: false,
+          track: {},
+          scrollbar: {}
+        },
+        y: {
+          scrollOffsetAttr: 'scrollTop',
+          sizeAttr: 'height',
+          scrollSizeAttr: 'scrollHeight',
+          offsetAttr: 'top',
+          overflowAttr: 'overflowY',
+          dragOffset: 0,
+          isOverflowing: true,
+          isVisible: false,
+          forceVisible: false,
+          track: {},
+          scrollbar: {}
+        }
+      };
+      this.recalculate = lodash_throttle(this.recalculate.bind(this), 64);
+      this.onMouseMove = lodash_throttle(this.onMouseMove.bind(this), 64);
+      this.hideScrollbars = lodash_debounce(this.hideScrollbars.bind(this), this.options.timeout);
+      this.onWindowResize = lodash_debounce(this.onWindowResize.bind(this), 64, {
+        leading: true
+      });
+      SimpleBar.getRtlHelpers = lodash_memoize(SimpleBar.getRtlHelpers); // getContentElement is deprecated
+
+      this.getContentElement = this.getScrollElement;
+      this.init();
+    }
+    /**
+     * Static properties
+     */
+
+    /**
+     * Helper to fix browsers inconsistency on RTL:
+     *  - Firefox inverts the scrollbar initial position
+     *  - IE11 inverts both scrollbar position and scrolling offset
+     * Directly inspired by @KingSora's OverlayScrollbars https://github.com/KingSora/OverlayScrollbars/blob/master/js/OverlayScrollbars.js#L1634
+     */
+
+
+    _createClass(SimpleBar, [{
+      key: "init",
+      value: function init() {
+        // Save a reference to the instance, so we know this DOM node has already been instancied
+        this.el.SimpleBar = this;
+        this.initDOM(); // We stop here on server-side
+
+        if (canUseDom) {
+          // Recalculate scrollbarWidth in case it's a zoom
+          this.scrollbarWidth = scrollbarWidth();
+          this.recalculate();
+          this.initListeners();
+        }
+      }
+    }, {
+      key: "initDOM",
+      value: function initDOM() {
+        var _this2 = this;
+
+        // make sure this element doesn't have the elements yet
+        if (Array.from(this.el.children).filter(function (child) {
+          return child.classList.contains(_this2.classNames.wrapper);
+        }).length) {
+          // assume that element has his DOM already initiated
+          this.wrapperEl = this.el.querySelector(".".concat(this.classNames.wrapper));
+          this.contentEl = this.el.querySelector(".".concat(this.classNames.content));
+          this.offsetEl = this.el.querySelector(".".concat(this.classNames.offset));
+          this.maskEl = this.el.querySelector(".".concat(this.classNames.mask));
+          this.placeholderEl = this.el.querySelector(".".concat(this.classNames.placeholder));
+          this.heightAutoObserverWrapperEl = this.el.querySelector(".".concat(this.classNames.heightAutoObserverWrapperEl));
+          this.heightAutoObserverEl = this.el.querySelector(".".concat(this.classNames.heightAutoObserverEl));
+          this.axis.x.track.el = this.el.querySelector(".".concat(this.classNames.track, ".").concat(this.classNames.horizontal));
+          this.axis.y.track.el = this.el.querySelector(".".concat(this.classNames.track, ".").concat(this.classNames.vertical));
+        } else {
+          // Prepare DOM
+          this.wrapperEl = document.createElement('div');
+          this.contentEl = document.createElement('div');
+          this.offsetEl = document.createElement('div');
+          this.maskEl = document.createElement('div');
+          this.placeholderEl = document.createElement('div');
+          this.heightAutoObserverWrapperEl = document.createElement('div');
+          this.heightAutoObserverEl = document.createElement('div');
+          this.wrapperEl.classList.add(this.classNames.wrapper);
+          this.contentEl.classList.add(this.classNames.content);
+          this.offsetEl.classList.add(this.classNames.offset);
+          this.maskEl.classList.add(this.classNames.mask);
+          this.placeholderEl.classList.add(this.classNames.placeholder);
+          this.heightAutoObserverWrapperEl.classList.add(this.classNames.heightAutoObserverWrapperEl);
+          this.heightAutoObserverEl.classList.add(this.classNames.heightAutoObserverEl);
+
+          while (this.el.firstChild) {
+            this.contentEl.appendChild(this.el.firstChild);
+          }
+
+          this.offsetEl.appendChild(this.contentEl);
+          this.maskEl.appendChild(this.offsetEl);
+          this.heightAutoObserverWrapperEl.appendChild(this.heightAutoObserverEl);
+          this.wrapperEl.appendChild(this.heightAutoObserverWrapperEl);
+          this.wrapperEl.appendChild(this.maskEl);
+          this.wrapperEl.appendChild(this.placeholderEl);
+          this.el.appendChild(this.wrapperEl);
+        }
+
+        if (!this.axis.x.track.el || !this.axis.y.track.el) {
+          var track = document.createElement('div');
+          var scrollbar = document.createElement('div');
+          track.classList.add(this.classNames.track);
+          scrollbar.classList.add(this.classNames.scrollbar);
+
+          if (!this.options.autoHide) {
+            scrollbar.classList.add(this.classNames.visible);
+          }
+
+          track.appendChild(scrollbar);
+          this.axis.x.track.el = track.cloneNode(true);
+          this.axis.x.track.el.classList.add(this.classNames.horizontal);
+          this.axis.y.track.el = track.cloneNode(true);
+          this.axis.y.track.el.classList.add(this.classNames.vertical);
+          this.el.appendChild(this.axis.x.track.el);
+          this.el.appendChild(this.axis.y.track.el);
+        }
+
+        this.axis.x.scrollbar.el = this.axis.x.track.el.querySelector(".".concat(this.classNames.scrollbar));
+        this.axis.y.scrollbar.el = this.axis.y.track.el.querySelector(".".concat(this.classNames.scrollbar));
+        this.el.setAttribute('data-simplebar', 'init');
+      }
+    }, {
+      key: "initListeners",
+      value: function initListeners() {
+        var _this3 = this;
+
+        // Event listeners
+        if (this.options.autoHide) {
+          this.el.addEventListener('mouseenter', this.onMouseEnter);
+        }
+
+        ['mousedown', 'click', 'dblclick', 'touchstart', 'touchend', 'touchmove'].forEach(function (e) {
+          _this3.el.addEventListener(e, _this3.onPointerEvent, true);
+        });
+        this.el.addEventListener('mousemove', this.onMouseMove);
+        this.el.addEventListener('mouseleave', this.onMouseLeave);
+        this.contentEl.addEventListener('scroll', this.onScroll); // Browser zoom triggers a window resize
+
+        window.addEventListener('resize', this.onWindowResize); // MutationObserver is IE11+
+
+        if (typeof MutationObserver !== 'undefined') {
+          // create an observer instance
+          this.mutationObserver = new MutationObserver(function (mutations) {
+            mutations.forEach(function (mutation) {
+              if (mutation.target === _this3.el || !_this3.isChildNode(mutation.target) || mutation.addedNodes.length) {
+                _this3.recalculate();
+              }
+            });
+          }); // pass in the target node, as well as the observer options
+
+          this.mutationObserver.observe(this.el, {
+            attributes: true,
+            childList: true,
+            characterData: true,
+            subtree: true
+          });
+        }
+
+        this.resizeObserver = new index(this.recalculate);
+        this.resizeObserver.observe(this.el);
+      }
+    }, {
+      key: "recalculate",
+      value: function recalculate() {
+        var isHeightAuto = this.heightAutoObserverEl.offsetHeight <= 1;
+        this.elStyles = window.getComputedStyle(this.el);
+        this.isRtl = this.elStyles.direction === 'rtl';
+        this.contentEl.style.padding = "".concat(this.elStyles.paddingTop, " ").concat(this.elStyles.paddingRight, " ").concat(this.elStyles.paddingBottom, " ").concat(this.elStyles.paddingLeft);
+        this.contentEl.style.height = isHeightAuto ? 'auto' : '100%';
+        this.placeholderEl.style.width = "".concat(this.contentEl.scrollWidth, "px");
+        this.placeholderEl.style.height = "".concat(this.contentEl.scrollHeight, "px");
+        this.wrapperEl.style.margin = "-".concat(this.elStyles.paddingTop, " -").concat(this.elStyles.paddingRight, " -").concat(this.elStyles.paddingBottom, " -").concat(this.elStyles.paddingLeft);
+        this.axis.x.track.rect = this.axis.x.track.el.getBoundingClientRect();
+        this.axis.y.track.rect = this.axis.y.track.el.getBoundingClientRect(); // Set isOverflowing to false if scrollbar is not necessary (content is shorter than offset)
+
+        this.axis.x.isOverflowing = (this.scrollbarWidth ? this.contentEl.scrollWidth : this.contentEl.scrollWidth - this.minScrollbarWidth) > Math.ceil(this.axis.x.track.rect.width);
+        this.axis.y.isOverflowing = (this.scrollbarWidth ? this.contentEl.scrollHeight : this.contentEl.scrollHeight - this.minScrollbarWidth) > Math.ceil(this.axis.y.track.rect.height); // Set isOverflowing to false if user explicitely set hidden overflow
+
+        this.axis.x.isOverflowing = this.elStyles.overflowX === 'hidden' ? false : this.axis.x.isOverflowing;
+        this.axis.y.isOverflowing = this.elStyles.overflowY === 'hidden' ? false : this.axis.y.isOverflowing;
+        this.axis.x.forceVisible = this.options.forceVisible === "x" || this.options.forceVisible === true;
+        this.axis.y.forceVisible = this.options.forceVisible === "y" || this.options.forceVisible === true;
+        this.axis.x.scrollbar.size = this.getScrollbarSize('x');
+        this.axis.y.scrollbar.size = this.getScrollbarSize('y');
+        this.axis.x.scrollbar.el.style.width = "".concat(this.axis.x.scrollbar.size, "px");
+        this.axis.y.scrollbar.el.style.height = "".concat(this.axis.y.scrollbar.size, "px");
+        this.positionScrollbar('x');
+        this.positionScrollbar('y');
+        this.toggleTrackVisibility('x');
+        this.toggleTrackVisibility('y');
+        this.hideNativeScrollbar();
+      }
+      /**
+       * Calculate scrollbar size
+       */
+
+    }, {
+      key: "getScrollbarSize",
+      value: function getScrollbarSize() {
+        var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
+        var contentSize = this.scrollbarWidth ? this.contentEl[this.axis[axis].scrollSizeAttr] : this.contentEl[this.axis[axis].scrollSizeAttr] - this.minScrollbarWidth;
+        var trackSize = this.axis[axis].track.rect[this.axis[axis].sizeAttr];
+        var scrollbarSize;
+
+        if (!this.axis[axis].isOverflowing) {
+          return;
+        }
+
+        var scrollbarRatio = trackSize / contentSize; // Calculate new height/position of drag handle.
+
+        scrollbarSize = Math.max(~~(scrollbarRatio * trackSize), this.options.scrollbarMinSize);
+
+        if (this.options.scrollbarMaxSize) {
+          scrollbarSize = Math.min(scrollbarSize, this.options.scrollbarMaxSize);
+        }
+
+        return scrollbarSize;
+      }
+    }, {
+      key: "positionScrollbar",
+      value: function positionScrollbar() {
+        var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
+        var contentSize = this.contentEl[this.axis[axis].scrollSizeAttr];
+        var trackSize = this.axis[axis].track.rect[this.axis[axis].sizeAttr];
+        var hostSize = parseInt(this.elStyles[this.axis[axis].sizeAttr], 10);
+        var scrollbar = this.axis[axis].scrollbar;
+        var scrollOffset = this.contentEl[this.axis[axis].scrollOffsetAttr];
+        scrollOffset = axis === 'x' && this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollingInverted ? -scrollOffset : scrollOffset;
+        var scrollPourcent = scrollOffset / (contentSize - hostSize);
+        var handleOffset = ~~((trackSize - scrollbar.size) * scrollPourcent);
+        handleOffset = axis === 'x' && this.isRtl && SimpleBar.getRtlHelpers().isRtlScrollbarInverted ? handleOffset + (trackSize - scrollbar.size) : handleOffset;
+        scrollbar.el.style.transform = axis === 'x' ? "translate3d(".concat(handleOffset, "px, 0, 0)") : "translate3d(0, ".concat(handleOffset, "px, 0)");
+      }
+    }, {
+      key: "toggleTrackVisibility",
+      value: function toggleTrackVisibility() {
+        var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
+        var track = this.axis[axis].track.el;
+        var scrollbar = this.axis[axis].scrollbar.el;
+
+        if (this.axis[axis].isOverflowing || this.axis[axis].forceVisible) {
+          track.style.visibility = 'visible';
+          this.contentEl.style[this.axis[axis].overflowAttr] = 'scroll';
+        } else {
+          track.style.visibility = 'hidden';
+          this.contentEl.style[this.axis[axis].overflowAttr] = 'hidden';
+        } // Even if forceVisible is enabled, scrollbar itself should be hidden
+
+
+        if (this.axis[axis].isOverflowing) {
+          scrollbar.style.visibility = 'visible';
+        } else {
+          scrollbar.style.visibility = 'hidden';
+        }
+      }
+    }, {
+      key: "hideNativeScrollbar",
+      value: function hideNativeScrollbar() {
+        this.offsetEl.style[this.isRtl ? 'left' : 'right'] = this.axis.y.isOverflowing || this.axis.y.forceVisible ? "-".concat(this.scrollbarWidth || this.minScrollbarWidth, "px") : 0;
+        this.offsetEl.style.bottom = this.axis.x.isOverflowing || this.axis.x.forceVisible ? "-".concat(this.scrollbarWidth || this.minScrollbarWidth, "px") : 0; // If floating scrollbar
+
+        if (!this.scrollbarWidth) {
+          var paddingDirection = [this.isRtl ? 'paddingLeft' : 'paddingRight'];
+          this.contentEl.style[paddingDirection] = this.axis.y.isOverflowing || this.axis.y.forceVisible ? "calc(".concat(this.elStyles[paddingDirection], " + ").concat(this.minScrollbarWidth, "px)") : this.elStyles[paddingDirection];
+          this.contentEl.style.paddingBottom = this.axis.x.isOverflowing || this.axis.x.forceVisible ? "calc(".concat(this.elStyles.paddingBottom, " + ").concat(this.minScrollbarWidth, "px)") : this.elStyles.paddingBottom;
+        }
+      }
+      /**
+       * On scroll event handling
+       */
+
+    }, {
+      key: "onMouseMoveForAxis",
+      value: function onMouseMoveForAxis() {
+        var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
+        this.axis[axis].track.rect = this.axis[axis].track.el.getBoundingClientRect();
+        this.axis[axis].scrollbar.rect = this.axis[axis].scrollbar.el.getBoundingClientRect();
+        var isWithinScrollbarBoundsX = this.isWithinBounds(this.axis[axis].scrollbar.rect);
+
+        if (isWithinScrollbarBoundsX) {
+          this.axis[axis].scrollbar.el.classList.add(this.classNames.hover);
+        } else {
+          this.axis[axis].scrollbar.el.classList.remove(this.classNames.hover);
+        }
+
+        if (this.isWithinBounds(this.axis[axis].track.rect)) {
+          this.showScrollbar(axis);
+          this.axis[axis].track.el.classList.add(this.classNames.hover);
+        } else {
+          this.axis[axis].track.el.classList.remove(this.classNames.hover);
+        }
+      }
+    }, {
+      key: "onMouseLeaveForAxis",
+      value: function onMouseLeaveForAxis() {
+        var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
+        this.axis[axis].track.el.classList.remove(this.classNames.hover);
+        this.axis[axis].scrollbar.el.classList.remove(this.classNames.hover);
+      }
+    }, {
+      key: "showScrollbar",
+
+      /**
+       * Show scrollbar
+       */
+      value: function showScrollbar() {
+        var axis = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'y';
+        var scrollbar = this.axis[axis].scrollbar.el;
+
+        if (!this.axis[axis].isVisible) {
+          scrollbar.classList.add(this.classNames.visible);
+          this.axis[axis].isVisible = true;
+        }
+
+        if (this.options.autoHide) {
+          this.hideScrollbars();
+        }
+      }
+      /**
+       * Hide Scrollbar
+       */
+
+    }, {
+      key: "onDragStart",
+
+      /**
+       * on scrollbar handle drag movement starts
+       */
+      value: function onDragStart(e) {
+        var axis = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'y';
+        var scrollbar = this.axis[axis].scrollbar.el; // Measure how far the user's mouse is from the top of the scrollbar drag handle.
+
+        var eventOffset = axis === 'y' ? e.pageY : e.pageX;
+        this.axis[axis].dragOffset = eventOffset - scrollbar.getBoundingClientRect()[this.axis[axis].offsetAttr];
+        this.draggedAxis = axis;
+        document.addEventListener('mousemove', this.drag);
+        document.addEventListener('mouseup', this.onEndDrag);
+      }
+      /**
+       * Drag scrollbar handle
+       */
+
+    }, {
+      key: "getScrollElement",
+
+      /**
+       * Getter for original scrolling element
+       */
+      value: function getScrollElement() {
+        return this.contentEl;
+      }
+    }, {
+      key: "removeListeners",
+      value: function removeListeners() {
+        // Event listeners
+        if (this.options.autoHide) {
+          this.el.removeEventListener('mouseenter', this.onMouseEnter);
+        }
+
+        this.contentEl.removeEventListener('scroll', this.onScroll);
+        window.removeEventListener('resize', this.onWindowResize);
+        this.mutationObserver && this.mutationObserver.disconnect();
+        this.resizeObserver.disconnect();
+      }
+      /**
+       * UnMount mutation observer and delete SimpleBar instance from DOM element
+       */
+
+    }, {
+      key: "unMount",
+      value: function unMount() {
+        this.removeListeners();
+        this.el.SimpleBar = null;
+      }
+      /**
+       * Recursively walks up the parent nodes looking for this.el
+       */
+
+    }, {
+      key: "isChildNode",
+      value: function isChildNode(el) {
+        if (el === null) return false;
+        if (el === this.el) return true;
+        return this.isChildNode(el.parentNode);
+      }
+      /**
+       * Check if mouse is within bounds
+       */
+
+    }, {
+      key: "isWithinBounds",
+      value: function isWithinBounds(bbox) {
+        return this.mouseX >= bbox.left && this.mouseX <= bbox.left + bbox.width && this.mouseY >= bbox.top && this.mouseY <= bbox.top + bbox.height;
+      }
+    }], [{
+      key: "getRtlHelpers",
+      value: function getRtlHelpers() {
+        var dummyDiv = document.createElement('div');
+        dummyDiv.innerHTML = '<div class="hs-dummy-scrollbar-size"><div style="height: 200%; width: 200%; margin: 10px 0;"></div></div>';
+        var scrollbarDummyEl = dummyDiv.firstElementChild;
+        document.body.appendChild(scrollbarDummyEl);
+        var dummyContainerChild = scrollbarDummyEl.firstElementChild;
+        scrollbarDummyEl.scrollLeft = 0;
+        var dummyContainerOffset = SimpleBar.getOffset(scrollbarDummyEl);
+        var dummyContainerChildOffset = SimpleBar.getOffset(dummyContainerChild);
+        scrollbarDummyEl.scrollLeft = 999;
+        var dummyContainerScrollOffsetAfterScroll = SimpleBar.getOffset(dummyContainerChild);
+        return {
+          // determines if the scrolling is responding with negative values
+          isRtlScrollingInverted: dummyContainerOffset.left !== dummyContainerChildOffset.left && dummyContainerChildOffset.left - dummyContainerScrollOffsetAfterScroll.left !== 0,
+          // determines if the origin scrollbar position is inverted or not (positioned on left or right)
+          isRtlScrollbarInverted: dummyContainerOffset.left !== dummyContainerChildOffset.left
+        };
+      }
+    }, {
+      key: "initHtmlApi",
+      value: function initHtmlApi() {
+        this.initDOMLoadedElements = this.initDOMLoadedElements.bind(this); // MutationObserver is IE11+
+
+        if (typeof MutationObserver !== 'undefined') {
+          // Mutation observer to observe dynamically added elements
+          this.globalObserver = new MutationObserver(function (mutations) {
+            mutations.forEach(function (mutation) {
+              Array.from(mutation.addedNodes).forEach(function (addedNode) {
+                if (addedNode.nodeType === 1) {
+                  if (addedNode.hasAttribute('data-simplebar')) {
+                    !addedNode.SimpleBar && new SimpleBar(addedNode, SimpleBar.getElOptions(addedNode));
+                  } else {
+                    Array.from(addedNode.querySelectorAll('[data-simplebar]')).forEach(function (el) {
+                      !el.SimpleBar && new SimpleBar(el, SimpleBar.getElOptions(el));
+                    });
+                  }
+                }
+              });
+              Array.from(mutation.removedNodes).forEach(function (removedNode) {
+                if (removedNode.nodeType === 1) {
+                  if (removedNode.hasAttribute('data-simplebar')) {
+                    removedNode.SimpleBar && removedNode.SimpleBar.unMount();
+                  } else {
+                    Array.from(removedNode.querySelectorAll('[data-simplebar]')).forEach(function (el) {
+                      el.SimpleBar && el.SimpleBar.unMount();
+                    });
+                  }
+                }
+              });
+            });
+          });
+          this.globalObserver.observe(document, {
+            childList: true,
+            subtree: true
+          });
+        } // Taken from jQuery `ready` function
+        // Instantiate elements already present on the page
+
+
+        if (document.readyState === 'complete' || document.readyState !== 'loading' && !document.documentElement.doScroll) {
+          // Handle it asynchronously to allow scripts the opportunity to delay init
+          window.setTimeout(this.initDOMLoadedElements);
+        } else {
+          document.addEventListener('DOMContentLoaded', this.initDOMLoadedElements);
+          window.addEventListener('load', this.initDOMLoadedElements);
+        }
+      } // Helper function to retrieve options from element attributes
+
+    }, {
+      key: "getElOptions",
+      value: function getElOptions(el) {
+        var options = Array.from(el.attributes).reduce(function (acc, attribute) {
+          var option = attribute.name.match(/data-simplebar-(.+)/);
+
+          if (option) {
+            var key = option[1].replace(/\W+(.)/g, function (x, chr) {
+              return chr.toUpperCase();
+            });
+
+            switch (attribute.value) {
+              case 'true':
+                acc[key] = true;
+                break;
+
+              case 'false':
+                acc[key] = false;
+                break;
+
+              case undefined:
+                acc[key] = true;
+                break;
+
+              default:
+                acc[key] = attribute.value;
+            }
+          }
+
+          return acc;
+        }, {});
+        return options;
+      }
+    }, {
+      key: "removeObserver",
+      value: function removeObserver() {
+        this.globalObserver.disconnect();
+      }
+    }, {
+      key: "initDOMLoadedElements",
+      value: function initDOMLoadedElements() {
+        document.removeEventListener('DOMContentLoaded', this.initDOMLoadedElements);
+        window.removeEventListener('load', this.initDOMLoadedElements);
+        Array.from(document.querySelectorAll('[data-simplebar]')).forEach(function (el) {
+          if (!el.SimpleBar) new SimpleBar(el, SimpleBar.getElOptions(el));
+        });
+      }
+    }, {
+      key: "getOffset",
+      value: function getOffset(el) {
+        var rect = el.getBoundingClientRect();
+        return {
+          top: rect.top + (window.pageYOffset || document.documentElement.scrollTop),
+          left: rect.left + (window.pageXOffset || document.documentElement.scrollLeft)
+        };
+      }
+    }]);
+
+    return SimpleBar;
+  }();
+  /**
+   * HTML API
+   * Called only in a browser env.
+   */
+
+
+  SimpleBar.defaultOptions = {
+    autoHide: true,
+    forceVisible: false,
+    classNames: {
+      content: 'simplebar-content',
+      offset: 'simplebar-offset',
+      mask: 'simplebar-mask',
+      wrapper: 'simplebar-wrapper',
+      placeholder: 'simplebar-placeholder',
+      scrollbar: 'simplebar-scrollbar',
+      track: 'simplebar-track',
+      heightAutoObserverWrapperEl: 'simplebar-height-auto-observer-wrapper',
+      heightAutoObserverEl: 'simplebar-height-auto-observer',
+      visible: 'simplebar-visible',
+      horizontal: 'simplebar-horizontal',
+      vertical: 'simplebar-vertical',
+      hover: 'simplebar-hover'
+    },
+    scrollbarMinSize: 25,
+    scrollbarMaxSize: 0,
+    timeout: 1000
+  };
+
+  if (canUseDom) {
+    SimpleBar.initHtmlApi();
+  }
+
+  return SimpleBar;
+
+})));

+ 4 - 0
style/.directory

@@ -0,0 +1,4 @@
+[Dolphin]
+Timestamp=2018,11,15,15,55,42
+Version=4
+ViewMode=2

+ 79 - 0
style/fonts.css

@@ -0,0 +1,79 @@
+@font-face {
+  font-family: 'ubuntu-b-webfont';
+  src: url('/fonts/ubuntu-b-webfont.eot'); /* IE9 Compat Modes */
+  src: url('/fonts/ubuntu-b-webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+       url('/fonts/ubuntu-b-webfont.woff2') format('woff2'), /* Super Modern Browsers */
+       url('/fonts/ubuntu-b-webfont.woff') format('woff'), /* Pretty Modern Browsers */
+       url('/fonts/ubuntu-b-webfont.ttf')  format('truetype'), /* Safari, Android, iOS */
+       url('/fonts/ubuntu-b-webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
+}
+
+@font-face {
+  font-family: 'ubuntu-bi-webfont';
+  src: url('/fonts/ubuntu-bi-webfont.eot'); /* IE9 Compat Modes */
+  src: url('/fonts/ubuntu-bi-webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+       url('/fonts/ubuntu-bi-webfont.woff2') format('woff2'), /* Super Modern Browsers */
+       url('/fonts/ubuntu-bi-webfont.woff') format('woff'), /* Pretty Modern Browsers */
+       url('/fonts/ubuntu-bi-webfont.ttf')  format('truetype'), /* Safari, Android, iOS */
+       url('/fonts/ubuntu-bi-webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
+}
+
+@font-face {
+  font-family: 'ubuntu-c-webfont';
+  src: url('/fonts/ubuntu-c-webfont.eot'); /* IE9 Compat Modes */
+  src: url('/fonts/ubuntu-c-webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+       url('/fonts/ubuntu-c-webfont.woff2') format('woff2'), /* Super Modern Browsers */
+       url('/fonts/ubuntu-c-webfont.woff') format('woff'), /* Pretty Modern Browsers */
+       url('/fonts/ubuntu-c-webfont.ttf')  format('truetype'), /* Safari, Android, iOS */
+       url('/fonts/ubuntu-c-webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
+}
+
+@font-face {
+  font-family: 'ubuntu-l-webfont';
+  src: url('/fonts/ubuntu-l-webfont.eot'); /* IE9 Compat Modes */
+  src: url('/fonts/ubuntu-l-webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+       url('/fonts/ubuntu-l-webfont.woff2') format('woff2'), /* Super Modern Browsers */
+       url('/fonts/ubuntu-l-webfont.woff') format('woff'), /* Pretty Modern Browsers */
+       url('/fonts/ubuntu-l-webfont.ttf')  format('truetype'), /* Safari, Android, iOS */
+       url('/fonts/ubuntu-l-webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
+}
+
+@font-face {
+  font-family: 'ubuntu-li-webfont';
+  src: url('/fonts/ubuntu-li-webfont.eot'); /* IE9 Compat Modes */
+  src: url('/fonts/ubuntu-li-webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+       url('/fonts/ubuntu-li-webfont.woff2') format('woff2'), /* Super Modern Browsers */
+       url('/fonts/ubuntu-li-webfont.woff') format('woff'), /* Pretty Modern Browsers */
+       url('/fonts/ubuntu-li-webfont.ttf')  format('truetype'), /* Safari, Android, iOS */
+       url('/fonts/ubuntu-li-webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
+}
+
+@font-face {
+  font-family: 'ubuntu-m-webfont';
+  src: url('/fonts/ubuntu-m-webfont.eot'); /* IE9 Compat Modes */
+  src: url('/fonts/ubuntu-m-webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+       url('/fonts/ubuntu-m-webfont.woff2') format('woff2'), /* Super Modern Browsers */
+       url('/fonts/ubuntu-m-webfont.woff') format('woff'), /* Pretty Modern Browsers */
+       url('/fonts/ubuntu-m-webfont.ttf')  format('truetype'), /* Safari, Android, iOS */
+       url('/fonts/ubuntu-m-webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
+}
+
+@font-face {
+  font-family: 'ubuntu-mi-webfont';
+  src: url('/fonts/ubuntu-mi-webfont.eot'); /* IE9 Compat Modes */
+  src: url('/fonts/ubuntu-mi-webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+       url('/fonts/ubuntu-mi-webfont.woff2') format('woff2'), /* Super Modern Browsers */
+       url('/fonts/ubuntu-mi-webfont.woff') format('woff'), /* Pretty Modern Browsers */
+       url('/fonts/ubuntu-mi-webfont.ttf')  format('truetype'), /* Safari, Android, iOS */
+       url('/fonts/ubuntu-mi-webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
+}
+
+@font-face {
+  font-family: 'ubuntu-r-webfont';
+  src: url('/fonts/ubuntu-r-webfont.eot'); /* IE9 Compat Modes */
+  src: url('/fonts/ubuntu-r-webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+       url('/fonts/ubuntu-r-webfont.woff2') format('woff2'), /* Super Modern Browsers */
+       url('/fonts/ubuntu-r-webfont.woff') format('woff'), /* Pretty Modern Browsers */
+       url('/fonts/ubuntu-r-webfont.ttf')  format('truetype'), /* Safari, Android, iOS */
+       url('/fonts/ubuntu-r-webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
+}

+ 236 - 0
style/fullpage.css

@@ -0,0 +1,236 @@
+/*!
+ * fullPage 3.0.3
+ * https://github.com/alvarotrigo/fullPage.js
+ *
+ * @license GPLv3 for open source use only
+ * or Fullpage Commercial License for commercial use
+ * http://alvarotrigo.com/fullPage/pricing/
+ *
+ * Copyright (C) 2018 http://alvarotrigo.com/fullPage - A project by Alvaro Trigo
+ */
+html.fp-enabled,
+.fp-enabled body {
+    margin: 0;
+    padding: 0;
+    overflow:hidden;
+
+    /*Avoid flicker on slides transitions for mobile phones #336 */
+    -webkit-tap-highlight-color: rgba(0,0,0,0);
+}
+.fp-section {
+    position: relative;
+    -webkit-box-sizing: border-box; /* Safari<=5 Android<=3 */
+    -moz-box-sizing: border-box; /* <=28 */
+    box-sizing: border-box;
+}
+.fp-slide {
+    float: left;
+}
+.fp-slide, .fp-slidesContainer {
+    height: 100%;
+    display: block;
+}
+.fp-slides {
+    z-index:1;
+    height: 100%;
+    overflow: hidden;
+    position: relative;
+    -webkit-transition: all 0.3s ease-out; /* Safari<=6 Android<=4.3 */
+    transition: all 0.3s ease-out;
+}
+.fp-section.fp-table, .fp-slide.fp-table {
+    display: table;
+    table-layout:fixed;
+    width: 100%;
+}
+.fp-tableCell {
+    display: table-cell;
+    vertical-align: middle;
+    width: 100%;
+    height: 100%;
+}
+.fp-slidesContainer {
+    float: left;
+    position: relative;
+}
+.fp-controlArrow {
+    -webkit-user-select: none; /* webkit (safari, chrome) browsers */
+    -moz-user-select: none; /* mozilla browsers */
+    -khtml-user-select: none; /* webkit (konqueror) browsers */
+    -ms-user-select: none; /* IE10+ */
+    position: absolute;
+    z-index: 4;
+    top: 50%;
+    cursor: pointer;
+    width: 0;
+    height: 0;
+    border-style: solid;
+    margin-top: -38px;
+    -webkit-transform: translate3d(0,0,0);
+    -ms-transform: translate3d(0,0,0);
+    transform: translate3d(0,0,0);
+}
+.fp-controlArrow.fp-prev {
+    left: 15px;
+    width: 0;
+    border-width: 38.5px 34px 38.5px 0;
+    border-color: transparent #fff transparent transparent;
+}
+.fp-controlArrow.fp-next {
+    right: 15px;
+    border-width: 38.5px 0 38.5px 34px;
+    border-color: transparent transparent transparent #fff;
+}
+.fp-scrollable {
+    overflow: hidden;
+    position: relative;
+}
+.fp-scroller{
+    overflow: hidden;
+}
+.iScrollIndicator{
+    border: 0 !important;
+}
+.fp-notransition {
+    -webkit-transition: none !important;
+    transition: none !important;
+}
+#fp-nav {
+    position: fixed;
+    z-index: 100;
+    margin-top: -32px;
+    top: 50%;
+    opacity: 1;
+    -webkit-transform: translate3d(0,0,0);
+}
+#fp-nav.fp-right {
+    right: 17px;
+}
+#fp-nav.fp-left {
+    left: 17px;
+}
+.fp-slidesNav{
+    position: absolute;
+    z-index: 4;
+    opacity: 1;
+    -webkit-transform: translate3d(0,0,0);
+    -ms-transform: translate3d(0,0,0);
+    transform: translate3d(0,0,0);
+    left: 0 !important;
+    right: 0;
+    margin: 0 auto !important;
+}
+.fp-slidesNav.fp-bottom {
+    bottom: 17px;
+}
+.fp-slidesNav.fp-top {
+    top: 17px;
+}
+#fp-nav ul,
+.fp-slidesNav ul {
+  margin: 0;
+  padding: 0;
+}
+#fp-nav ul li,
+.fp-slidesNav ul li {
+    display: block;
+    width: 14px;
+    height: 13px;
+    margin: 7px;
+    position:relative;
+}
+.fp-slidesNav ul li {
+    display: inline-block;
+}
+#fp-nav ul li a,
+.fp-slidesNav ul li a {
+    display: block;
+    position: relative;
+    z-index: 1;
+    width: 100%;
+    height: 100%;
+    cursor: pointer;
+    text-decoration: none;
+}
+#fp-nav ul li a.active span,
+.fp-slidesNav ul li a.active span,
+#fp-nav ul li:hover a.active span,
+.fp-slidesNav ul li:hover a.active span{
+    height: 12px;
+    width: 12px;
+    margin: -6px 0 0 -6px;
+    border-radius: 100%;
+ }
+#fp-nav ul li a span,
+.fp-slidesNav ul li a span {
+    border-radius: 50%;
+    position: absolute;
+    z-index: 1;
+    height: 4px;
+    width: 4px;
+    border: 0;
+    background: #333;
+    left: 50%;
+    top: 50%;
+    margin: -2px 0 0 -2px;
+    -webkit-transition: all 0.1s ease-in-out;
+    -moz-transition: all 0.1s ease-in-out;
+    -o-transition: all 0.1s ease-in-out;
+    transition: all 0.1s ease-in-out;
+}
+#fp-nav ul li:hover a span,
+.fp-slidesNav ul li:hover a span{
+    width: 10px;
+    height: 10px;
+    margin: -5px 0px 0px -5px;
+}
+#fp-nav ul li .fp-tooltip {
+    position: absolute;
+    top: -2px;
+    color: #fff;
+    font-size: 14px;
+    font-family: arial, helvetica, sans-serif;
+    white-space: nowrap;
+    max-width: 220px;
+    overflow: hidden;
+    display: block;
+    opacity: 0;
+    width: 0;
+    cursor: pointer;
+}
+#fp-nav ul li:hover .fp-tooltip,
+#fp-nav.fp-show-active a.active + .fp-tooltip {
+    -webkit-transition: opacity 0.2s ease-in;
+    transition: opacity 0.2s ease-in;
+    width: auto;
+    opacity: 1;
+}
+#fp-nav ul li .fp-tooltip.fp-right {
+    right: 20px;
+}
+#fp-nav ul li .fp-tooltip.fp-left {
+    left: 20px;
+}
+.fp-auto-height.fp-section,
+.fp-auto-height .fp-slide,
+.fp-auto-height .fp-tableCell{
+    height: auto !important;
+}
+
+.fp-responsive .fp-auto-height-responsive.fp-section,
+.fp-responsive .fp-auto-height-responsive .fp-slide,
+.fp-responsive .fp-auto-height-responsive .fp-tableCell {
+    height: auto !important;
+}
+
+/*Only display content to screen readers*/
+.fp-sr-only{
+    position: absolute;
+    width: 1px;
+    height: 1px;
+    padding: 0;
+    overflow: hidden;
+    clip: rect(0, 0, 0, 0);
+    white-space: nowrap;
+    border: 0;
+}

File diff suppressed because it is too large
+ 4 - 0
style/knacss.css


+ 183 - 0
style/simplebar.css

@@ -0,0 +1,183 @@
+[data-simplebar] {
+    position: relative;
+    flex-direction: column;
+    flex-wrap: wrap;
+    justify-content: flex-start;
+    align-content: flex-start;
+    align-items: flex-start;
+    width: inherit;
+    height: inherit;
+    max-width: inherit;
+    max-height: inherit;
+}
+
+.simplebar-wrapper {
+    overflow: hidden;
+    width: inherit;
+    height: inherit;
+    max-width: inherit;
+    max-height: inherit;
+}
+
+.simplebar-mask {
+    direction: inherit;
+    position: absolute;
+    overflow: hidden;
+    padding: 0;
+    margin: 0;
+    left: 0;
+    top: 0;
+    bottom: 0;
+    right: 0;
+    width: auto !important;
+    height: auto !important;
+    z-index: 0;
+}
+
+.simplebar-offset {
+    direction: inherit !important;
+    box-sizing: inherit !important;
+    resize: none !important;
+    position: absolute;
+    top: 0;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    padding: 0;
+    margin: 0;
+    -webkit-overflow-scrolling: touch;
+}
+
+.simplebar-content {
+    direction: inherit;
+    box-sizing: border-box !important;
+    position: relative;
+    display: block;
+    height: 100%; /* Required for horizontal native scrollbar to not appear if parent is taller than natural height */
+    width: auto;
+    visibility: visible;
+    overflow: scroll; /* Scroll on this element otherwise element can't have a padding applied properly */
+    max-width: 100%; /* Not required for horizontal scroll to trigger */
+    max-height: 100%; /* Needed for vertical scroll to trigger */
+}
+
+.simplebar-placeholder {
+    max-height: 100%;
+    max-width: 100%;
+    width: 100%;
+    pointer-events: none;
+}
+
+.simplebar-height-auto-observer-wrapper {
+    box-sizing: inherit !important;
+    height: 100%;
+    width: inherit;
+    max-width: 1px;
+    position: relative;
+    float: left;
+    max-height: 1px;
+    overflow: hidden;
+    z-index: -1;
+    padding: 0;
+    margin: 0;
+    pointer-events: none;
+    flex-grow: inherit;
+    flex-shrink: 0;
+    flex-basis: 0;
+}
+
+.simplebar-height-auto-observer {
+    box-sizing: inherit;
+    display: block;
+    opacity: 0;
+    position: absolute;
+    top: 0;
+    left: 0;
+    height: 1000%;
+    width: 1000%;
+    min-height: 1px;
+    min-width: 1px;
+    overflow: hidden;
+    pointer-events: none;
+    z-index: -1;
+}
+
+.simplebar-track {
+    z-index: 1;
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    pointer-events: none;
+}
+
+.simplebar-scrollbar {
+    position: absolute;
+    right: 2px;
+    width: 7px;
+    min-height: 10px;
+}
+
+.simplebar-scrollbar:before {
+    position: absolute;
+    content: "";
+    background: black;
+    border-radius: 7px;
+    left: 0;
+    right: 0;
+    opacity: 0;
+    transition: opacity 0.2s linear;
+}
+
+.simplebar-track .simplebar-scrollbar.simplebar-visible:before {
+    /* When hovered, remove all transitions from drag handle */
+    opacity: 0.5;
+    transition: opacity 0s linear;
+}
+
+.simplebar-track.simplebar-vertical {
+    top: 0;
+    width: 11px;
+}
+
+.simplebar-track.simplebar-vertical .simplebar-scrollbar:before {
+    top: 2px;
+    bottom: 2px;
+}
+
+.simplebar-track.simplebar-horizontal {
+    left: 0;
+    height: 11px;
+}
+
+.simplebar-track.simplebar-horizontal .simplebar-scrollbar:before {
+    height: 100%;
+    left: 2px;
+    right: 2px;
+}
+
+.simplebar-track.simplebar-horizontal .simplebar-scrollbar {
+    right: auto;
+    left: 0;
+    top: 2px;
+    height: 7px;
+    min-height: 0;
+    min-width: 10px;
+    width: auto;
+}
+
+/* Rtl support */
+[data-simplebar-direction="rtl"] .simplebar-track.simplebar-vertical {
+    right: auto;
+    left: 0;
+}
+
+.hs-dummy-scrollbar-size {
+    direction: rtl;
+    position: fixed;
+    opacity: 0;
+    visibility: hidden;
+    height: 500px;
+    width: 500px;
+    overflow-y: hidden;
+    overflow-x: scroll;
+}

+ 284 - 0
style/style.css

@@ -0,0 +1,284 @@
+html,body{
+  margin: 0;
+  padding: 0;
+  font-weight: normal;
+  font-size: 1rem;
+  height: 100%;
+  /* color: #323232ff!important; */
+}
+
+html{
+  background: #f7f4ed;
+}
+
+header{
+  position: fixed;
+  display: flex;
+  align-items: baseline;
+  justify-content: space-between;
+  width: 100%;
+  z-index: 999;
+  background: #f7f4ed;
+}
+
+.logo{
+  display: flex;
+  align-items: baseline;
+  padding: 10px 0 20px 50px;
+}
+
+h1{
+  font-family: 'ubuntu-m-webfont';
+  font-size: 36px;
+  margin: 0;
+}
+
+h2{
+  font-family: 'ubuntu-m-webfont';
+  font-size: 14px;
+  margin: 0;
+}
+
+nav{
+  display: flex;
+  height: 20px;
+  font-size: 12px;
+  padding-right: 50px;
+}
+
+ul, li{
+  list-style: none;
+}
+
+nav li{
+  margin: 0 10px;
+  font-family: 'ubuntu-r-webfont';
+}
+
+nav li:nth-child(1){
+  border-left: 1px solid black;
+  border-right: 1px solid black;
+  padding: 0px 10px;
+}
+
+nav li:last-child{
+  background: #4d4b4bff;
+  padding: 0 5px;
+  color: #f7f4ed;
+  border-radius: 3px;
+  text-transform: uppercase;
+  line-height: 1.9;
+  font-size: 10px;
+}
+
+/* main */
+h3{
+  font-family: 'ubuntu-r-webfont';
+  font-size: 10rem;
+  line-height: 9rem;
+}
+
+p{
+  font-family: 'ubuntu-m-webfont';
+  font-size: 12px;
+  line-height: 20px;
+}
+
+button{
+  font-family: 'ubuntu-m-webfont'!important;
+  font-size: 12px!important;
+  border-radius: 5px!important;
+  border: none!important;
+  padding: 8px 12px!important;
+
+}
+
+button[name="join_us"]{
+  background: #69cdcfff;
+  color: #f7f4ed;
+}
+
+#ddb{
+  background: #f7f4ed;
+}
+
+#ddb button[name="join_us"]{
+  position: absolute;
+}
+/* ddb */
+#ddb{
+  height: 100vh;
+}
+
+#ddb h3{
+  pointer-events: none;
+  position: absolute;
+  margin: 130px 0 200px 50px;
+  z-index: 1;
+}
+
+#ddb .content{
+  pointer-events: none;
+  margin: 0 50px;
+}
+
+#ddb .txt{
+  pointer-events: none;
+  position: absolute;
+  width: 500px;
+  font-size: 12px;
+  top: 460px;
+  left: 730px;
+  z-index: 1;
+}
+
+#ddb .txt img{
+  position: relative;
+  top: -30px;
+  left: -290px;
+  z-index: 1;
+}
+
+
+#ddb .txt img:nth-of-type(2) {
+  top: -230px;
+  left: 150%;
+}
+
+#ddb .images{
+  overflow-y: auto;
+  overflow-x: hidden;
+  position: relative;
+  height: 100%;
+}
+
+#ddb .images img{
+  position: absolute;
+  min-width: 100px;
+  height: auto;
+}
+
+#ddb .images img:nth-child(1){
+  top: 85%;
+  left: 70%;
+}
+
+#ddb .images img:nth-child(2){
+  top: 105%;
+  left: 10%;
+}
+
+#ddb .images img:nth-child(3){
+  width: 300px;
+  height: auto;
+  top: 200%;
+  left: 2%;
+}
+
+#ddb .images img:nth-child(4){
+  width: 150px;
+  height: auto;
+  top: 190%;
+  left: 40%;
+}
+
+#ddb .images img:nth-child(5){
+  width: 350px;
+  top: 180%;
+  left: 75%;
+}
+
+#ddb .images img:nth-child(6){
+  top: 230%;
+  left: 25%;
+}
+
+#ddb .images img:nth-child(7){
+  top: 255%;
+  left: 60%;
+}
+
+#ddb .images img:nth-child(8){
+  width: 300px;
+  height: auto;
+  top: 300%;
+  left: 7%;
+}
+
+#ddb .images img:nth-child(9){
+  width: 10%;
+  top: 320%;
+  left: 35%;
+}
+
+.simplebar-track.simplebar-vertical{
+  top: 100px;
+  width: 0px;
+  left: -20px;
+}
+/* scrollbar */
+
+/* video */
+#videos{
+  background: #69cdcfff;
+  height: auto;
+}
+
+.liste_movies{
+  display: flex;
+  flex-flow: column;
+  align-content:center;
+  padding-top: 65px;
+}
+
+.liste_movies ul{
+  width: 65%;
+  display: flex;
+  margin: 20px auto 0 auto ;
+  padding: 0;
+}
+
+.liste_movies ul li{
+  width: 250px;
+  height: auto;
+}
+
+.liste_movies ul li img{
+  width: 100%;
+  height: auto;
+}
+
+.liste_movies img:nth-child(1){
+  width: 65%;
+  height: auto;
+  margin: auto;
+}
+
+.liste_movies li img{
+  filter: grayscale(1);
+  width: 200px;
+  height: auto;
+  margin: 20px 20px 0 0;
+  transition: filter 0.2s;
+}
+
+.liste_movies li img:hover{
+  filter: grayscale(0);
+  transition: filter 0.2s;
+}
+
+/* showrooms */
+#showroom{
+  background: #f7f4ed;
+}
+#showroom{
+  padding: 0px 50px;
+}
+
+#showroom h3{
+  margin: 0;
+}
+
+#showroom .txt{
+  width: 500px;
+}

Some files were not shown because too many files changed in this diff