PageSourceSearch

https://bumainternational.org/js/all5197.js?829423

js bumainternational.org collected 2026-10-07 18:51:04 UTC 26,824 bytes, 796 lines download raw bytes

1$(document).ready(function(){
2    $("#announcement").modal('show');
3});
4
5//document.addEventListener("DOMContentLoaded", function() {
6//if (!sessionStorage.getItem('modalShown')) {
7//	var myModal = new bootstrap.Modal(document.getElementById('announcement'));
8//	myModal.show();
9//	sessionStorage.setItem('modalShown', 'true');
10//}
11//});
12
13$(window).scroll(function() {    
14    var scroll = $(window).scrollTop();
15
16    if (scroll >= 50) {
17        $("header").addClass("sticky");
18    } else {
19        $("header").removeClass("sticky");
20    }
21});
22
23$('.smoothlink').click(function(e){
24  e.preventDefault();
25  var target = $($(this).attr('href'));
26  if(target.length){
27    var scrollTo = target.offset().top -100;
28    $('body, html').animate({scrollTop: scrollTo+'px'}, 800);
29  }
30});
31
32$('.slider').slick({
33    nextArrow: '<i class="fa fa-arrow-circle-right slick-next"></i>',
34    prevArrow: '<i class="fa fa-arrow-circle-left slick-prev"></i>',
35});
36
37$('.home-display-slider').slick({
38	autoplay: true,
39	dots: false,
40	infinite: true,
41	fade: true,
42	cssEase: 'linear',
43	speed: 1000,
44	slidesToShow: 1,
45    pauseOnHover: false,
46    pauseOnFocus: false,
47	arrows: false,
48    nextArrow: '<i class="fa fa-arrow-circle-right slick-next"></i>',
49    prevArrow: '<i class="fa fa-arrow-circle-left slick-prev"></i>'
50});
51
52$('.esg-slider').slick({
53	autoplay: false,
54	dots: false,
55	infinite: true,
56	fade: true,
57	cssEase: 'linear',
58	speed: 1000,
59	slidesToShow: 1,
60	adaptiveHeight: true,
61    pauseOnHover: false,
62    pauseOnFocus: false,
63    nextArrow: '<i class="fa fa-arrow-circle-right slick-next slick-next-dark"></i>',
64    prevArrow: '<i class="fa fa-arrow-circle-left slick-prev slick-prev-dark"></i>'
65});
66
67$('.slideimage').slick({
68	autoplay: true,
69	dots: false,
70	infinite: true,
71	fade: true,
72	cssEase: 'linear',
73	speed: 1000,
74	slidesToShow: 1,
75    pauseOnHover: false,
76    pauseOnFocus: false
77});
78
79$('.career-testi-content').slick({
80	autoplay: false,
81	dots: false,
82	infinite: true,
83	fade: true,
84	cssEase: 'linear',
85	speed: 1000,
86	slidesToShow: 1,
87	adaptiveHeight: true,
88    pauseOnHover: false,
89    pauseOnFocus: false,
90	prevArrow: $('.prev'),
91	nextArrow: $('.next')
92});
93
94$('.career-slider-content').slick({
95	autoplay: true,
96	dots: false,
97	infinite: true,
98	speed: 1000,
99	slidesToShow: 2,
100    pauseOnHover: false,
101    pauseOnFocus: false,
102    nextArrow: '<i class="fa fa-arrow-circle-right slick-next"></i>',
103    prevArrow: '<i class="fa fa-arrow-circle-left slick-prev"></i>'
104});
105
106
107$("#img-ina").click(function(){
108	const $el = $('#img-ina');
109	const $el2 = $('.map');
110	if ($el.hasClass('enlarge-ina')) {
111	  $el.removeClass('enlarge-ina');
112	  $el2.removeClass('enlarge-map');
113	} else {
114	  $el.addClass('enlarge-ina');
115	  $el2.addClass('enlarge-map');
116	}
117});
118$("#img-aus").click(function(){
119	const $el = $('#img-aus');
120	const $el2 = $('.map');
121	if ($el.hasClass('enlarge-aus')) {
122	  $el.removeClass('enlarge-aus');
123	  $el2.removeClass('enlarge-map');
124	} else {
125	  $el.addClass('enlarge-aus');
126	  $el2.addClass('enlarge-map');
127	}
128});
129/*
130$("#img-aus").click(function(){
131	const $el = $('#img-aus');
132	const $el2 = $('.map');
133	if ($el.hasClass('enlarge-aus')) {
134	  $el.removeClass('enlarge-aus');
135	} else {
136	  $el.addClass('enlarge-aus');
137	}
138});
139*/
140
141const accordionBtns = document.querySelectorAll(".accordion");
142
143$(document).ready(function() {
144  $(".set > a").on("click", function() {
145    if ($(this).hasClass("active")) {
146      $(this).removeClass("active");
147      $(this)
148        .siblings(".content")
149        .slideUp(200);
150      $(".set > a i")
151        .removeClass("fa-chevron-up")
152        .addClass("fa-chevron-down");
153    } else {
154      $(".set > a i")
155        .removeClass("fa-chevron-up")
156        .addClass("fa-chevron-down");
157      $(this)
158        .find("i")
159        .removeClass("fa-chevron-down")
160        .addClass("fa-chevron-up");
161      $(".set > a").removeClass("active");
162      $(this).addClass("active");
163      $(".content").slideUp(200);
164      $(this)
165        .siblings(".content")
166        .slideDown(200);
167    }
168  });
169});
170
171// DOM ready.
172$(function () {
173	initHoverBoxes();
174});
175
176function initHoverBoxes() {
177  var $column1 = $('.columnx1');
178  var $column2 = $('.columnx2');
179  
180  $column1.click(function() {
181    $column1.removeClass('col-6');
182    $column1.addClass('col-12');
183    $column2.addClass('gone');
184  });
185  
186  $column1.mouseleave(function() {
187    $column1.removeClass('col-12');
188    $column1.addClass('col-6');
189    $column2.removeClass('gone');
190  });
191  
192  $column2.click(function() {
193    $column2.removeClass('col-6');
194    $column2.addClass('col-12');
195    $column1.addClass('gone');
196  });
197  
198  $column2.mouseleave(function() {
199    $column2.removeClass('col-12');
200    $column2.addClass('col-6');
201    $column1.removeClass('gone');
202  });
203  
204}
205
206
207
208(function() {
209	// Swipe Content Plugin - by CodyHouse.co
210	// https://codyhouse.co/ds/components/info/swipe-content
211	var SwipeContent = function(element) {
212		this.element = element;
213		this.delta = [false, false];
214		this.dragging = false;
215		this.intervalId = false;
216		initSwipeContent(this);
217	};
218
219	function initSwipeContent(content) {
220		content.element.addEventListener('mousedown', handleEvent.bind(content));
221		content.element.addEventListener('touchstart', handleEvent.bind(content));
222	};
223
224	function initDragging(content) {
225		//add event listeners
226		content.element.addEventListener('mousemove', handleEvent.bind(content));
227		content.element.addEventListener('touchmove', handleEvent.bind(content));
228		content.element.addEventListener('mouseup', handleEvent.bind(content));
229		content.element.addEventListener('mouseleave', handleEvent.bind(content));
230		content.element.addEventListener('touchend', handleEvent.bind(content));
231	};
232
233	function cancelDragging(content) {
234		//remove event listeners
235		if(content.intervalId) {
236			(!window.requestAnimationFrame) ? clearInterval(content.intervalId) : window.cancelAnimationFrame(content.intervalId);
237			content.intervalId = false;
238		}
239		content.element.removeEventListener('mousemove', handleEvent.bind(content));
240		content.element.removeEventListener('touchmove', handleEvent.bind(content));
241		content.element.removeEventListener('mouseup', handleEvent.bind(content));
242		content.element.removeEventListener('mouseleave', handleEvent.bind(content));
243		content.element.removeEventListener('touchend', handleEvent.bind(content));
244	};
245
246	function handleEvent(event) {
247		switch(event.type) {
248			case 'mousedown':
249			case 'touchstart':
250				startDrag(this, event);
251				break;
252			case 'mousemove':
253			case 'touchmove':
254				drag(this, event);
255				break;
256			case 'mouseup':
257			case 'mouseleave':
258			case 'touchend':
259				endDrag(this, event);
260				break;
261		}
262	};
263
264	function startDrag(content, event) {
265		content.dragging = true;
266		// listen to drag movements
267		initDragging(content);
268		content.delta = [parseInt(unify(event).clientX), parseInt(unify(event).clientY)];
269		// emit drag start event
270		emitSwipeEvents(content, 'dragStart', content.delta);
271	};
272
273	function endDrag(content, event) {
274		cancelDragging(content);
275		// credits: https://css-tricks.com/simple-swipe-with-vanilla-javascript/
276		var dx = parseInt(unify(event).clientX), 
277	    dy = parseInt(unify(event).clientY);
278	  
279	  // check if there was a left/right swipe
280		if(content.delta && (content.delta[0] || content.delta[0] === 0)) {
281	    var s = Math.sign(dx - content.delta[0]);
282			
283			if(Math.abs(dx - content.delta[0]) > 30) {
284				(s < 0) ? emitSwipeEvents(content, 'swipeLeft', [dx, dy]) : emitSwipeEvents(content, 'swipeRight', [dx, dy]);	
285			}
286	    
287	    content.delta[0] = false;
288	  }
289		// check if there was a top/bottom swipe
290	  if(content.delta && (content.delta[1] || content.delta[1] === 0)) {
291	  	var y = Math.sign(dy - content.delta[1]);
292
293	  	if(Math.abs(dy - content.delta[1]) > 30) {
294	    	(y < 0) ? emitSwipeEvents(content, 'swipeUp', [dx, dy]) : emitSwipeEvents(content, 'swipeDown', [dx, dy]);
295	    }
296
297	    content.delta[1] = false;
298	  }
299		// emit drag end event
300	  emitSwipeEvents(content, 'dragEnd', [dx, dy]);
301	  content.dragging = false;
302	};
303
304	function drag(content, event) {
305		if(!content.dragging) return;
306		// emit dragging event with coordinates
307		(!window.requestAnimationFrame) 
308			? content.intervalId = setTimeout(function(){emitDrag.bind(content, event);}, 250) 
309			: content.intervalId = window.requestAnimationFrame(emitDrag.bind(content, event));
310	};
311
312	function emitDrag(event) {
313		emitSwipeEvents(this, 'dragging', [parseInt(unify(event).clientX), parseInt(unify(event).clientY)]);
314	};
315
316	function unify(event) { 
317		// unify mouse and touch events
318		return event.changedTouches ? event.changedTouches[0] : event; 
319	};
320
321	function emitSwipeEvents(content, eventName, detail) {
322		// emit event with coordinates
323		var event = new CustomEvent(eventName, {detail: {x: detail[0], y: detail[1]}});
324		content.element.dispatchEvent(event);
325	};
326
327	window.SwipeContent = SwipeContent;
328	
329	//initialize the SwipeContent objects
330	var swipe = document.getElementsByClassName('js-swipe-content');
331	if( swipe.length > 0 ) {
332		for( var i = 0; i < swipe.length; i++) {
333			(function(i){new SwipeContent(swipe[i]);})(i);
334		}
335	}
336}());
337
338// Utility function
339function Util () {};
340
341/*
342	class manipulation functions
343*/
344Util.hasClass = function(el, className) {
345	if (el.classList) return el.classList.contains(className);
346	else return !!el.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
347};
348
349Util.addClass = function(el, className) {
350	var classList = className.split(' ');
351 	if (el.classList) el.classList.add(classList[0]);
352 	else if (!Util.hasClass(el, classList[0])) el.className += " " + classList[0];
353 	if (classList.length > 1) Util.addClass(el, classList.slice(1).join(' '));
354};
355
356Util.removeClass = function(el, className) {
357	var classList = className.split(' ');
358	if (el.classList) el.classList.remove(classList[0]);
359	else if(Util.hasClass(el, classList[0])) {
360		var reg = new RegExp('(\\s|^)' + classList[0] + '(\\s|$)');
361		el.className=el.className.replace(reg, ' ');
362	}
363	if (classList.length > 1) Util.removeClass(el, classList.slice(1).join(' '));
364};
365
366Util.toggleClass = function(el, className, bool) {
367	if(bool) Util.addClass(el, className);
368	else Util.removeClass(el, className);
369};
370
371Util.setAttributes = function(el, attrs) {
372  for(var key in attrs) {
373    el.setAttribute(key, attrs[key]);
374  }
375};
376
377/*
378  DOM manipulation
379*/
380Util.getChildrenByClassName = function(el, className) {
381  var children = el.children,
382    childrenByClass = [];
383  for (var i = 0; i < el.children.length; i++) {
384    if (Util.hasClass(el.children[i], className)) childrenByClass.push(el.children[i]);
385  }
386  return childrenByClass;
387};
388
389/*
390	Animate height of an element
391*/
392Util.setHeight = function(start, to, element, duration, cb) {
393	var change = to - start,
394	    currentTime = null;
395
396  var animateHeight = function(timestamp){
397    if (!currentTime) currentTime = timestamp;
398    var progress = timestamp - currentTime;
399    var val = parseInt((progress/duration)*change + start);
400    element.setAttribute("style", "height:"+val+"px;");
401    if(progress < duration) {
402        window.requestAnimationFrame(animateHeight);
403    } else {
404    	cb();
405    }
406  };
407
408  //set the height of the element before starting animation -> fix bug on Safari
409  element.setAttribute("style", "height:"+start+"px;");
410  window.requestAnimationFrame(animateHeight);
411};
412
413/*
414	Smooth Scroll
415*/
416
417Util.scrollTo = function(final, duration, cb) {
418  var start = window.scrollY || document.documentElement.scrollTop,
419      currentTime = null;
420
421  var animateScroll = function(timestamp){
422  	if (!currentTime) currentTime = timestamp;
423    var progress = timestamp - currentTime;
424    if(progress > duration) progress = duration;
425    var val = Math.easeInOutQuad(progress, start, final-start, duration);
426    window.scrollTo(0, val);
427    if(progress < duration) {
428        window.requestAnimationFrame(animateScroll);
429    } else {
430      cb && cb();
431    }
432  };
433
434  window.requestAnimationFrame(animateScroll);
435};
436
437/*
438  Focus utility classes
439*/
440
441//Move focus to an element
442Util.moveFocus = function (element) {
443  if( !element ) element = document.getElementsByTagName("body")[0];
444  element.focus();
445  if (document.activeElement !== element) {
446    element.setAttribute('tabindex','-1');
447    element.focus();
448  }
449};
450
451/*
452  Misc
453*/
454
455Util.getIndexInArray = function(array, el) {
456  return Array.prototype.indexOf.call(array, el);
457};
458
459Util.cssSupports = function(property, value) {
460  if('CSS' in window) {
461    return CSS.supports(property, value);
462  } else {
463    var jsProperty = property.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase();});
464    return jsProperty in document.body.style;
465  }
466};
467
468/*
469	Polyfills
470*/
471//Closest() method
472if (!Element.prototype.matches) {
473	Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
474}
475
476if (!Element.prototype.closest) {
477	Element.prototype.closest = function(s) {
478		var el = this;
479		if (!document.documentElement.contains(el)) return null;
480		do {
481			if (el.matches(s)) return el;
482			el = el.parentElement || el.parentNode;
483		} while (el !== null && el.nodeType === 1);
484		return null;
485	};
486}
487
488//Custom Event() constructor
489if ( typeof window.CustomEvent !== "function" ) {
490
491  function CustomEvent ( event, params ) {
492    params = params || { bubbles: false, cancelable: false, detail: undefined };
493    var evt = document.createEvent( 'CustomEvent' );
494    evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
495    return evt;
496  }
497
498  CustomEvent.prototype = window.Event.prototype;
499
500  window.CustomEvent = CustomEvent;
501}
502
503/*
504	Animation curves
505*/
506Math.easeInOutQuad = function (t, b, c, d) {
507	t /= d/2;
508	if (t < 1) return c/2*t*t + b;
509	t--;
510	return -c/2 * (t*(t-2) - 1) + b;
511};
512
513
514/* Main js */
515/* -----------------*/
516(function() {
517  // Horizontal Timeline - by CodyHouse.co
518  var HorizontalTimeline = function(element) {
519		this.element = element;
520		this.datesContainer = this.element.getElementsByClassName('h--timeline-dates')[0];
521		this.line = this.datesContainer.getElementsByClassName('h--timeline-line')[0]; // grey line in the top timeline section
522		this.fillingLine = this.datesContainer.getElementsByClassName('h--timeline-filling-line')[0]; // green filling line in the top timeline section
523		this.date = this.line.getElementsByClassName('h--timeline-date');
524		this.selectedDate = this.line.getElementsByClassName('h--timeline-date--selected')[0];
525		this.dateValues = parseDate(this);
526		this.minLapse = calcMinLapse(this);
527		this.navigation = this.element.getElementsByClassName('h--timeline-navigation');
528		this.contentWrapper = this.element.getElementsByClassName('h--timeline-events')[0];
529		this.content = this.contentWrapper.getElementsByClassName('h--timeline-event');
530
531		this.eventsMinDistance = 80; // min distance between two consecutive events (in px)
532		this.eventsMaxDistance = 120; // max distance between two consecutive events (in px)
533		this.translate = 0; // this will be used to store the translate value of this.line
534		this.lineLength = 0; //total length of this.line
535
536		// store index of selected and previous selected dates
537		this.oldDateIndex = Util.getIndexInArray(this.date, this.selectedDate);
538		this.newDateIndex = this.oldDateIndex;
539
540		initTimeline(this);
541		initEvents(this);
542  };
543
544  function initTimeline(timeline) {
545  	// set dates left position
546  	var left = 0;
547		for (var i = 0; i < timeline.dateValues.length; i++) {
548			var j = (i == 0) ? 0 : i - 1;
549	    var distance = daydiff(timeline.dateValues[j], timeline.dateValues[i]),
550	    	distanceNorm = (Math.round(distance/timeline.minLapse) + 2)*timeline.eventsMinDistance,
551			containerWidth = timeline.datesContainer.offsetWidth,
552			distanceCorrecture = 0;
553
554	    if(distanceNorm < timeline.eventsMinDistance) {
555	    	distanceNorm = timeline.eventsMaxDistance;
556	    } else if(distanceNorm > timeline.eventsMaxDistance) {
557	    	distanceNorm = timeline.eventsMinDistance;
558	    }
559	    left = left + distanceNorm;
560	    timeline.date[i].setAttribute('style', 'left:' + left+'px');
561		}
562
563		// set line/filling line dimensions
564		timeline.line.style.width = (left + timeline.eventsMinDistance)+distanceCorrecture+'px';
565		timeline.lineLength = left + timeline.eventsMinDistance+distanceCorrecture;
566	  
567		// add 100px more to line/filling line if container bigger then timeline lineLength
568		if(containerWidth > timeline.lineLength) {
569		  timeline.line.style.width = (left + timeline.eventsMinDistance)+distanceCorrecture+'px';
570		  timeline.lineLength = timeline.lineLength + distanceCorrecture;
571		}
572	  
573		// reveal timeline
574		Util.addClass(timeline.element, 'h--timeline--loaded');
575		selectNewDate(timeline, timeline.selectedDate);
576		resetTimelinePosition(timeline, 'next');
577  };
578
579  function initEvents(timeline) {
580  	var self = timeline;
581		// deaktivate the buttons
582		deaktivateNavigationButtons(self);
583	  
584		// click on arrow navigation
585		self.navigation[0].addEventListener('click', function(event){
586			event.preventDefault();
587			translateTimeline(self, 'prev');
588			deaktivateNavigationButtons(self);
589		});
590		self.navigation[1].addEventListener('click', function(event){
591			event.preventDefault();
592			translateTimeline(self, 'next');
593			deaktivateNavigationButtons(self);
594		});
595
596		//swipe on timeline
597		new SwipeContent(self.datesContainer);
598		self.datesContainer.addEventListener('swipeLeft', function(event){
599			translateTimeline(self, 'next');
600		});
601		self.datesContainer.addEventListener('swipeRight', function(event){
602			translateTimeline(self, 'prev');
603		}); 
604
605		//select a new event
606		for(var i = 0; i < self.date.length; i++) {
607			(function(i){
608				self.date[i].addEventListener('click', function(event){
609					event.preventDefault();
610					selectNewDate(self, event.target);
611				});
612
613				self.content[i].addEventListener('animationend', function(event){
614					if( i == self.newDateIndex && self.newDateIndex != self.oldDateIndex) resetAnimation(self);
615				});
616			})(i);
617		}
618  };
619
620  function updateFilling(timeline) { // update fillingLine scale value
621		var dateStyle = window.getComputedStyle(timeline.selectedDate, null),
622			left = dateStyle.getPropertyValue("left"),
623			width = dateStyle.getPropertyValue("width");
624
625		left = Number(left.replace('px', '')) + Number(width.replace('px', ''))/2;
626		timeline.fillingLine.style.transform = 'scaleX('+(left/timeline.lineLength)+')';
627	};
628
629  function translateTimeline(timeline, direction) { // translate timeline (and date elements)
630  	var containerWidth = timeline.datesContainer.offsetWidth;
631  	if(direction) {
632  		timeline.translate = (direction == 'next') ? timeline.translate - containerWidth + timeline.eventsMinDistance : timeline.translate + containerWidth - timeline.eventsMinDistance;
633  	}
634    if( 0 - timeline.translate > timeline.lineLength - containerWidth ) timeline.translate = containerWidth - timeline.lineLength;
635    if( timeline.translate > 0 ) timeline.translate = 0;
636
637    timeline.line.style.transform = 'translateX('+timeline.translate+'px)';
638    // update the navigation items status (toggle inactive class)
639		(timeline.translate == 0 ) ? Util.addClass(timeline.navigation[0], 'h--timeline-navigation--inactive') : 
639Util.removeClass(timeline.navigation[0], 'h--timeline-navigation--inactive');
640		(timeline.translate == containerWidth - timeline.lineLength ) ? Util.addClass(timeline.navigation[1], 'h--timeline-navigation--inactive') : Util.removeClass(timeline.navigation[1], 'h--timeline-navigation--inactive');
641  };
642	
643	function deaktivateNavigationButtons(timeline) {
644    var containerWidth = timeline.datesContainer.offsetWidth;
645    // deaktivate next button if container bigger then timeline lineLength
646    if(containerWidth >= timeline.lineLength) {
647			Util.addClass(timeline.navigation[0], 'h--timeline-navigation--inactive');
648			Util.addClass(timeline.navigation[1], 'h--timeline-navigation--inactive');
649		}
650	};
651
652	function selectNewDate(timeline, target) { // ned date has been selected -> update timeline
653		timeline.newDateIndex = Util.getIndexInArray(timeline.date, target);
654		timeline.oldDateIndex = Util.getIndexInArray(timeline.date, timeline.selectedDate);
655		Util.removeClass(timeline.selectedDate, 'h--timeline-date--selected');
656		Util.addClass(timeline.date[timeline.newDateIndex], 'h--timeline-date--selected');
657		timeline.selectedDate = timeline.date[timeline.newDateIndex];
658		updateOlderEvents(timeline);
659		updateVisibleContent(timeline);
660		updateFilling(timeline);
661	};
662
663	function updateOlderEvents(timeline) { // update older events style
664		for(var i = 0; i < timeline.date.length; i++) {
665			(i < timeline.newDateIndex) ? Util.addClass(timeline.date[i], 'h--timeline-date--older-event') : Util.removeClass(timeline.date[i], 'h--timeline-date--older-event');
666		}
667	};
668
669	function updateVisibleContent(timeline) { // show content of new selected date
670		if (timeline.newDateIndex > timeline.oldDateIndex) {
671			var classEntering = 'h--timeline-event--selected h--timeline-event--enter-right',
672				classLeaving = 'h--timeline-event--leave-left';
673		} else if(timeline.newDateIndex < timeline.oldDateIndex) {
674			var classEntering = 'h--timeline-event--selected h--timeline-event--enter-left',
675				classLeaving = 'h--timeline-event--leave-right';
676		} else {
677			var classEntering = 'h--timeline-event--selected',
678				classLeaving = '';
679		}
680
681		Util.addClass(timeline.content[timeline.newDateIndex], classEntering);
682		if (timeline.newDateIndex != timeline.oldDateIndex) {
683			Util.removeClass(timeline.content[timeline.oldDateIndex], 'h--timeline-event--selected');
684			Util.addClass(timeline.content[timeline.oldDateIndex], classLeaving);
685			//timeline.contentWrapper.style.height = timeline.content[timeline.newDateIndex].offsetHeight + 'px';
686		}
687	};
688
689	function resetAnimation(timeline) { // reset content classes when entering animation is over
690		//timeline.contentWrapper.style.height = null;
691		Util.removeClass(timeline.content[timeline.newDateIndex], 'h--timeline-event--enter-right h--timeline-event--enter-left');
692		Util.removeClass(timeline.content[timeline.oldDateIndex], 'h--timeline-event--leave-right h--timeline-event--leave-left');
693	};
694
695	function keyNavigateTimeline(timeline, direction) { // navigate the timeline using the keyboard
696		var newIndex = (direction == 'next') ? timeline.newDateIndex + 1 : timeline.newDateIndex - 1;
697		if(newIndex < 0 || newIndex >= timeline.date.length) return;
698		selectNewDate(timeline, timeline.date[newIndex]);
699		resetTimelinePosition(timeline, direction);
700	};
701
702	function resetTimelinePosition(timeline, direction) { //translate timeline according to new selected event position
703		var eventStyle = window.getComputedStyle(timeline.selectedDate, null),
704			eventLeft = Number(eventStyle.getPropertyValue('left').replace('px', '')),
705			timelineWidth = timeline.datesContainer.offsetWidth;
706
707    if( (direction == 'next' && eventLeft >= timelineWidth - timeline.translate) || (direction == 'prev' && eventLeft <= - timeline.translate) ) {
708    	timeline.translate = timelineWidth/2 - eventLeft;
709    	translateTimeline(timeline, false);
710    }
711  };
712
713  function parseDate(timeline) { // get timestamp value for each date
714		var dateArrays = [];
715		for(var i = 0; i < timeline.date.length; i++) {
716			var singleDate = timeline.date[i].getAttribute('data-date'),
717				dateComp = singleDate.split('T');
718
719			if( dateComp.length > 1 ) { //both DD/MM/YEAR and time are provided
720				var dayComp = dateComp[0].split('/'),
721					timeComp = dateComp[1].split(':');
722			} else if( dateComp[0].indexOf(':') >=0 ) { //only time is provide
723				var dayComp = ["2000", "0", "0"],
724					timeComp = dateComp[0].split(':');
725			} else { //only DD/MM/YEAR
726				var dayComp = dateComp[0].split('/'),
727					timeComp = ["0", "0"];
728			}
729			var	newDate = new Date(dayComp[2], dayComp[1]-1, dayComp[0], timeComp[0], timeComp[1]);
730			dateArrays.push(newDate);
731		}
732	  return dateArrays;
733  };
734
735  function calcMinLapse(timeline) { // determine the minimum distance among events
736		var dateDistances = [];
737		for(var i = 1; i < timeline.dateValues.length; i++) {
738	    var distance = daydiff(timeline.dateValues[i-1], timeline.dateValues[i]);
739	    if(distance > 0) dateDistances.push(distance);
740		}
741
742		return (dateDistances.length > 0 ) ? Math.min.apply(null, dateDistances) : 86400000;
743	};
744
745	function daydiff(first, second) { // time distance between events
746		return Math.round((second-first));
747	};
748
749  window.HorizontalTimeline = HorizontalTimeline;
750
751  var horizontalTimeline = document.getElementsByClassName('js-h--timeline'),
752  	horizontalTimelineTimelineArray = [];
753  if(horizontalTimeline.length > 0) {
754		for(var i = 0; i < horizontalTimeline.length; i++) {
755			horizontalTimelineTimelineArray.push(new HorizontalTimeline(horizontalTimeline[i]));
756		}
757		// navigate the timeline when inside the viewport using the keyboard
758		document.addEventListener('keydown', function(event){
759			if( (event.keyCode && event.keyCode == 39) || ( event.key && event.key.toLowerCase() == 'arrowright') ) {
760				updateHorizontalTimeline('next'); // move to next event
761			} else if((event.keyCode && event.keyCode == 37) || ( event.key && event.key.toLowerCase() == 'arrowleft')) {
762				updateHorizontalTimeline('prev'); // move to prev event
763			}
764		});
765  };
766
767  function updateHorizontalTimeline(direction) {
768		for(var i = 0; i < horizontalTimelineTimelineArray.length; i++) {
769			if(elementInViewport(horizontalTimeline[i])) keyNavigateTimeline(horizontalTimelineTimelineArray[i], direction);
770		}
771  };
772
773  /*
774		How to tell if a DOM element is visible in the current viewport?
775		http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
776	*/
777	function elementInViewport(el) {
778		var top = el.offsetTop;
779		var left = el.offsetLeft;
780		var width = el.offsetWidth;
781		var height = el.offsetHeight;
782
783		while(el.offsetParent) {
784		    el = el.offsetParent;
785		    top += el.offsetTop;
786		    left += el.offsetLeft;
787		}
788
789		return (
790		    top < (window.pageYOffset + window.innerHeight) &&
791		    left < (window.pageXOffset + window.innerWidth) &&
792		    (top + height) > window.pageYOffset &&
793		    (left + width) > window.pageXOffset
794		);
795	}
796}());

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