PageSourceSearch

https://www.e-flux.com/js/main.js?104

js e-flux.com collected 2026-09-24 08:25:41 UTC 153,990 bytes, 5,127 lines download raw bytes

1/*
2	<PROJECT>
3	Copyright (C) 2020 by Systemantics, Bureau for Informatics
4
5	Systemantics GmbH
6	Hausbroicher Str. 218
7	47877 Willich
8	GERMANY
9
10	Web:    www.systemantics.net
11	Email:  [email protected]
12
13	Permission granted to use the files associated with this
14	website only on your webserver.
15
16	Changes to these files are PROHIBITED due to license restrictions.
17*/
18
19// Detect touch device
20
21const fadeDuration = 200
22
23let overlayerLoaded = false
24
25const isTouch = 'ontouchstart' in document
26const noTouch = !isTouch
27
28function isMobile() {
29  if (!$('#bp').length) {
30    $('<div id="bp"/>').appendTo('body')
31  }
32
33  return $('#bp').width() == 1
34}
35function onOverlayerSubmit(token) {
36  $("<input>").attr({
37    type: "hidden",
38    name: "g-recaptcha-response",
39    value: token
40  }).appendTo("#subscribeForm");
41
42  // Now trigger the AJAX form submission
43  $("#subscribeForm").submit();
44}
45
46function isSafari() {
47  if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent.toLowerCase())) {
48    return true
49  }
50
51  return false
52}
53$(document).on("click",".mute_wrap .mute",function (){
54
55  $(this).toggleClass("active")
56   $(this).siblings("video").prop('muted', !$(this).siblings("video").prop('muted'))
57
58})
59function carouselArticlePreInit() {
60  $('.js-carousel').each(function () {
61    const carousel = $(this)
62    const container = carousel.closest('.block-media')
63    const placeholder = container.find('.block-carousel-placeholder')
64    const carouselArrows = container.find('.block-carousel-arrows')
65    const containerHeight = $(window).height() - 300
66
67    if (isMobile()) {
68      let maxRatio = 1
69      const maxWidth = placeholder.width()
70      const space = parseInt(placeholder.css('padding-right'))
71
72      // get largest image ratio
73      carousel.find('.article-carousel__cell').each(function () {
74        const el = $(this)
75
76        if (maxRatio < el.data('ratio')) {
77          maxRatio = el.data('ratio')
78        }
79      })
80
81      const newHeight = maxWidth * 1 / maxRatio
82
83      carousel.find('.block-carousel-cell').each(function () {
84        const el = $(this)
85        const elImage = el.find('.block-carousel-cell-image')
86
87        el.css({
88          'margin-right': space,
89          width: maxWidth
90        })
91
92        elImage.css({
93          height: newHeight,
94          width: newHeight * el.data('ratio')
95        })
96      })
97
98      carousel.css({
99        left: placeholder.offset().left
100      })
101    } else {
102      const maxHeight = Math.max(450, $(window).height() - 276)
103      const maxWidth = placeholder.width();
104      const // $(window).width() - 384,
105        maxRatio = maxWidth / maxHeight
106      const space = parseInt(placeholder.css('padding-right'))
107
108      carousel.css({
109        left: placeholder.offset().left
110      })
111
112      heighestImage = 0
113      carousel.find('.block-carousel-cell').each(function () {
114        const el = $(this)
115        const elImage = el.find('.block-carousel-image')
116
117        if (el.data('ratio') < maxRatio) {
118          // fit height
119          elWidth = maxHeight * el.data('ratio')
120          eheight = maxHeight
121        } else {
122          // fit width
123          elWidth = maxWidth// * 1 / el.data('ratio');
124          eheight = maxWidth * 1 / el.data('ratio')
125        }
126
127        if (heighestImage < eheight) {
128          heighestImage = eheight
129        }
130
131        el.css({
132          width: elWidth,
133          'margin-right': space
134        })
135
136        elImage.css({
137          height: '',
138          width: ''
139        })
140      })
141
142      carouselArrows.css('top', 'calc(' + heighestImage + 'px + .7rem)')
143    }
144
145    if (!carousel.hasClass('flickity-enabled')) {
146      setTimeout(function () {
147        carouselArticleInit(carousel)
148      }, 150)
149    }
150    ;
151  })
152}
153
154function carouselArticleInit(carousel) {
155  carousel.flickity({
156    setGallerySize: true,
157    pageDots: false,
158    prevNextButtons: false,
159    cellAlign: 'left',
160    wrapAround: false,
161    draggable: !!isMobile(),
162    on: {
163      change: function () {
164        const flkty = $(this)[0]
165        const container = $(flkty.element).closest('.block-media')
166
167        if (flkty.selectedIndex != 0) {
168          container.find('.block-carousel-arrow--prev').removeClass('block-carousel-arrow--hidden')
169        } else {
170          container.find('.block-carousel-arrow--prev').addClass('block-carousel-arrow--hidden')
171        }
172
173        if (flkty.selectedIndex < flkty.cells.length - 1) {
174          container.find('.block-carousel-arrow--next').removeClass('block-carousel-arrow--hidden')
175        } else {
176          container.find('.block-carousel-arrow--next').addClass('block-carousel-arrow--hidden')
177        }
178
179        const mobileCaption = container.find('.block-carousel-caption-mobile')
180        const currentCaption = $(flkty.selectedElement).find('.block-carousel-caption')
181
182        if (currentCaption.length) {
183          mobileCaption.addClass('block-carousel-caption-mobile--visible')
184          mobileCaption.html(currentCaption.html())
185        } else {
186          mobileCaption.removeClass('block-carousel-caption-mobile--visible')
187          mobileCaption.html('')
188        }
189      }
190    }
191  })
192}
193
194function carouselHomepageJournal() {
195  const carousels = $('.js-homepage-carousel')
196
197  if (carousels.length) {
198    carousels.each(function () {
199      const carousel = $(this)
200      let autoHeight = true
201      let dots = false
202
203      if (carousel.hasClass('homepage-carousel--announcements')) {
204        autoHeight = false
205        dots = true
206
207        carousel.find('.homepage-carousel__cell').css('width', carousel.width())
208      } else {
209        carousel.find('.homepage-carousel__cell').css('width', $(window).width())
210      }
211
212      if (!carousel.hasClass('flickity-enabled')) {
213        carousel.flickity({
214          adaptiveHeight: autoHeight,
215          setGallerySize: true,
216          pageDots: dots,
217          prevNextButtons: false,
218          cellAlign: 'left',
219          wrapAround: false,
220          draggable: !!isMobile(),
221          on: {
222            change: function () {
223              const flkty = $(this)[0]
224              const container = $(flkty.element).closest('.homepage-section')
225              const arrows = container.find('.homepage-arrows')
226
227              if (flkty.selectedIndex == 0) {
228                arrows.removeClass('homepage-arrows--arrow-left-show')
229              } else {
230                arrows.addClass('homepage-arrows--arrow-left-show')
231              }
232
233              if (flkty.selectedIndex == flkty.slides.length - 1) {
234                arrows.removeClass('homepage-arrows--arrow-right-show')
235              } else {
236                arrows.addClass('homepage-arrows--arrow-right-show')
237              }
238            }
239          }
240        })
241      }
242    })
243  }
244}
245
246function fitFeaturedCarouselImages(carousel) {
247  carousel.find('.featured-projects__cell--fit').each(function () {
248    const cell = $(this)
249    const image = cell.find('.js-fit-featured-carousel-image')
250
251    cell.find('.featured-projects__gradient').width(image.find('img').height() * image.data('ratio'))
252  })
253  // carousel.find('.featured-projects__cell').each(function () {
254  //   const cell = $(this)
255
256  //   if (cell.hasClass('featured-projects__cell--fit')) {
257  //     const area = cell.find('.featured-projects__cell-area')
258  //     const image = cell.find('.js-fit-featured-carousel-image')
259  //     const content = cell.find('.featured-projects__cell-content')
260
261  //     const areaHeight = content.offset().top - area.position().top - cell.offset().top
262  //     const areaWidth = area.width()
263
264  //     const minRatio = Math.min(1, areaWidth / image.data('width'), areaHeight / image.data('height'))
265
266  //     area.css('height', areaHeight)
267  //     image.css({
268  //       height: Math.floor(minRatio * image.data('height')),
269  //       width: Math.floor(minRatio * image.data('width'))
270  //     })
271  //   }
272  // })
273}
274
275function featuredCarouselContentWidth() {
276
277  const container = $('.featured-projects__inner')
278  const slides = $('.js-featured-projects__cell--fit')
279
280  if (slides.length) {
281    slides.each(function () {
282      const cell = $(this)
283      const image = cell.find('.js-fit-featured-carousel-image')
284      const content = cell.find('.featured-projects__cell-content')
285
286      let width = (container.height() * image.data('ratio')) - 20
287
288      let space = 0
289      if (isMobile()) {
290        space = 30
291      }
292
293      if (container.width() > width + space) {
294        content.css('width', width + 'px')
295      } else {
296        content.css('width', '')
297      }
298    })
299  }
300}
301
302
303function projectsCarouselInit() {
304
305  featuredCarouselContentWidth()
306
307  $('.js-carousel-projects').each(function () {
308    const carousel = $(this)
309    const slides = carousel.find('.featured-projects__cell')
310    let showDots = false
311
312    if (slides.length > 1) {
313      showDots = true
314    } else {
315      carousel.addClass('featured-projects__carousel--single')
316    }
317
318    carousel.flickity({
319      setGallerySize: false,
320      pageDots: showDots,
321      prevNextButtons: false,
322      cellAlign: 'center',
323      wrapAround: false,
324      fade: true,
325      on: {
326        ready: function () {
327          flkty = $(this)[0]
328
329          $(flkty.element).addClass('featured-projects__carousel--ready')
330
331          fitFeaturedCarouselImages(carousel)
332        }
333      }
334    })
335  })
336
337  $('.js-carousel-videos').each(function () {
338    const carousel = $(this)
339    const slides = carousel.find('.video-featured__item')
340    let dots = true
341
342    if (slides.length = 1) {
343      dots = false
344    }
345
346    carousel.flickity({
347      setGallerySize: isMobile(),
348      pageDots: dots,
349      prevNextButtons: false,
350      cellAlign: 'center',
351      wrapAround: false,
352      fade: true,
353      on: {
354        ready: function () {
355          const flkty = $(this)[0]
356          const currentCell = $(flkty.selectedElement)
357
358          videoSlideColor(currentCell)
359        },
360        change: function () {
361          const flkty = $(this)[0]
362          const currentCell = $(flkty.selectedElement)
363
364          videoSlideColor(currentCell)
365        }
366      }
367    })
368  })
369}
370
371projectsCarouselInit()
372
373// waitForElement('.js-carousel-projects', 10000).then(function () {
374//
375// }).catch(()=> {
376//   alert("Project carousel was not loaded");
377// });
378
379function videoSlideColor(currentCell) {
380  currentCell.closest('.homepage-section--video').removeClass('homepage-section--video-w
380hite homepage-section--video-black')
381
382  if (currentCell.hasClass('video-featured__item--white')) {
383    currentCell.closest('.homepage-section--video').addClass('homepage-section--video-white')
384  } else if (currentCell.hasClass('video-featured__item--black')) {
385    currentCell.closest('.homepage-section--video').addClass('homepage-section--video-black')
386  }
387}
388
389function initMap(fromComponent = false) {
390  if ($('#anchor_map').length) {
391    console.log('Anchor map block firing');
392
393    const activeIcon = {
394      url: '/elements/EFL03_red-pin.svg'
395    }
396
397    const normalIcon = {
398      url: '/elements/EFL03_black-pin.svg'
399    }
400
401    $('#anchor_map').each(function () {
402      const el = $(this)
403
404      // infoWindows = [];
405      const markers = []
406
407      const myLatlng = new google.maps.LatLng(28.4387675, 77.5243212)
408      const mapOptions = {
409        title: 'map',
410        scrollwheel: false,
411        navigationControl: false,
412        mapTypeControl: false,
413        scaleControl: false,
414        streetViewControl: false,
415        draggable: true,
416        fullscreenControl: false,
417        clickableIcons: false,
418        panControl: true,
419        zoomControl: true,
420        zoomControlOptions: {
421          style: google.maps.ZoomControlStyle.LARGE,
422          position: google.maps.ControlPosition.LEFT_CENTER
423        },
424
425        gestureHandling: 'greedy'
426      }
427
428      const map = new google.maps.Map(document.getElementById('anchor_map'), mapOptions)
429      const getMarkers = $('#anchor_map').data('markers')
430      var bounds = []
431      var bounds = new google.maps.LatLngBounds()
432
433      $.each(getMarkers, function (i, item) {
434        const latlng = new google.maps.LatLng(item[1], item[2])
435
436        bounds.extend(latlng)
437
438        const marker = new google.maps.Marker({
439          position: latlng,
440          map: map,
441          title: item[0],
442          icon: '/elements/EFL03_black-pin.svg'
443        })
444
445        marker.addListener('click', function (e) {
446          const pupup = $('.popup[data-id="' + $(this)[0].title + '"]')
447
448          for (let j = 0; j < markers.length; j++) {
449            markers[j].setIcon(normalIcon)
450          }
451
452          if (pupup.hasClass('popup--active')) {
453            pupup.removeClass('popup--active')
454          } else {
455            const activePopup = $('.popup.popup--active')
456
457            if (activePopup.length) {
458              if (activePopup.hasClass('popup--grouped')) {
459                activePopup.addClass('popup--active-grouped-close')
460
461                setTimeout(function () {
462                  activePopup.removeClass('popup--active popup--grouped popup--active-grouped-close')
463                }, 200)
464              } else {
465                activePopup.removeClass('popup--active')
466              }
467            }
468
469            $('.clustermarker--selected').css('background', '#000').removeClass('clustermarker--selected')
470
471            pupup.addClass('popup--active')
472            this.setIcon(activeIcon)
473          }
474        })
475
476        markers.push(marker)
477      })
478
479      const markerCluster = new MarkerClusterer(map, markers, {
480        styles: [{
481          textColor: 'white',
482          textSize: 15,
483          height: 40,
484          width: 40
485        }]
486      })
487
488      map.fitBounds(bounds)
489
490      // set new Zoom after bounds markers
491      var listener = google.maps.event.addListener(map, 'idle', function () {
492        if (map.getZoom() > 16) map.setZoom(16)
493        google.maps.event.removeListener(listener)
494      })
495
496      $('.js-popup-close').on('click', function () {
497        const popup = $(this).closest('.popup')
498
499        $(this).closest('.popups').find('.popup--grouped').not(popup).removeClass('popup--grouped')
500
501        if (popup.hasClass('popup--grouped')) {
502          popup.addClass('popup--active-grouped-close')
503        }
504
505        $('.clustermarker--selected').css('background', '#000').removeClass('clustermarker--selected')
506
507        setTimeout(function () {
508          if (popup.hasClass('popup--grouped')) {
509            setTimeout(function () {
510              popup.removeClass('popup--active popup--grouped popup--active-grouped-close')
511            }, 200)
512
513            $('.popups').removeClass('popups--is-grouped')
514          } else {
515            popup.removeClass('popup--active')
516          }
517
518          for (let j = 0; j < markers.length; j++) {
519            markers[j].setIcon(normalIcon)
520          }
521        })
522      })
523    })
524  }
525
526
527  const newMap = $('.js-map')
528  if (newMap.length) {
529    console.log('New map block firing');
530
531    newMap.each(function () {
532      const thisMap = $(this)
533
534      setMapHeight()
535
536      mapboxgl.accessToken = 'pk.eyJ1IjoiZWZsdXgiLCJhIjoiY2tvdWtlYmRrMG0yZDJwbGduc29xYnhmYSJ9._VbyfiocV_cdHHlcMri-Dg'
537
538      marker = thisMap.data('markers')
539      if(!marker[0]){
540        return
541      }
542      const map = new mapboxgl.Map({
543        container: thisMap.get(0),
544        style: 'mapbox://styles/eflux/ckpx4an1j53vv17n3t5ck4ljz',
545        zoom: 15,
546        center: [marker[0].lng, marker[0].lat]
547      })
548      map.addControl(new mapboxgl.NavigationControl({showCompass: false}))
549      map.scrollZoom.disable()
550      map.dragRotate.disable()
551      map.doubleClickZoom.disable()
552      map.touchZoomRotate.disableRotation()
553
554      const el = document.createElement('div')
555      el.className = 'marker'
556      el.style.backgroundImage = 'url("/elements/EFL03_red-pin.svg")'
557      el.style.width = '24px'
558      el.style.height = '38px'
559      el.style.backgroundSize = '100%'
560
561      const popup = new mapboxgl.Popup({
562        closeButton: false,
563        closeOnClick: false
564      })
565
566      el.addEventListener('mouseenter', function (e) {
567        $(this)[0].style.backgroundImage = 'url("/elements/EFL03_black-pin.svg")'
568      })
569
570      el.addEventListener('mouseleave', function () {
571        $(this)[0].style.backgroundImage = 'url("/elements/EFL03_red-pin.svg")'
572      })
573
574      let tooltipContent = '<div class="map-tooltip"><div class="map-tooltip__left"><div class="map-tooltip__left-address">' + newMap.data('address') + '</div></div>'
575
576      if (thisMap.data('image')) {
577        tooltipContent = tooltipContent + '<div class="map-tooltip__right"><img src="' + thisMap.data('image') + '"></div>'
578      }
579
580      tooltipContent = tooltipContent + '</div>'
581
582      new mapboxgl
583        .Marker(el)
584        .setLngLat(marker[0])
585        .setPopup(new mapboxgl.Popup({
586            offset: 25,
587            closeButton: false
588          })
589            .setHTML(tooltipContent)
590        )
591        .addTo(map)
592    })
593  }
594
595  // initInstitutionMap()
596}
597
598
599function initInstitutionMap() {
600
601  if ($('#institution_map').length && !$('.mapboxgl-canvas').length) {
602    console.log('institution map block is firing');
603
604    let mapReady = false
605
606    const el = $('#institution_map')
607
608    mapboxgl.accessToken = 'pk.eyJ1IjoiZWZsdXgiLCJhIjoiY2tvdWtlYmRrMG0yZDJwbGduc29xYnhmYSJ9._VbyfiocV_cdHHlcMri-Dg'
609    const mapBounds = sessionStorage.getItem('mapBounds')
610    const map = new mapboxgl.Map({
611      container: el.get(0),
612      style: 'mapbox://styles/eflux/ckpx4an1j53vv17n3t5ck4ljz',
613      center: [-73.9658774, 40.6945364],
614      zoom: 2,
615      bounds: mapBounds ? JSON.parse(mapBounds) : false,
616      projection: 'globe'
617    })
618
619    map.addControl(new mapboxgl.NavigationControl({showCompass: false}), 'top-right')
620
621    // map.scrollZoom.disable();
622    map.dragRotate.disable()
623    map.doubleClickZoom.disable()
624    map.touchZoomRotate.disableRotation()
625
626    const bounds = [
627      [999, 999],
628      [-999, -999]
629    ]
630
631    const saveMapState = function () {
632      sessionStorage.setItem('mapBounds', JSON.stringify(map.getBounds().toArray()))
633    }
634
635    map.on('moveend', saveMapState)
636    map.on('zoomend', saveMapState)
637
638    const markers = {}
639    let markersOnScreen = {}
640
641    map.on('load', function () {
642
643      // Hide road labels and highway route shields (keep the road lines visible)
644      map.getStyle().layers.forEach(function (layer) {
645        const isRoadLabel = layer.type === 'symbol' &&
646          (layer['source-layer'] === 'road' || /road|motorway|highway|shield/i.test(layer.id))
647        if (isRoadLabel) {
648          map.setLayoutProperty(layer.id, 'visibility', 'none')
649        }
650      })
651
652      let features = []
653      $('.js-institution-location').each(function (i, e) {
654        const coordinates = $(e).data('coordinates')
655        //NOTE: GOOGLE USES LAT, LNG, WHILE MAPBOX IS OFTEN LNG,LAT
656
657        const point = {
658          "id": $(e).data('id'),
659          "type": "Feature",
660          "properties": {
661            "directionUrl": "https://www.google.com/maps?q=loc:" + coordinates[1] + "," + coordinates[0] + "",
662            "client": $(e).data('client'),
663            "url": $(e).data('url'),
664            "overlay": $(e).data('overlay'),
665            "location": $(e).data('location')
666          },
667          "geometry": {
668            "type": "Point",
669            "coordinates": coordinates
670          }
671        }
672
673        features.push(point)
674      })
675
676      map.addSource('points', {
677        type: 'geojson',
678        data: {
679          "type": "FeatureCollection",
680          "features": features
681        },
682        cluster: true,
683        clusterMaxZoom: 20,
684        clusterRadius: 50
685      });
686
687      map.addLayer({
688        id: 'circle',
689        type: 'circle',
690        source: 'points',
691        paint: {
692          'circle-color': 'transparent',
693          'circle-radius': 12,
694          'circle-stroke-width': 0
695        }
696      })
697
698      let moveTimeout
699      map.on('dragend', function () {
700        clearTimeout(moveTimeout)
701
702        moveTimeout = setTimeout(function () {
703          showMarkersInSidebar(map)
704        }, 200)
705      })
706
707      map.on('zoomend', function () {
708        clearTimeout(moveTimeout)
709
710        moveTimeout = setTimeout(function () {
711          showMarkersInSidebar(map)
712        }, 200)
713
714      })
715
716      map.on('render', function () {
717        if (!map.isSourceLoaded('points')) {
718          return
719        }
720
721        const newMarkers = {}
722        const features = map.querySourceFeatures('points')
723
724        features.forEach(function (feature) {
725          let marker = markers[feature.id]
726
727          if (!marker) {
728            const el = $('<div class="map__marker map__marker--institutions"></div>')
729
730            if (feature.properties.cluster) {
731              const clusterId = feature.properties.cluster_id
732
733              el.addClass('map__marker--cluster')
734              if (!isMobile()) {
735                el.addClass('js-map-cluster-zoom')
736              }
737
738              //el.append('<div class="map__marker-label">' + feature.properties.point_count + '</div>')
739              el.append('<div class="map__marker-label"></div>')
740
741              el.attr({
742                'data-id': clusterId,
743                'data-size': feature.properties.point_count,
744                'data-center': JSON.stringify(feature.geometry.coordinates)
745              })
746            } else {
747              el.addClass('clickable-block js-mapshow-scroll')
748                .data({
749                  // order: feature.properties.order,
750                  title: feature.properties.title,
751                  date: feature.properties.date,
752                  client: feature.properties.client,
753                  directionUrl: feature.properties.directionUrl,
754                  overlay: feature.properties.overlay,
755                  // url: feature.properties.url
756                })
757                .attr('data-id', feature.id)
758
759              // if (feature.properties.overlay && !isMobile()) {
760              //   el.addClass('js-open-overlayer').data('href', feature.properties.url)
761              // }
762            }
763
764            marker = new mapboxgl.Marker(el[0])
765              .setLngLat(feature.geometry.coordinates)
766            markers[feature.id] = marker
767          }
768
769          newMarkers[feature.id] = marker
770
771          if (!markersOnScreen[feature.id]) {
772            marker.addTo(map)
773          }
774        })
775
776        for (id in markersOnScreen) {
777          if (!newMarkers[id]) {
778            markersOnScreen[id].remove()
779          }
780        }
781
782        markersOnScreen = newMarkers
783
784        if (!mapReady) {
785          showMarkersInSidebar(map)
786          mapReady = true
787        }
788      })
789
790      $(document).on('click', '.js-map-cluster-zoom', function () {
791        const center = $(this).data('center')
792        map.getSource('points').getClusterExpansionZoom(
793          $(this).data('id'),
794          function (err, zoom) {
795            if (err) return
796            map.easeTo({
797              center,
798              zoom
799            })
800          }
801        )
802      })
803    })
804  }
805}
806
807
808function relatedStyle() {
809  $('.js-related__items-height').each(function () {
810    const related = $(this)
811
812    related.each(function () {
813      const related = $(this)
814      const container = related.closest('.related__inner')
815      const placeholderLandscape = container.find('.related__placeholder-item-landscape')
816      const placeholderSquare = container.find('.related__placeholder-item-square')
817      const placeholderPortrait = container.find('.related__placeholder-item-portrait')
818      const placeholderGutter = container.find('.related__placeholder-item-gutter')
819      const items = related.find('.related__item')
820
821      if (related.closest('.related').hasClass('related--thumbs')) {
822
823        const cellHeight = related.find('.related__carousel').height()
824
825        items.each(function () {
826          const el = $(this)
827          const ratio = el.find('.related__item-thumb').data('ratio')
828
829          el.css({
830            'height': cellHeight,
831            'width': cellHeight * ratio
832          })
833        })
834
835
836      } else {
837        if (!isMobile()) {
838          if (items.length <= 4 && related.find('.related__item--portrait').length <= 4) {
839            items.each(function (i, s) {
840              if (i != 0) {
841                $(s).css('padding-left', placeholderGutter.width())
842              }
843            })
844          }
845        }
846
847        items.each(function () {
848          const el = $(this)
849
850          if (el.hasClass('related__item--landscape')) {
851            el.css('width', placeholderLandscape.width())
852          } else if (el.hasClass('related__item--square')) {
853            el.css('width', placeholderSquare.width())
854          } else if (el.hasClass('related__item--journal') || el.hasClass('related__item--large-education')) {
855            el.css('width', container.width())
856          } else if (el.hasClass('preview-criticism-home')) {
857            el.css('width', placeholderSquare.width())
858          } else {
859            el.css('width', placeholderPortrait.width())
860          }
861        })
862      }
863
864      // const wWidth = $(window).width()
865      // const lastCellSpace = wWidth - ((placeholder.width() * 4) + (30 * 4))
866
867      lastCellSpace = parseInt(container.css('margin-left'))
868
869      related.find('.related__item').last().css('padding-right', Math.floor(lastCellSpace))
870
871      // set related container height
872      const cellHeight = related.find('.related__item').eq(0)
873      related.css('height', cellHeight.height())
874    })
875  })
876}
877
878function relatedSlide(slider, to) {
879  const cellWidth = slider.find('.related__item').outerWidth()
880  let scrollSize
881  const slideCells = Math.floor($(window).width() / cellWidth)
882
883  // Not remove snap type on Safari
884  if (!isSafari()) {
885    slider.removeClass('related__carousel-snap-active')
886  }
887
888  const wWidth = $(window).width()
889  let currentLeftItem
890
891  if (to == 'next') {
892    slider.find('.related__item').each(function () {
893      const cell = $(this)
894
895      if (cell.offset().left <= wWidth) {
896        currentLeftItem = cell
897      }
898    })
899  } else {
900    slider.find('.related__item').each(function () {
901      const cell = $(this)
902
903      if (cell.offset().left + wWidth >= 0) {
904        currentLeftItem = cell
905        return false
906      }
907    })
908  }
909
910  scrollSize = slider.scrollLeft() + currentLeftItem.offset().left
911
912  slider.animate({
913    scrollLeft: scrollSize + 'px'
914  }, 250, () => slider.addClass('related__carousel-snap-active'))
915}
916
917function videoCarouselStyle() {
918  $('.js-video-carousel__items-height').each(function () {
919    const carousel = $(this)
920
921    carousel.each(function () {
922      const carousel = $(this)
923      const container = carousel.closest('.video-carousel__inner')
924      const placeholder = container.find('.video-carousel__placeholder')
925      const accordion = carousel.closest('.video-accordion__content')
926
927      let cellWidth = placeholder.width()
928      if (accordion.length && accordion.is(':hidden')) {
929        cellWidth = $(window).width()
930      }
931
932      carousel.find('.video-carousel__slider').children().css({
933        width: cellWidth
934      })
935
936      const wWidth = $(window).width()
937      const lastCellSpace = wWidth - ((placeholder.width() * 4) + (30 * 4))
938
939      carousel.find('.video-carousel__slider').children().last().css('padding-right', Math.floor(lastCellSpace))
940
941      // set carousel container height
942      const cellHeight = carousel.find('.video-carousel__slider').children().eq(0)
943      carousel.css('height', cellHeight.outerHeight())
944
945      if (isMobile() || isSafari()) {
946        carousel.find('.video-carousel__slider').addClass('video-carousel__slider--snap-active')
947      } else {
948        carousel.find('.video-carousel__slider').removeClass('video-carousel__slider--snap-active')
949      }
950    })
951  })
952}
953
954let fadeoutTimer
955const copyToClipboard = function (str) {
956  const el = document.createElement('textarea') // Create a <textarea> element
957  el.value = str // Set its value to the string that you want copied
958  el.setAttribute('readonly', '') // Make it readonly to be tamper-proof
959  el.style.position = 'absolute'
960  el.style.left = '-9999px' // Move outside the screen to make it invisible
961  document.body.appendChild(el) // Append the <textarea> element to the HTML document
962
963  const selected =
964    document.getSelection().rangeCount > 0 // Check if there is any content selected previously
965      ? document.getSelection().getRangeAt(0) // Store selection if found
966      : false // Mark as false to know no selection existed before
967  el.select() // Select the <textarea> content
968  document.execCommand('copy') // Copy - only works as a result of a user action (e.g. click events)
969  document.body.removeChild(el) // Remove the <textarea> element
970
971  if (selected) { // If a selection existed before copying
972    document.getSelection().removeAllRanges() // Unselect everything on the HTML document
973    document.getSelection().addRange(selected) // Restore the original selection
974  }
975
976  $('#js-clipboard').addClass('clipboard-button-show')
977
978  fadeoutTimer = setTimeout(function () {
979    $('#js-clipboard').removeClass('clipboard-button-show')
980  }, 2000)
981}
982
983function updateSearchResults() {
984  const query = []
985  const keywords = $('#search-form-input')
986
987  if (keywords.length) {
988    if (keywords.val().length) {
989      query.push('q=' + encodeURIComponent(keywords.val()))
990    }
991  }
992
993  $('.filter-category').each(function () {
994    const container = $(this)
995    const name = false
996
997    container.find('.filter-item-clickable--selected.js-filter-item').each(function () {
998      query.push($(this).data('name') + '[]=' + encodeURIComponent($(this).data('filter')))
999    })
1000  })
1001
1002  if ($('[name="sort"]').length) {
1003    query.push('order=' + $('[name="sort"]:checked').val())
1004  }
1005
1006  location.href = '?' + query.join('&')
1007}
1008
1009function getScrollbarWidth() {
1010  // Creating invisible container
1011  const outer = document.createElement('div')
1012  outer.style.visibility = 'hidden'
1013  outer.style.overflow = 'scroll' // forcing scrollbar to appear
1014  outer.style.msOverflowStyle = 'scrollbar' // needed for WinJS apps
1015  document.body.appendChild(outer)
1016
1017  // Creating inner element and placing it in the container
1018  const inner = document.createElement('div')
1019  outer.appendChild(inner)
1020
1021  // Calculating difference between container's full width and the child width
1022  const scrollbarWidth = (outer.offsetWidth - inner.offsetWidth)
1023
1024  // Removing temporary elements from the DOM
1025  outer.parentNode.removeChild(outer)
1026
1027  return scrollbarWidth
1028}
1029
1030function closemenu() {
1031  $('.menu')
1032    .removeClass('menu--open')
1033    .fadeOut(fadeDuration)
1034
1035  $('.header--short').removeClass('header--menu-open')
1036}
1037
1038function trackPageview(url) {
1039  // Google Analytics
1040  if (typeof ga !== 'undefined' && $.isFunction(ga)) {
1041    ga('send', 'pageview', url)
1042  }
1043
1044  // Matomo
1045  if (typeof _paq !== 'undefined') {
1046    _paq.push(['setCustomUrl', '/' + url]);
1047    _paq.push(['trackPageView']);
1048  }
1049}
1050
1051function resetMain() {
1052  const main = $('.main')
1053
1054  main.removeClass('main--lock fx-scrollbar')
1055  $(window).scrollTop(main.data('scrollPosition'))
1056
1057  document.title = $('.main').data('pageTitle')
1058
1059  window.history.pushState(null, null, main.data('pageUrl'))
1060
1061  // Track pageview
1062  trackPageview(main.data('pageUrl'))
1063}
1064
1065function relatedGradient() {
1066  $('.related__carousel').each(function () {
1067    const relatedCarosuel = $(this)
1068
1069    relatedCarosuel.each(function () {
1070      const scroller = $(this)
1071      const container = scroller.closest('.related__inner')
1072      const block = scroller.closest('.related__items')
1073      const scrollerWidth = scroller[0].scrollWidth
1074
1075      if (scrollerWidth > $(window).width()) {
1076        block.addClass('related__items--right-gradient')
1077        container.addClass('related__inner--arrow-right-show')
1078      } else {
1079        block.removeClass('related__items--right-gradient')
1080        container.removeClass('related__inner--arrow-right-show')
1081      }
1082
1083      $('.related__carousel').on('scroll', function () {
1084        const scroller = $(this)
1085        const container = scroller.closest('.related__inner')
1086        const block = scroller.closest('.related__items')
1087        const scrollerWidth = scroller[0].scrollWidth
1088
1089        const scrollPosition = scroller.scrollLeft()
1090
1091        if (scrollPosition <= 0) {
1092          block.removeClass('related__items--left-gradient')
1093          container.removeClass('related__inner--arrow-left-show')
1094        } else {
1095          block.addClass('related__items--left-gradient')
1096          container.addClass('related__inner--arrow-left-show')
1097        }
1098
1099        if (scrollPosition >= scrollerWidth - scroller.width()) {
1100          block.removeClass('related__items--right-gradient')
1101          container.removeClass('related__inner--arrow-right-show')
1102        } else {
1103          block.addClass('related__items--right-gradient')
1104          container.addClass('related__inner--arrow-right-show')
1105        }
1106
1107        relatedCarouselStop(scroller)
1108      })
1109    })
1110  })
1111}
1112
1113function videoCarouselGradient() {
1114  $('.video-carousel__slider').each(function () {
1115    const carousel = $(this)
1116
1117    carousel.each(function () {
1118      const scroller = $(this)
1119      const container = scroller.closest('.video-carousel__inner')
1120      const block = scroller.closest('.video-carousel__items')
1121      const scrollerWidth = scroller[0].scrollWidth
1122
1123      if (scrollerWidth > $(window).width()) {
1124        block.addClass('video-carousel__items--right-gradient')
1125        container.addClass('video-carousel__items--arrow-right-show')
1126      } else {
1127        block.removeClass('video-carousel__items--right-gradient')
1128        container.removeClass('video-carousel__items--arrow-right-show')
1129      }
1130
1131      $('.video-carousel__slider').on('scroll', function () {
1132        const scrollPosition = scroller.scrollLeft()
1133
1134        if (scrollPosition <= 0) {
1135          block.removeClass('video-carousel__items--left-gradient')
1136          container.removeClass('video-carousel__items--arrow-left-show')
1137        } else {
1138          block.addClass('video-carousel__items--left-gradient')
1139          container.addClass('video-carousel__items--arrow-left-show')
1140        }
1141
1142        if (scrollPosition >= scrollerWidth - Math.ceil(scroller.width())) {
1143          block.removeClass('video-carousel__items--right-gradient')
1144          container.removeClass('video-carousel__items--arrow-right-show')
1145        } else {
1146          block.addClass('video-carousel__items--right-gradient')
1147          container.addClass('video-carousel__items--arrow-right-show')
1148        }
1149      })
1150    })
1151  })
1152}
1153
1154function isEmail(email) {
1155  const regex = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/
1156  return regex.test(email)
1157}
1158
1159function initFunctions() {
1160  carouselArticlePreInit()
1161  initMap()
1162  hideSidebar()
1163  hideAd()
1164  sidebarHeightMobile()
1165  initTypeahead()
1166  appLayerSizes()
1167  initMarquee()
1168
1169
1170  if ($('.js-app-animation').length && isMobile()) {
1171    $('.js-app-animation').find('.page-app__section').each(function () {
1172      const video = $(this).find('video')
1173
1174      video.find('source').attr('src', video.find('source').data('src'))
1175      video[0].load()
1176    })
1177  }
1178
1179	$('.js-related-items').each(function () {
1180		const related = $(this)
1181
1182		const relatedItems = related.find('.related__item')
1183
1184
1185		if (relatedItems.length) {
1186			related.addClass('related--visible')
1187
1188			$('.js-sidebar-related').addClass('sidebar__bottom-related--visible')
1189
1190			relatedStyle()
1191			relatedGradient()
1192			sidebarHeightMobile()
1193			siebarScrollArea()
1194		}
1195	})
1196
1197  relatedStyle()
1198  videoCarouselStyle()
1199  relatedGradient()
1200  videoCarouselGradient()
1201  siebarScrollArea()
1202  journalImageHeight()
1203  sideAd()
1204  createShareLinks()
1205  if ($.isFunction($.fn.cbplayer)) {
1206    $('.js-player-audio').cbplayer({
1207      tpf: false,
1208      overlaySpinner: false,
1209      overlayButton: false
1210    })
1211  }
1212
1213  // $('.js-player-audio').cbplayer('initSource');
1214
1215  if ($.isFunction($.fn.cblightbox)) {
1216    $('.js-lightbox').cblightbox({
1217      margin: [0, 150],
1218      captionPosition: 'inside',
1219      counter: false,
1220      closeOutsideClick: false,
1221      zoom: true,
1222      zoomSize: 10,
1223      zoomControlls: true,
1224      zoomSteps: 5
1225    })
1226  }
1227
1228  if ($.isFunction($.fn.cbplayer)) {
1229    $('.js-videoheaderplayer').cbplayer({
1230      tpl: false,
1231      autoplay: false,
1232      overlaySpinner: false,
1233      overlayButton: false,
1234      disableClick: true
1235    })
1236
1237    $('.js-videoheaderplayer').cbplayer('initSource');
1238
1239    $('.js-autoplayvideo').cbplayer({
1240      tpl: false,
1241      backgroundMode: true,
1242      autoplay: true,
1243      muted: true,
1244      loop: true,
1245      overlaySpinner: false,
1246      overlayButton: false,
1247    })
1248  }
1249
1250  $('.js-overlayer-form').ajaxForm({
1251    beforeSubmit: function (formData, form, options) {
1252      const captcha = $('input[name="g-recaptcha-response"][value!=""]')
1253      let error = false
1254      if (captcha.val()=="") {
1255        $(".js-overlayer-subscribeform #error-captcha").text("Please submit the captcha")
1256        error = true
1257      }
1258
1259
1260      window.fetch("https://backend-api.e-flux-systems.com/api/checkCaptcha?g-recaptcha-response="+captcha.val(),{
1261        method: 'POST',
1262        dataType: 'json',
1263        data:{
1264          "g-recaptcha-response": captcha.val()??""
1265        }
1266      }).then(function (response) {
1267        if(!response.ok){
1268          error = true
1269        }
1270      })
1271
1272      if (error) {
1273        return false
1274      }
1275      form.find('.button--submit').prop('disabled', true)
1276    },
1277    success: function (response, status, xhr, form) {
1278      if (response.ok) {
1279        if (form.hasClass('js-close-after-submit')) {
1280          closeOverlayerForm(form.closest('.overlayer-form'))
1281        } else {
1282          form.addClass('el-hidden')
1283
1284          if (form.closest('.overlayer-form--inline').length) {
1285            form.closest('.overlayer-form--inline').find('.overlayer-form__successful').removeClass('el-hidden')
1286          } else {
1287            form.closest('.overlayer-form__content').find('.overlayer-form__successful').removeClass('el-hidden')
1288          }
1289          window.history.pushState(null, null, window.location.origin + window.location.pathname)
1290          $(".button--rsvpbutton--ticket").hide()
1291        }
1292      } else {
1293        if (response.missing) {
1294          const prefix = form.data('type')
1295
1296          $.each(response.missing, function (i, fieldName) {
1297            $('[name="' + prefix + '_' + fieldName + '"]').closest('.form__wrap-input, .form__wrap-checkbox, .form__wrap-textarea').addClass('form__wrap--error')
1298          })
1299        }
1300      }
1301    }
1302  })
1303
1304  $('.js-overlayer-subscribeform').ajaxForm({
1305    beforeSubmit: function (formData, form, options) {
1306      let error = false
1307
1308      const email = form.find('input[name="email"]')
1309      if (email.val()) {
1310        if (!isEmail(email.val())) {
1311          email.closest('.form__wrap-input').addClass('form__wrap--error')
1312          error = true
1313        }
1314      } else {
1315        email.closest('.form__wrap-input').addClass('form__wrap--error')
1316        error = true
1317      }
1318
1319      const privacy = form.find('input[name="privacy"]')
1320      if (!privacy.is(':checked')) {
1321        privacy.closest('.form__wrap-checkbox ').addClass('form__wrap--error')
1322        error = true
1323      }
1324      const captcha = $('input[name="g-recaptcha-response"][value!=""]')
1325
1326      if (captcha.val()=="") {
1327        $(".js-overlayer-subscribeform #error-captcha").text("Please submit the captcha")
1328        error = true
1329      }
1330
1331      window.fetch("https://backend-api.e-flux-systems.com/api/checkCaptcha?g-recaptcha-response="+captcha.val(),{
1332        method: 'POST',
1333        dataType: 'json',
1334        data:{
1335          "g-recaptcha-response": captcha.val()??""
1336        }
1337      }).then(function (response) {
1338        if(!response.ok){
1339          error = true
1340        }
1341      })
1342      if (error) {
1343        return false
1344      }
1345
1346      form.find('.button--submit').prop('disabled', true)
1347    },
1348    success: function (response, status, xhr, form) {
1349      console.log(response)
1350      if (response.ok) {
1351        form.addClass('el-hidden')
1352        form.closest('.overlayer-form__content').find('.overlayer-form__successful').removeClass('el-hidden')
1353        form.closest('.inline-subscribe').find('.inline-subscribe__thanks').removeClass('el-hidden')
1354        window.history.pushState(null, null, window.location.origin + window.location.pathname)
1355        $(".inline-subscribe").find('.inline-subscribe__thanks').removeClass('el-hidden')
1356      } else {
1357        if (response.missing) {
1358          $.each(response.missing, function (i, fieldName) {
1359            form.find('[name="' + fieldName + '"]').closest('.form__wrap-input, .form__wrap-checkbox').addClass('form__wrap--error')
1360          })
1361        }
1362
1363        form.find('.button--submit').prop('disabled', false)
1364      }
1365    }
1366  })
1367  $('.js-overlayer-subscribeform-client').ajaxForm({
1368    beforeSubmit: function (formData, form, options) {
1369      const captcha = $('input[name="g-recaptcha-response"][value!=""]')
1370      let error = false
1371
1372      if (captcha.val()=="") {
1373        $(".js-overlayer-subscribeform #error-captcha").text("Please submit the captcha")
1374        error = true
1375      }
1376
1377      window.fetch("https://backend-api.e-flux-systems.com/api/checkCaptcha?g-recaptcha-response="+captcha.val(),{
1378        method: 'POST',
1379        dataType: 'json',
1380        data:{
1381          "g-recaptcha-response": captcha.val()??""
1382        }
1383      }).then(function (response) {
1384        if(!response.ok){
1385          error = true
1386        }
1387      })
1388
1389      if (error) {
1390        return false
1391      }
1392      form.find('.button--submit').prop('disabled', true)
1393    },
1394    success: function (response, status, xhr, form) {
1395      if (response.ok) {
1396        form.addClass('el-hidden')
1397        form.closest('.overlayer-form__content').find('.overlayer-form__successful').removeClass('el-hidden')
1398        window.history.pushState(null, null, window.location.origin + window.location.pathname)
1399      } else {
1400        if (response.missing) {
1401          $.each(response.missing, function (i, fieldName) {
1402            $('[name="' + fieldName + '"]').closest('.form__wrap-input, .form__wrap-checkbox').addClass('form__wrap--error')
1403          })
1404        }
1405
1406        form.find('.button--submit').prop('disabled', false)
1407      }
1408    }
1409  })
1410  buyButtonTooltip()
1411  overlayerBgPosition()
1412  adArticleHeight()
1413
1414  const articleBody = $('.article__body--with-ad')
1415  if (articleBody.length) {
1416    if (!articleBody.find('.js-article-ad').length) {
1417      const tags = articleBody.children()
1418      const selectedTag = tags.eq(5)
1419      const currentLayer = articleBody.closest('.overlayer__inner')
1420      const ad = currentLayer.find('.js-article-ad.article-ad--hidden')
1421
1422      ad.clone().removeClass('article-ad--hidden').insertAfter(selectedTag)
1423    } else {
1424      articleBody.find('.js-article-ad').removeClass('article-ad--hidden')
1425    }
1426  }
1427
1428  // check for chrome - clip-path + fixed bug
1429  const articleAd = $('.js-article-ad:not(.article-ad--landing)')
1430  if (articleAd.length) {
1431    if (/chrom(e|ium)/.test(navigator.userAgent.toLowerCase())) {
1432      articleAd.addClass('article-ad--chrome')
1433    } else if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent.toLowerCase())) {
1434      const userAgent = navigator.userAgent
1435      const versionIndex = navigator.userAgent.indexOf('Version')
1436      const version = userAgent.substr(versionIndex, 10).split('/')
1437
1438      // Check is safari version 14 or older
1439      // Use Chrome style for Ad
1440      if (version[1] <= 14) {
1441        articleAd.addClass('article-ad--chrome')
1442      } else {
1443        articleAd.addClass('article-ad--safari')
1444      }
1445    }
1446  }
1447
1448  adFitItem()
1449
1450  if ($.isFunction($.fn.cbplayer)) {
1451    $('.js-ad-video').cbplayer({
1452      tpl: false,
1453      autoplay: true,
1454      muted: true,
1455      loop: true,
1456      backgroundMode: true,
1457      mediaIsPlay: function (container) {
1458        const videoRatio = container.data('videowidth') / container.data('videoheight')
1459        container.closest('.article-ad__item').data('ratio', videoRatio)
1460
1461        adFitItem()
1462      }
1463    })
1464  }
1465
1466  relatedGradient()
1467
1468  setTimeout(()=>{$(window).trigger('resize');},1500)
1469
1470}
1471
1472function adArticleHeight() {
1473
1474  const ad = $('.js-article-ad')
1475
1476  if (ad.length) {
1477    ad.each(function () {
1478      const ad = $(this)
1479
1480      if (ad.hasClass('article-ad--landing')) {
1481        let height = $(window).height() * 0.5
1482        if (window.innerWidth <= 768) {
1483          height = $(window).height() * 0.25
1484        } else if (window.innerWidth <= 1200) {
1485          height = $(window).height() * 0.35
1486        }
1487
1488        ad.css('height', height)
1489        ad.find('.article-ad__inner').css('height', height)
1490      } else {
1491        ad.css('height', $(window).height())
1492      }
1493    })
1494
1495    adFitItem()
1496  }
1497}
1498
1499function adFitItem() {
1500  const items = $('.js-ad-fit-item')
1501  $(window).trigger('scroll')
1502  $('.js-article-ad').css('opacity',1)
1503
1504  if (items.length) {
1505    items.each(function () {
1506      const item = $(this)
1507      let container = item.closest('.article-ad__area')
1508/*      if(item.find('.js-ad-video').length){
1509        container =item.find('.js-ad-video')
1510      }*/
1511      const containerRatio = container.width() / container.height()
1512      let newWidth, newHeight
1513
1514      if (containerRatio < item.data('ratio')) {
1515        newWidth = container.width()
1516        newHeight = 1 / item.data('ratio') * newWidth
1517      } else {
1518        newHeight = container.height()
1519        newWidth = newHeight * item.data('ratio')
1520      }
1521
1522      item.css({
1523        width: newWidth
1524      })
1525    })
1526  }
1527}
1528
1529function buyButtonTooltip() {
1530  const buyTooltip = $('.js-dropdown-button--auto')
1531  if (buyTooltip.length) {
1532    buyTooltip.each(function () {
1533      const tooltip = $(this)
1534      const button = tooltip.find('.button')
1535
1536      tooltip.removeClass('dropdown-button--open-left-top dropdown-button--open-right-top')
1537
1538      if (button.offset().left + 200 > $(window).width()) {
1539        tooltip.addClass('dropdown-button--open-left-top')
1540      } else {
1541        tooltip.addClass('dropdown-button--open-right-top')
1542      }
1543    })
1544  }
1545}
1546
1547function contentTopBorder() {
1548  const border = $('.js-conent-top-border')
1549
1550  if (border.length) {
1551    const container = border.parent()
1552
1553    border.css({
1554      left: container.offset().left,
1555      width: container.width()
1556    })
1557  }
1558}
1559
1560function hideSidebar() {
1561  const wScrolltop = $(window).scrollTop()
1562  const wScrollbottom = wScrolltop + $(window).height()
1563  let currentContent = $('.main')
1564
1565  if ($('.overlayer').length && !currentContent.hasClass('.main-form')) {
1566    currentContent = $('.overlayer')
1567
1568  }
1569
1570  const wideElements = currentContent.find('.js-hide-sidebar')
1571  const sidebar = currentContent.find('.sidebar')
1572
1573  if(currentContent.find('.article__content').height()> sidebar.height()){
1574
1575    if (!isMobile() && wideElements.length && sidebar.length) {
1576      let isvisible = false
1577      wideElements.each(function () {
1578        const el = $(this)
1579        const elTop = el.offset().top
1580        const elBottom = elTop + el.height()
1581
1582        if (wScrollbottom > elTop && wScrolltop < elBottom) {
1583          isvisible = true
1584          return false
1585        }
1586      })
1587
1588      if (isvisible) {
1589        if (!sidebar.hasClass('sidebar--hidden')) {
1590          sidebar.addClass('sidebar--hidden')
1591        }
1592      } else if (sidebar.hasClass('sidebar--hidden')) {
1593        sidebar.removeClass('sidebar--hidden')
1594      }
1595    } else {
1596      sidebar.removeClass('sidebar--hidden')
1597    }
1598  }else{
1599    currentContent.find('.article__content').css("min-height",parseInt(sidebar.height())+125)
1600  }
1601
1602}
1603
1604function hideAd() {
1605
1606
1607  const wScrolltop = $(window).scrollTop()
1608  const wScrollbottom = wScrolltop + $(window).height()
1609  let currentContent = $('.main')
1610
1611  if ($('.overlayer').length) {
1612    currentContent = $('.overlayer')
1613  }
1614
1615  const wideElements = currentContent.find('.js-hide-side-ad')
1616  const ad = currentContent.find('.side-ad__item')
1617
1618  if (!isMobile() && wideElements.length && ad.length) {
1619    const adTop = ad.position().top
1620    const adBottom = adTop + ad.height()
1621    let isTouching = false
1622    wideElements.each(function () {
1623      const el = $(this)
1624      const elTop = el.offset().top - wScrolltop
1625      const elBottom = elTop + el.height()
1626
1627      if (adBottom + 50 > elTop && adTop - 50 < elBottom) {
1628        isTouching = true
1629        return false
1630      }
1631    })
1632
1633    if (isTouching) {
1634      if (!ad.hasClass('side-ad__item--hidden')) {
1635        ad.addClass('side-ad__item--hidden')
1636      }
1637    } else if (ad.hasClass('side-ad__item--hidden')) {
1638      ad.removeClass('side-ad__item--hidden')
1639    }
1640  } else {
1641    ad.removeClass('side-ad__item--hidden')
1642  }
1643}
1644
1645function hideHeader() {
1646  // if (isMobile()) {
1647  //  return;
1648  // }
1649
1650  // const els = $('.js-hide-header');
1651
1652  // if (els.length == 0) {
1653  //  return;
1654  // }
1655
1656  // const wScrolltop = $(window).scrollTop(),
1657  //       wScrollbottom = wScrolltop + $(window).height();
1658  // let isInViewport = false;
1659  // els.each(function(){
1660  //  const el = $(this),
1661  //        elTop = el.offset().top,
1662  //        elBottom = elTop + el.height();
1663
1664  //  if (wScrollbottom > elTop && wScrolltop < elBottom){
1665  //    isInViewport = true;
1666  //    return false;
1667  //  }
1668  // });
1669  // if (isInViewport) {
1670  //  $('.header--fixed').addClass('header--hidden');
1671  // } else {
1672  //  $('.header--fixed').removeClass('header--hidden');
1673  // }
1674}
1675
1676function sidebarHeightMobile() {
1677  const sidebar = $('.sidebar')
1678
1679  if (sidebar.length && isMobile() && $('.js-sidebar-scroll-area').length) {
1680    const area = $('.js-sidebar-scroll-area').find('.sidebar__top-scroll')
1681    const areaScrollHeight = area[0].scrollHeight + parseInt(area.css('padding-top')) + parseInt(area.css('padding-bottom'))
1682    const screenHeight = window.innerHeight ? window.innerHeight : $(window).height()
1683    let scrollheight = screenHeight - sidebar.find('.sidebar__toggle').height() - sidebar.find('.sidebar__bottom').outerHeight()
1684
1685    if ($('.marquee').length) {
1686      scrollheight = scrollheight - $('.marquee').height()
1687    }
1688
1689    if (scrollheight > areaScrollHeight) {
1690      sidebar.find('.sidebar__top-scroll').css('max-height', scrollheight)
1691    } else {
1692      sidebar.find('.sidebar__top-scroll').css('max-height', '')
1693    }
1694  }
1695}
1696
1697function hideTopHeader() {
1698  const wScrolltop = $(window).scrollTop()
1699  const el = $('.js-header-hide-on-top')
1700
1701  if (wScrolltop < 0) {
1702    el.hide()
1703  } else {
1704    el.show()
1705  }
1706}
1707
1708function siebarScrollArea() {
1709  const sidebarArea = $('.js-sidebar-scroll-area')
1710
1711  if (sidebarArea.length) {
1712    const sidebar = sidebarArea.closest('.sidebar')
1713    const sidebarBottom = $('.sidebar__bottom')
1714    let sidebarHeight = sidebar.height() - $('.header').height() - sidebarBottom.height() - parseInt(sidebarBottom.css('bottom')) - 10
1715
1716    if ($('.marquee').length) {
1717      sidebarHeight = sidebarHeight - $('.marquee').height()
1718    }
1719
1720    if (isMobile()) {
1721      sidebarArea.css('height', '')
1722
1723      sidebarHeight = sidebar - $('.header').height() - sidebarBottom.outerHeight()
1724
1725      const area = $('.js-sidebar-scroll-area').find('.sidebar__top-scroll')
1726      const areaScrollHeight = area[0].scrollHeight + parseInt(area.css('padding-top')) + parseInt(area.css('padding-bottom'))
1727
1728      if (sidebarHeight > areaScrollHeight) {
1729        sidebarArea.css('height', '')
1730      } else {
1731        sidebarArea.css('height', sidebarHeight)
1732      }
1733    } else {
1734      sidebarArea.css('height', sidebarHeight)
1735    }
1736  }
1737}
1738
1739function journalImageHeight() {
1740  // const image = $('.article__header-media-image')
1741
1742  // if (image.length && isMobile()) {
1743  //   const header = $('.article__header-top')
1744
1745  //   image.css('height', header.outerHeight())
1746  // } else if (image.length && !isMobile()) {
1747  //   image.css('height', '')
1748  // }
1749}
1750
1751function scaleIssueTop() {
1752  const el = $('.js-issue-scale')
1753
1754  if (el.length) {
1755    el.each(function () {
1756      const container = $(this)
1757      const wrapper = container.find('.current-issue__number-wrap')
1758      let largestWrapperWidth = 0
1759      let largestWrapper
1760      const startFontSize = 200
1761
1762      container.removeClass('current-issue__number--ready')
1763
1764      wrapper.each(function () {
1765        const thisWrapper = $(this)
1766
1767        if (largestWrapperWidth < thisWrapper.width()) {
1768          largestWrapperWidth = thisWrapper.width()
1769          largestWrapper = thisWrapper
1770        }
1771      })
1772
1773      for (let i = startFontSize; i >= 0; i--) {
1774        container.css('font-size', i)
1775
1776        if (largestWrapper.width() <= largestWrapper.parent().width()) {
1777          container.addClass('current-issue__number--ready')
1778          return true
1779        }
1780      }
1781    })
1782  }
1783}
1784
1785scaleIssueTop()
1786
1787function setMapHeight() {
1788  const maps = $('.js-map')
1789  if (maps.length) {
1790    maps.each(function () {
1791      const map = $(this)
1792      const container = map.closest('.announcement__map-content')
1793      const block = map.closest('.announcement__map')
1794
1795      if (isMobile()) {
1796        mapHeight = container.width() * 0.5625
1797        map.css('height', mapHeight)
1798      } else {
1799        map.css('height', '')
1800      }
1801
1802      if (block.hasClass('announcement__map--open')) {
1803        container.css('height', mapHeight)
1804      }
1805    })
1806  }
1807}
1808
1809function overlayerBgPosition() {
1810  const topBg = $('.js-overlayer__bgimage-top')
1811
1812  if (topBg.length) {
1813    const imageWidth = topBg.data('width')
1814    const imageHeight = topBg.data('height')
1815    const imageRatio = imageWidth / imageHeight
1816    let windowHeight = $(window).height()
1817    const windowWidth = $(window).width()
1818    const marquee = topBg.closest('.overlayer').find('.marquee')
1819
1820    if (imageRatio < windowWidth / windowHeight) {
1821      let topPosition = windowWidth * (1 / imageRatio)
1822      topPosition = (topPosition - windowHeight) / 2
1823
1824      if (marquee.length) {
1825        topPosition = topPosition + marquee.height()
1826      }
1827
1828      topPosition = -1 * topPosition
1829
1830      topBg.css({
1831        'background-position': 'center ' + topPosition + 'px',
1832        'background-size': 'cover'
1833      })
1834    } else {
1835      const size = windowHeight * imageRatio
1836
1837      let topPosition = 0
1838
1839      if (marquee.length) {
1840        topPosition = topPosition + marquee.height()
1841        topPosition = -1 * topPosition
1842      }
1843
1844      topBg.css({
1845        'background-position': 'center ' + topPosition + 'px',
1846        'background-size': size
1847      })
1848    }
1849  }
1850}
1851
1852overlayerBgPosition()
1853
1854function initTypeahead() {
1855
1856
1857  $(document).on('typeahead:selected', function (e, value, name) {
1858    // on select trigger submit
1859    // typeaheadSubmit(value.value);
1860    const input = $(e.target)
1861
1862    input.typeahead('close')
1863  })
1864}
1865
1866function appLayerSizes() {
1867  const layer = $('.page-app__layer')
1868  const phone = $('.page-app__phone')
1869  const sections = $('.page-app__section')
1870
1871  if (layer.length) {
1872    const screenHeight = $(window).height() - 128
1873    const screenWidth = screenHeight * 0.561058
1874
1875    layer.css('width', screenWidth / 1.2492)
1876
1877    phone.css('width', screenWidth)
1878
1879    const columnWidth = ($(window).width() / 2) - (screenWidth / 2)
1880
1881    sections.find('.page-app__section-column').css('width', columnWidth)
1882  }
1883}
1884
1885function appAnimation() {
1886  const windowY = $(window).scrollTop()
1887  const windowBottom = windowY + $(window).height()
1888  const layercontainer = $('.page-app__layer')
1889  const el = $('.js-app-animation')
1890
1891  if (!isMobile() && el.length) {
1892    if (el.length) {
1893      // 22 = pin position - .page-app__sections padding-top
1894      if (el.offset().top - 22 + el.outerHeight() < windowBottom) {
1895        el.addClass('page-app__sections--uppin-phone')
1896      } else if (el.offset().top < windowY) {
1897        el.removeClass('page-app__sections--uppin-phone')
1898        el.addClass('page-app__sections--pin-phone')
1899      } else {
1900        el.removeClass('page-app__sections--uppin-phone')
1901        el.removeClass('page-app__sections--pin-phone')
1902      }
1903    }
1904
1905    $('.page-app__section').each(function () {
1906      const section = $(this)
1907      const sectionBottom = (section.offset().top + section.height()) - windowY
1908      const layerPosition = layercontainer.position().top + layercontainer.height()
1909      const layer = layercontainer.find('.page-app__layer-item').eq(section.data('number') - 1)
1910
1911      if (sectionBottom < layerPosition && sectionBottom > layercontainer.position().top) {
1912        const layerHeight = sectionBottom - layercontainer.position().top + 2
1913
1914        layer.removeClass('page-app__layer-item--hidden')
1915        layer.css('height', layerHeight)
1916
1917        layernext = layercontainer.find('.page-app__layer-item').eq(section.data('number'))
1918
1919        if (!layernext.hasClass('page-app__layer-item--init')) {
1920          layernext.find('video source').attr('src', layernext.find('video source').data('src'))
1921          layernext.find('video')[0].load()
1922
1923          layernext.addClass('page-app__layer-item--init')
1924        }
1925      } else if (sectionBottom < layerPosition && section.data('number') != layercontainer.find('.page-app__layer-item').length) {
1926        layer.addClass('page-app__layer-item--hidden')
1927      } else {
1928        layer.css('height', '')
1929      }
1930    })
1931  }
1932}
1933
1934// Add Shopify buy buttons
1935const scriptURL = 'https://sdks.shopifycdn.com/buy-button/latest/buy-button-storefront.min.js'
1936let scriptIsLoaded = false
1937
1938function loadScript() {
1939  if (scriptIsLoaded) {
1940    return
1941  }
1942
1943  const script = document.createElement('script')
1944  script.async = true
1945  script.src = scriptURL;
1946  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script)
1947
1948  if ($('.js-shop-button').length) {
1949    const items = $('.js-shop-button')
1950
1951    script.onload = function () {
1952      ShopifyBuyInit(items)
1953      scriptIsLoaded = true
1954    }
1955  }
1956}
1957
1958function ShopifyBuyInit(items) {
1959  const client = ShopifyBuy.buildClient({
1960    domain: 'efluxshop.myshopify.com',
1961    storefrontAccessToken: '0d57cc764de8d73f6236bbf33b6e8e49'
1962  })
1963
1964  if ($('.shop-item:not(.shopify-buy-frame)').length && ShopifyBuyInit == false) {
1965    loadScript($('.js-shop-button:not(.shopify-buy-frame)'))
1966    return
1967  }
1968
1969  var items = items
1970
1971  if ($('.js-shop-button:not(.shopify-buy-frame)').length) {
1972    items = $('.js-shop-button:not(.shopify-buy-frame)')
1973  }
1974
1975  items.each(function () {
1976    const item = $(this)
1977    ShopifyBuy.UI.onReady(client).then(function (ui) {
1978      if ([item.data('shopify-id')] == 8688195666094) {
1979
1980        ui.createComponent('product', {
1981          id: [item.data('shopify-id')],
1982          node: item[0],
1983          options: {
1984            product: {
1985              iframe: false,
1986              variantId: 'all',
1987              width: '100%',
1988              contents: {
1989                img: false,
1990                imgWithCarousel: false,
1991                title: false,
1992                variantTitle: false,
1993                price: false,
1994                description: false,
1995                buttonWithQuantity: false,
1996                quantity: false,
1997              },
1998              styles: {
1999                button: {
2000                  backgroundColor: 'black',
2001                  color: 'white',
2002                  ':hover': {
2003                    backgroundColor: '#333'
2004                  },
2005                  ':focus': {
2006                    backgroundColor: '#111'
2007                  }
2008                }
2009              },
2010              DOMEvents: {
2011                'click .js-form__checkbox-button': function (evt, target) {
2012                    var product = ui.components.product.filter(function (product) {
2013                      return product.id[0] === 8688195666094;
2014                    })[0];
2015                    target.checked = true;
2016    
2017                    const formatValue = target.getAttribute('value');
2018                    product.updateVariant("Format", formatValue);
2019
2020                  }
2021              },
2022              templates: {
2023                options: `
2024                <div class="{{data.classes.product.options}}" style="margin-top: .75rem;">
2025                  <fieldset class="variant-options">
2026                    {{#data.variants}}
2027                      <div class="form__checkbox2">
2028                        <input type="radio" name="Format" value="{{title}}"
2029                          class="form__checkbox-input" id="{{id}}" >
2030                        <label for="{{id}}" class="form__checkbox-button js-form__checkbox-button"   value="{{title}}" style="min-width:1.1rem;"></label>
2031                        <p class="form__checkbox-value js-form__checkbox-label" style="padding-bottom: .25rem;">{{title}}</p>
2032                        <br>
2033                      </div>
2034                    {{/data.variants}}
2035                  </fieldset>
2036                    <p class="announcement__header-media-caption" style="text-align: left;">Institutional subscriptions include free access to a downloadable PDF of each <em>Index</em> to share with students and faculty.</p>
2037                    <p class="announcement__header-media-caption" style="text-align: left;margin-top: 0rem;">Subscriptions run for one year, covering four issues of <em>Index</em>, and begin with the most current issue at the time of purchase.</p>
2038                    <p class="announcement__header-media-caption" style="text-align: left;margin-top: 0rem;">Shipping and discount codes are added at checkout.</p>
2039                </div>
2040              `,
2041              },
2042              text: {
2043                button: 'Subscribe',
2044                outOfStock: 'Sold Out',
2045                unavailable: 'Sold Out'
2046              }
2047            },
2048            cart: {
2049              styles: {
2050                button: {
2051                  'font-size': '21px',
2052                  // "padding-top": "14.5px",
2053                  'padding-bottom': '14.5px',
2054                  ':hover': {
2055                    'background-color': '#232323'
2056                  },
2057                  'background-color': '#232323',
2058                  ':focus': {
2059                    'background-color': '#232323'
2060                  },
2061                  'border-radius': '0px'
2062                }
2063              }
2064            },
2065            toggle: {
2066              styles: {
2067                toggle: {
2068                  'font-family': "'Neue Haas Unica',Arial",
2069                  'background-color': '#232323',
2070                  ':hover': {
2071                    'background-color': '#232323'
2072                  },
2073                  ':focus': {
2074                    'background-color': '#232323'
2075                  }
2076                },
2077                count: {
2078                  'font-size': '21px'
2079                }
2080              }
2081            }
2082          }
2083        })
2084      } else {
2085        ui.createComponent('product', {
2086          id: [item.data('shopify-id')],
2087          node: item[0],
2088          options: {
2089            product: {
2090              iframe: false,
2091              variantId: 'all',
2092              width: '100%',
2093              contents: {
2094                img: false,
2095                imgWithCarousel: false,
2096                title: false,
2097                variantTitle: false,
2098                price: false,
2099                description: false,
2100                buttonWithQuantity: false,
2101                quantity: false
2102                // "margin-top": "0",
2103
2104              },
2105              text: {
2106                button: 'Purchase',
2107                outOfStock: 'Sold Out',
2108                unavailable: 'Sold Out'
2109              }
2110            },
2111            cart: {
2112              styles: {
2113                button: {
2114                  'font-size': '21px',
2115                  // "padding-top": "14.5px",
2116                  'padding-bottom': '14.5px',
2117                  ':hover': {
2118                    'background-color': '#232323'
2119                  },
2120                  'background-color': '#232323',
2121                  ':focus': {
2122                    'background-color': '#232323'
2123                  },
2124                  'border-radius': '0px'
2125                }
2126              }
2127            },
2128            toggle: {
2129              styles: {
2130                toggle: {
2131                  'font-family': "'Neue Haas Unica',Arial",
2132                  'background-color': '#232323',
2133                  ':hover': {
2134                    'background-color': '#232323'
2135                  },
2136                  ':focus': {
2137                    'background-color': '#232323'
2138                  }
2139                },
2140                count: {
2141                  'font-size': '21px'
2142                }
2143              }
2144            }
2145          }
2146        })
2147      }
2148    })
2149  })
2150}
2151
2152// mapshow
2153function intersectRect(r1, r2) {
2154  return !(r2.left > r1.right || r2.right < r1.left || r2.top > r1.bottom || r2.bottom < r1.top)
2155}
2156
2157function getVisibleMarkers(map) {
2158  const cc = map.getContainer()
2159  const els = cc.getElementsByClassName('map__marker')
2160  const ccRect = cc.getBoundingClientRect()
2161  const visibles = []
2162
2163  for (let i = 0; i < els.length; i++) {
2164    const el = els.item(i)
2165    const elRect = el.getBoundingClientRect()
2166    intersectRect(ccRect, elRect) && visibles.push(el)
2167  }
2168
2169  return visibles
2170}
2171
2172function showMarkersInSidebar(map) {
2173  const container = $('.js-map-sidebar-items')
2174  const newItem = $('.mapshow-preview-item .mapshow-sidebar-item')
2175  const mapCenter = map.getCenter()
2176
2177  container.addClass('mapshow-sidebar__items--hide')
2178  container.empty()
2179
2180  const visibleMarkers = getVisibleMarkers(map)
2181
2182  $('.mapshow__sidebar').removeClass('mapshow__sidebar--hover');
2183
2184  $.each(visibleMarkers, function (i, e) {
2185    let el = $(this)
2186
2187    if (el.hasClass('map__marker--cluster')) {
2188      const clusterSource = map.getSource('points')
2189
2190      clusterSource.getClusterLeaves(el.data('id'), el.data('size'), 0, function (error, features) {
2191        $.each(features, function (i, e) {
2192          const clusterEl = $(this)
2193          const values = clusterEl[0].properties
2194
2195          // console.log(clusterEl[0])
2196
2197          const item = newItem.clone()
2198
2199          item.attr('data-id', el.data('id'))
2200    console.log(el)
2201
2202          if ($('.js-mapshow--institutions').length) {
2203            let from = turf.point([mapCenter.lng, mapCenter.lat])
2204            let to = turf.point(clusterEl[0].geometry.coordinates)
2205            let distance = turf.distance(from, to, {units: 'miles'})
2206
2207            item.attr('data-order', distance)
2208            item.find('.mapshow-sidebar-item__title').html(values.client)
2209            item.find('.mapshow-sidebar-item__location').html(values.location)
2210          } else {
2211            item.attr('data-order', values.order)
2212            item.find('.mapshow-sidebar-item__date').html(values.date)
2213            item.find('.mapshow-sidebar-item__client').html(values.client)
2214          }
2215
2216          if (values.url) {
2217            let addClass = ''
2218            if (values.overlay) {
2219              addClass = ' js-open-overlayer'
2220            }
2221
2222            $('<a href="' + values.url + '" class="mapshow-sidebar-item__title mapshow-sidebar-item__title--link' + addClass + '">' + values.title + '</a>').appendTo(item.find('.mapshow-sidebar-item__bottom'))
2223          } else {
2224            $('<div class="mapshow-sidebar-item__title">' + values.title + '</div>').appendTo(item.find('.mapshow-sidebar-item__bottom'))
2225          }
2226
2227          if (values.url) {
2228            let addClass = ''
2229            if (values.overlay) {
2230              addClass = ' js-open-overlayer'
2231            }
2232
2233            const buttonInformation = $('<a href="' + values.url + '" class="button button--map' + addClass + '">More Information</a>')
2234            buttonInformation.appendTo(item.find('.mapshow-sidebar-item__buttons'))
2235          }
2236
2237          if ($('.js-mapshow--institutions').length) {
2238
2239            const coordinates = clusterEl[0].geometry.coordinates
2240            const url = 'https://www.google.com/maps?q=loc:' + coordinates[1] + ',' + coordinates[0] + ''
2241
2242            buttonDirection = $('<a href="' + url + '" class="button button--map">Get Directions</a>')
2243          } else {
2244            buttonDirection = $('<a href="' + el.data('directionUrl') + '" class="button button--map">Get Directions</a>')
2245          }
2246          buttonDirection.appendTo(item.find('.mapshow-sidebar-item__buttons'))
2247
2248          // item.find('.mapshow-sidebar-item__bullet').attr('href', values.directionUrl)
2249
2250          const img = $('<img>').attr('src', values.image)
2251          item.find('.mapshow-sidebar-item__image').append(img)
2252
2253          item.appendTo(container)
2254        })
2255      })
2256    } else {
2257      const item = newItem.clone()
2258
2259      if ($('.js-mapshow--institutions').length) {
2260        el = $('.js-institution-location[data-id="' + el.data('id') + '"]')
2261      }
2262
2263      item.attr('data-id', el.data('id'))
2264
2265      if ($('.js-mapshow--institutions').length) {
2266        let from = turf.point([mapCenter.lng, mapCenter.lat])
2267        let to = turf.point(el.data('coordinates'))
2268        let distance = turf.distance(from, to, {units: 'miles'})
2269
2270        item.attr('data-order', distance)
2271        item.find('.mapshow-sidebar-item__title').html(el.data('client'))
2272        item.find('.mapshow-sidebar-item__location').html(el.data('location'))
2273      } else {
2274        item.attr('data-order', el.data('order'))
2275        item.find('.mapshow-sidebar-item__date').html(el.data('date'))
2276        item.find('.mapshow-sidebar-item__client').html(el.data('client'))
2277      }
2278
2279      if (el.data('url')) {
2280        let addClass = ''
2281        if (el.data('overlay')) {
2282          addClass = ' js-open-overlayer'
2283        }
2284
2285        $('<a href="' + el.data('url') + '" class="mapshow-sidebar-item__title mapshow-sidebar-item__title--link' + addClass + '">' + el.data('title') + '</a>').appendTo(item.find('.mapshow-sidebar-item__bottom'))
2286      } else {
2287        $('<div class="mapshow-sidebar-item__title">' + el.data('title') + '</div>').appendTo(item.find('.mapshow-sidebar-item__bottom'))
2288      }
2289
2290      if (el.data('url')) {
2291        let addClass = ''
2292        if (el.data('overlay')) {
2293          addClass = ' js-open-overlayer'
2294        }
2295
2296        const buttonInformation = $('<a href="' + el.data('url') + '" class="button button--map' + addClass + '">More Information</a>')
2297        buttonInformation.appendTo(item.find('.mapshow-sidebar-item__buttons'))
2298      }
2299
2300      let buttonDirection
2301      if ($('.js-mapshow--institutions').length) {
2302
2303        const coordinates = el.data('coordinates')
2304        const url = 'https://www.google.com/maps?q=loc:' + coordinates[1] + ',' + coordinates[0] + ''
2305
2306        buttonDirection = $('<a href="' + url + '" class="button button--map">Get Directions</a>')
2307      } else {
2308        buttonDirection = $('<a href="' + el.data('directionUrl') + '" class="button button--map">Get Directions</a>')
2309      }
2310
2311      buttonDirection.appendTo(item.find('.mapshow-sidebar-item__buttons'))
2312
2313      // item.find('.mapshow-sidebar-item__bullet').attr('href', el.data('directionUrl'))
2314
2315      const img = $('<img>').attr('src', el.data('image'))
2316      item.find('.mapshow-sidebar-item__image').append(img)
2317
2318      item.appendTo(container)
2319    }
2320  })
2321
2322
2323  setTimeout(function () {
2324
2325    container.children()
2326      .sort(function (a, b) {
2327        return $(a).data('order') - $(b).data('order')
2328      })
2329      .appendTo(container)
2330
2331    container.removeClass('mapshow-sidebar__items--hide')
2332    $('.mapshow__sidebar').removeClass('mapshow__sidebar--visible')
2333
2334    $('.map__marker').removeClass('map__marker--hover')
2335
2336    if (isMobile()) {
2337      container.scrollLeft(0)
2338    }
2339  })
2340}
2341
2342function closeSubscribeInfo(item) {
2343  item.closest('.landing-subscribe').fadeOut()
2344  document.cookie = 'hidesubscribeform=1; path=/'
2345}
2346
2347function closeOverlayerForm(overlayer) {
2348  // hide form
2349  overlayer.fadeOut(fadeDuration)
2350
2351  window.history.pushState(null, null, window.location.origin + window.location.pathname)
2352
2353  // Track pageview
2354  trackPageview(window.location.origin + window.location.pathname)
2355
2356  // reset from
2357  setTimeout(function () {
2358    overlayer.find('.overlayer-form__form').removeClass('el-hidden')
2359    overlayer.find('.overlayer-form__successful').addClass('el-hidden')
2360
2361    overlayer.find('input[type="text"]').val('')
2362    overlayer.find('input[type="email"]').val('')
2363    overlayer.find('input[type="checkbox"]').prop('checked', false)
2364  }, fadeDuration)
2365}
2366
2367function fadeHeader() {
2368  $('.header--fadable').each(function () {
2369    const header = $(this)
2370    const container = header.closest('.overlayer, .main')
2371    const trigger = container.find('.js-header-fade-trigger')
2372    const sTop = $(window).scrollTop()
2373
2374    if (container.hasClass('main--lock')) {
2375      return
2376    }
2377
2378    if (header.length && trigger.length) {
2379      if (sTop > trigger.offset().top) {
2380        header.addClass('header--visible')
2381      } else {
2382        header.removeClass('header--visible')
2383      }
2384    }
2385  })
2386}
2387
2388function topicBottomheight() {
2389  const topics = $('.js-topic-bottom-height')
2390  if (topics.length) {
2391    topics.each(function () {
2392      const container = $(this).closest('.preview-topic')
2393      const topicBottom = $(this)
2394      const topicTop = container.find('.preview-topic__content-top')
2395      const topicImage = container.find('.preview-topic__image .lazyimage-container')
2396
2397      if (isMobile()) {
2398        const tipicSCrollHeight = container.find('.preview-topic__content-articles').outerHeight()
2399        if (tipicSCrollHeight > 220) {
2400          container.addClass('preview-topic--arrow')
2401        } else {
2402          container.removeClass('preview-topic--arrow')
2403        }
2404      } else {
2405        const topicScrollHeight = topicImage.outerHeight() - topicTop.height()
2406        topicBottom.css({
2407          height: topicScrollHeight,
2408          width: 'calc(100% + ' + getScrollbarWidth() + 'px)'
2409        })
2410      }
2411    })
2412  }
2413}
2414
2415function sideAd() {
2416  const sidead = $('.side-ad')
2417
2418  if (sidead.length) {
2419    const sideadItem = sidead.find('.side-ad__item')
2420
2421    sideadItem.css('width', sidead.width())
2422  }
2423}
2424
2425sideAd()
2426
2427function setScreenHeight() {
2428  const height = window.innerHeight
2429
2430  $('body').get(0).style.setProperty('--screen-height', height + 'px')
2431}
2432
2433setScreenHeight()
2434
2435function relatedCarouselStop(scroller) {
2436  const scrollPosition = scroller.scrollLeft()
2437  const dots = scroller.closest('.related').find('.related__dots')
2438
2439  if (dots.length) {
2440    scroller.find('.related__item').each(function (i, e) {
2441
2442      if ($(e).position().left + ($(e).width() / 2) >= 0) {
2443        const currentIndex = $(e).index()
2444
2445        //change dots
2446        dots.find('.related-dot').removeClass('related-dot--selected')
2447
2448        dots.find('.related-dot').eq(currentIndex).addClass('related-dot--selected')
2449
2450        return false;
2451      }
2452    })
2453  }
2454}
2455
2456function initMarquee(update = false) {
2457  const marquees = $('.js-marquee')
2458
2459  if (marquees.length) {
2460    marquees.each(function () {
2461      const container = $(this)
2462      const slider = container.find('.marquee__slider-inner')
2463
2464      if (!container.hasClass('marquee--initialized') || update) {
2465
2466        const slide = container.find('.marquee__slide').eq(0)
2467        const textWidth = slide.outerWidth()
2468        const animationName = 'anaimation-' + Math.floor(Math.random() * 26) + Date.now()
2469
2470        if (container.hasClass('marquee--initialized')) {
2471          slider.resetKeyframe()
2472        }
2473
2474        slider.css({
2475          'animation-name': animationName,
2476          'animation-duration': '15s'
2477        })
2478
2479        $.keyframe.define({
2480          name: animationName,
2481          from: {
2482            'margin-left': '0px'
2483          },
2484          to: {
2485            'margin-left': '-' + textWidth + 'px'
2486          }
2487        })
2488      }
2489    })
2490  }
2491}
2492
2493function jumpToAccordion(videoAccordion) {
2494  if (videoAccordion.length) {
2495
2496    // Close open accordion
2497    const firstAccordion = $('.video-accordion')
2498    firstAccordion.removeClass('video-accordion--open')
2499    firstAccordion.find('.video-accordion__content').hide()
2500
2501    // Open selected accordion
2502    videoAccordion.addClass('video-accordion--open')
2503    videoAccordion.find('.video-accordion__content').show()
2504
2505    videoCarouselStyle()
2506    videoCarouselGradient()
2507
2508    let position = videoAccordion.offset().top - $('.header').height() + 1
2509    const marquee = $('.marquee')
2510
2511    if (marquee.length) {
2512      position = position - marquee.height()
2513    }
2514
2515    $(window).scrollTop(position)
2516
2517  }
2518}
2519
2520function criticismLimitPreview() {
2521  const items = $('.js-preview-criticism-limit-height')
2522
2523  if (items.length) {
2524
2525    items.each(function () {
2526      const container = $(this)
2527      const content = container.find('.preview-criticism__content')
2528      const image = container.find('.preview-criticism__right .preview-criticism__image')
2529
2530      if (isMobile()) {
2531        content.css('height', '')
2532      } else {
2533        content.css('height', image.outerHeight())
2534      }
2535    })
2536  }
2537}
2538
2539function alignRelatedMoreButton() {
2540  const button = $('.js-related-more')
2541
2542  if (button.length) {
2543    const prevItem = button.closest('.related__item').prev()
2544    const buttonPosition = prevItem.find('.related__item-media').outerHeight() / 2
2545
2546    button.css('top', buttonPosition)
2547  }
2548}
2549function triggerLoad() {
2550  let mapReady = false
2551  if ($('#map').length) {
2552    const el = $('#map')
2553
2554    mapboxgl.accessToken = 'pk.eyJ1IjoiZWZsdXgiLCJhIjoiY2tvdWtlYmRrMG0yZDJwbGduc29xYnhmYSJ9._VbyfiocV_cdHHlcMri-Dg'
2555    const mapBounds = sessionStorage.getItem('mapBounds')
2556    const map = new mapboxgl.Map({
2557      container: el.get(0),
2558      style: 'mapbox://styles/eflux/ckpx4an1j53vv17n3t5ck4ljz',
2559      center: [6.125833, 51.795556],
2560      zoom: 2,
2561      bounds: mapBounds ? JSON.parse(mapBounds) : false
2562    })
2563
2564    map.addControl(new mapboxgl.NavigationControl({showCompass: false}), 'top-right')
2565
2566    // map.scrollZoom.disable();
2567    map.dragRotate.disable()
2568    map.doubleClickZoom.disable()
2569    map.touchZoomRotate.disableRotation()
2570
2571    const bounds = [
2572      [999, 999],
2573      [-999, -999]
2574    ]
2575
2576    const saveMapState = function () {
2577      sessionStorage.setItem('mapBounds', JSON.stringify(map.getBounds().toArray()))
2578    }
2579
2580    map.on('moveend', saveMapState)
2581    map.on('zoomend', saveMapState)
2582
2583    const markers = {}
2584    let markersOnScreen = {}
2585
2586    map.on('load', function () {
2587      let pointsFromMarkup = {
2588        "type": "FeatureCollection",
2589        "features": [
2590
2591        ]
2592      }
2593      $(".js-map-sidebar-item").each(function(index){
2594        let ths = $(this)
2595        if(ths.find('.mapshow-sidebar-item__title').text()){
2596          pointsFromMarkup.features.push( {
2597            "id": ths.data('id'),
2598            "type": "Feature",
2599            "geometry": {"type": "Point", "coordinates": [ths.data('lng'), ths.data('lat')]},
2600            "properties": {
2601              "order": 1+index,
2602              "title": ths.find('.mapshow-sidebar-item__title').text(),
2603              "type": ths.data('announcementtype'),
2604              "date": ths.find('.mapshow-sidebar-item__date').text(),
2605              "client": ths.find('.mapshow-sidebar-item__client').text(),
2606              "image": ths.find('.mapshow-sidebar-item__image').attr('src'),
2607              "url": ths.find('.mapshow-sidebar-item__title--link').attr('href'),
2608              "overlay": false,
2609              "directionUrl": ths.find('.button--map.coords').attr('href')
2610            }
2611          })
2612        }
2613
2614      })
2615console.log(pointsFromMarkup)
2616      map.addSource('points', {
2617        type: 'geojson',
2618        data: pointsFromMarkup,
2619        cluster: true,
2620        clusterMaxZoom: 20,
2621        clusterRadius: 50
2622      })
2623
2624      // Add a circle layer
2625      map.addLayer({
2626        id: 'circle',
2627        type: 'circle',
2628        source: 'points',
2629        paint: {
2630          'circle-color': 'transparent',
2631          'circle-radius': 12,
2632          'circle-stroke-width': 0
2633        }
2634      })
2635
2636      if (!mapBounds) {
2637        window.fetch('/v2/api/map/' + el.data('id'))
2638          .then(response => response.json())
2639          .then(geojson => {
2640            geojson.features.forEach(function (feature) {
2641              if (feature.geometry.coordinates[0] < bounds[0][0]) {
2642                bounds[0][0] = feature.geometry.coordinates[0]
2643              }
2644
2645              if (feature.geometry.coordinates[1] < bounds[0][1]) {
2646                bounds[0][1] = feature.geometry.coordinates[1]
2647              }
2648
2649              if (feature.geometry.coordinates[0] > bounds[1][0]) {
2650                bounds[1][0] = feature.geometry.coordinates[0]
2651              }
2652
2653              if (feature.geometry.coordinates[1] > bounds[1][1]) {
2654                bounds[1][1] = feature.geometry.coordinates[1]
2655              }
2656            })
2657
2658            map.fitBounds(bounds, {
2659              duration: 0,
2660              padding: 50
2661            })
2662          })
2663      }
2664
2665      let moveTimeout
2666      map.on('dragend', function () {
2667        clearTimeout(moveTimeout)
2668
2669        moveTimeout = setTimeout(function () {
2670          showMarkersInSidebar(map)
2671        }, 200)
2672      })
2673
2674      map.on('zoomend', function () {
2675        clearTimeout(moveTimeout)
2676
2677        moveTimeout = setTimeout(function () {
2678          showMarkersInSidebar(map)
2679        }, 200)
2680
2681      })
2682
2683      map.on('render', function () {
2684        if (!map.isSourceLoaded('points')) {
2685          return
2686        }
2687
2688        const newMarkers = {}
2689        const features = map.querySourceFeatures('points')
2690        features.forEach(function (feature) {
2691          let marker = markers[feature.id]
2692
2693          if (!marker) {
2694            const el = $('<div class="map__marker"></div>')
2695
2696            if (feature.properties.cluster) {
2697              const clusterId = feature.properties.cluster_id
2698
2699              el.addClass('map__marker--cluster')
2700              if (!isMobile()) {
2701                el.addClass('js-map-cluster-zoom')
2702              }
2703
2704              el.append('<div class="map__marker-label">' + feature.properties.point_count + '</div>')
2705              el.attr({
2706                'data-id': clusterId,
2707                'data-size': feature.properties.point_count,
2708                'data-center': JSON.stringify(feature.geometry.coordinates)
2709              })
2710            } else {
2711              el.addClass('clickable-block js-mapshow-scroll')
2712                .data({
2713                  order: feature.properties.order,
2714                  title: feature.properties.title,
2715                  date: feature.properties.date,
2716                  client: feature.properties.client,
2717                  directionUrl: feature.properties.directionUrl,
2718                  overlay: feature.properties.overlay,
2719                  // url: feature.properties.url
2720                })
2721                .attr('data-id', feature.id)
2722
2723
2724              // if (feature.properties.overlay && !isMobile()) {
2725              //   el.addClass('js-open-overlayer').data('href', feature.properties.url)
2726              // }
2727            }
2728
2729            marker = new mapboxgl.Marker(el[0])
2730              .setLngLat(feature.geometry.coordinates)
2731            markers[feature.id] = marker
2732          }
2733
2734          newMarkers[feature.id] = marker
2735
2736          if (!markersOnScreen[feature.id]) {
2737            marker.addTo(map)
2738          }
2739        })
2740
2741        for (id in markersOnScreen) {
2742          if (!newMarkers[id]) {
2743            markersOnScreen[id].remove()
2744          }
2745        }
2746
2747        markersOnScreen = newMarkers
2748
2749        if (!mapReady) {
2750          showMarkersInSidebar(map)
2751          mapReady = true
2752        }
2753      })
2754
2755      $(document).on('click', '.js-map-cluster-zoom', function () {
2756        const center = $(this).data('center')
2757        map.getSource('points').getClusterExpansionZoom(
2758          $(this).data('id'),
2759          function (err, zoom) {
2760            if (err) return
2761            map.easeTo({
2762              center,
2763              zoom
2764            })
2765          }
2766        )
2767      })
2768    })
2769  }
2770}
2771
2772alignRelatedMoreButton()
2773
2774let activeAfterPageLoad
2775$(window).on('load', function () {
2776  activeAfterPageLoad = true
2777  topicBottomheight()
2778
2779  hash = location.hash.substr(1)
2780  if (hash) {
2781    const videoAccordion = $('.video-accordion[data-hash="' + hash + '"]')
2782
2783    if (videoAccordion.length) {
2784      jumpToAccordion(videoAccordion)
2785    }
2786  }
2787})
2788
2789$(function () {
2790  $('html').addClass(isTouch ? 'is-touch' : 'no-touch')
2791
2792  // FastClick.attach(document.body)
2793
2794  initFunctions()
2795  contentTopBorder()
2796  criticismLimitPreview()
2797
2798  $("<style type='text/css'>.fx-scrollbar-fixed-el{margin-right:" + getScrollbarWidth() + 'px;}</style>').appendTo($('head'))
2799  $("<style type='text/css'>.fx-scrollbar{padding-right:" + getScrollbarWidth() + 'px;}</style>').appendTo($('head'))
2800
2801  const mapSidebar = $('.mapshow__sidebar-scroller')
2802  if (mapSidebar.length) {
2803    mapSidebar.css('right', '-' + getScrollbarWidth() + 'px')
2804  }
2805
2806  $(document).on('lazybeforeunveil', function (el) {
2807    let img = $(el.target)
2808    let width = img.innerWidth()
2809    let height = img.innerHeight()
2810    if(img.attr('width')){
2811      width=Math.floor( parseInt(img.attr('width')))
2812    }
2813    if(img.attr('height')){
2814      height=Math.floor( parseInt(img.attr('height')))
2815    }
2816    width=Math.floor( parseInt(width)*1.5)
2817    height=Math.floor( parseInt(height)*1.5)
2818
2819    if(!img.hasClass('js-dont-resize') && window.innerWidth>500){
2820      img.attr('data-src',img.attr('data-src')+"?width="+width+"&height="+height)
2821    }
2822
2823
2824
2825
2826    $(el.target).attr('data-width', $(el.target).innerWidth())
2827    $(el.target).attr('data-height', $(el.target).innerHeight())
2828  })
2829  $(document).on('lazyloaded', function (el) {
2830    if ($(el.target).hasClass('js-lazyimage-loaded')) {
2831      if ($(el.target).closest('.preview-video__media').length) {
2832        $(el.target).closest('.preview-video__media').addClass('preview-video__media--ready')
2833      } else if ($(el.target).closest('.preview-note__video').length) {
2834        $(el.target).closest('.preview-note__video').addClass('preview-note__video--ready')
2835      } else if ($(el.target).closest('.preview-liveitem__media').length) {
2836        $(el.target).closest('.preview-liveitem__media').addClass('preview-liveitem__media--ready')
2837      }
2838    }
2839  })
2840
2841  $(document).on('click', '.js-filter-item', function () {
2842    const item = $(this)
2843
2844    if (item.hasClass('filter-item-clickable--selected')) {
2845      return
2846    }
2847
2848    item.addClass('filter-item-clickable--selected')
2849
2850    updateSearchResults()
2851  })
2852
2853  $(document).on('change', '.js-search-order-changed', function () {
2854    updateSearchResults()
2855  })
2856
2857  $(document).on('click', '.filter-category__selected-item:not(.manual)', function () {
2858    //console.log('clliiiickkk')
2859    const item = $(this)
2860    const group = item.closest('.filter-category')
2861    const selectedFilters = item.closest('.filter-category__selected')
2862
2863    group.find('.js-filter-item[data-id="' + item.data('id') + '"]').removeClass('filter-item-clickable--selected')
2864
2865    item.remove()
2866
2867    if (!selectedFilters.children().length) {
2868      selectedFilters.removeClass('filter-category__selected--visible')
2869    }
2870
2871    updateSearchResults()
2872  })
2873
2874  $(document).on('click', '.block-carousel-cell', function () {
2875    const cell = $(this)
2876    let cellNext = cell.index()
2877
2878    if (cell.hasClass('is-selected')) {
2879      cellNext = cell.index() + 1
2880    }
2881
2882    cell.closest('.flickity-enabled').flickity('select', cellNext)
2883  })
2884
2885  $(document).on('click', '.js-announcement-sound-toggle', function () {
2886    const button = $(this)
2887    const video = button.closest('.announcement__header-image').find('.announcement__header-media-video')
2888
2889    if (button.hasClass('announcement__header-sound-on')) {
2890      button
2891        .removeClass('announcement__header-sound-on')
2892        .addClass('announcement__header-sound-off')
2893
2894      video.prop('muted', true)
2895    } else {
2896      button
2897        .removeClass('announcement__header-sound-off')
2898        .addClass('announcement__header-sound-on')
2899
2900      video.prop('muted', false)
2901    }
2902  })
2903
2904  let timeoutKeyup
2905  $(document).on('keyup', '.js-filter-input', function () {
2906    const el = $(this)
2907    const container = el.closest('.filter-category__dropdown')
2908    const list = container.find('.filter-items')
2909    const value = el.val()
2910
2911    clearTimeout(timeoutKeyup)
2912
2913    timeoutKeyup = setTimeout(function () {
2914      if (list.hasClass('js-filterlist')) {
2915        // filter by ajax request
2916        const url = list.data('filterlist') + '&' + el.attr('name') + '=' + value
2917
2918        fetch(url)
2919          .then(resp => resp.json())
2920          .then(data => {
2921            list.empty()
2922
2923            $(data).appendTo(list)
2924          })
2925      } else {
2926        // filter by jquery filter
2927        // Diacritic-insensitive: strip combining marks after Unicode NFD decomposition
2928        // (e.g. "Jörg" -> "Jorg") on both sides, so typing "Jorg" still finds "Jörg".
2929        const normalize = (str) => str.toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '')
2930        const normalizedValue = normalize(value)
2931        list.children().filter(function () {
2932          $(this).toggle(normalize($(this).text()).indexOf(normalizedValue) > -1)
2933        })
2934      }
2935    }, 300)
2936  })
2937
2938  //
2939
2940  $(document).on('click', '.js-filter-category-toggle', function () {
2941    const container = $(this).closest('.filter-category')
2942    const dropdown = container.find('.filter-category__dropdown')
2943    const title = container.find('.filter-category__title')
2944    const selectedItems = container.find('.filter-category__selected--visible')
2945    let minContainerHeight = title.outerHeight()
2946
2947    if (selectedItems.length) {
2948      minContainerHeight = minContainerHeight + selectedItems.outerHeight(true) + 1
2949    }
2950
2951/*    container.css('min-height', minContainerHeight)*/
2952
2953    if (container.hasClass('filter-category--open')) {
2954      container.removeClass('filter-category--open')
2955      dropdown.slideUp(fadeDuration, function () {
2956        container.removeClass('filter-category--fix-selected')
2957      })
2958    } else {
2959      other = $('.filter-category.filter-category--open')
2960      if (other.length) {
2961        other.removeClass('filter-category--open')
2962        other.find('.filter-category__dropdown').slideUp(fadeDuration, function () {
2963          container.removeClass('filter-category--fix-selected')
2964        })
2965      }
2966
2967      container.addClass('filter-category--open filter-category--fix-selected')
2968      dropdown.slideDown(fadeDuration)
2969    }
2970  })
2971
2972  $(document).on('click', '.sidebar-list__button', function () {
2973    const button = $(this)
2974    const container = button.closest('.sidebar-list')
2975
2976    if (button.hasClass('sidebar-list__button--more')) {
2977      container.addClass('sidebar-list--expand')
2978    } else {
2979      container.removeClass('sidebar-list--expand')
2980    }
2981  })
2982
2983  $(document).on('click', '.js-toggle-dropdown', function () {
2984    const container = $(this).closest('.dropdown-button')
2985
2986    if (container.hasClass('dropdown-button--open')) {
2987      container.removeClass('dropdown-button--open')
2988    } else {
2989      const other = $('.dropdown-button.dropdown-button--open')
2990      if (other.length) {
2991        other.removeClass('dropdown-button--open')
2992      }
2993
2994      container.addClass('dropdown-button--open')
2995    }
2996  })
2997
2998  $(document).on('click', '.js-related-dropdown', function (e) {
2999    e.preventDefault()
3000
3001    const select = $(this)
3002    const dropdown = select.closest('.dropdown-button')
3003
3004    const selected = dropdown.find('.related__top-button-selected')
3005
3006    dropdown.removeClass('dropdown-button--open')
3007
3008    if (!select.hasClass('selected')) {
3009
3010      $('.js-related-dropdown').removeClass('selected')
3011      $('.js-related-dropdown[data-service="' + select.data('service') + '"]').addClass('selected')
3012
3013      selected.data('service', select.data('service'))
3014      selected.text(select.text())
3015
3016      const related = select.closest('.related')
3017      const url = 'v2/api/homepage/' + select.data('service') + '/'
3018
3019      fetch(url)
3020        .then(response => response.json())
3021        .then(data => {
3022
3023          related.find('.related__items').remove()
3024          related.find('.related__dots').remove()
3025
3026          $(data).find('.related__items').appendTo(related.find('.related__inner'))
3027          $(data).find('.related__dots').appendTo(related.find('.related__inner'))
3028
3029          relatedStyle()
3030          alignRelatedMoreButton()
3031          relatedGradient()
3032
3033          lazySizes.autoSizer.checkElems()
3034        })
3035    }
3036  })
3037
3038  $(document).on('click', '#js-clipboard', function () {
3039    copyToClipboard(window.location.href)
3040  })
3041
3042  $(document).on('click', function (e) {
3043    if (!$(e.target).closest('.dropdown-button').length) {
3044      $('.dropdown-button').removeClass('dropdown-button--open')
3045    }
3046
3047    if (!$(e.target).closest('.js-menu-open').length && !$(e.target).closest('.menu').length) {
3048      closemenu()
3049    }
3050  })
3051
3052  $(document).on('click', '.js-sidebar-related', function () {
3053    const related = $('.related')
3054    const header = $(this).closest('.overlayer').find('.header')
3055    let position = related.offset().top - header.height() + 2
3056    const marquee = $(this).closest('.overlayer').find('.marquee')
3057
3058    if (marquee.length) {
3059      position = position - marquee.height()
3060    }
3061
3062    $('.sidebar').removeClass('sidebar--open')
3063
3064    $('html, body').animate({
3065      scrollTop: position
3066    }, 500)
3067  })
3068
3069  $(document).on('click', '.menu__item-accordion-title', function () {
3070    const container = $(this).closest('.menu__item-accordion')
3071
3072    if (container.hasClass('menu__item-accordion--active')) {
3073      container.removeClass('menu__item-accordion--active')
3074      container.find('.menu__item-accordion-items').slideUp(200)
3075    } else {
3076      container.addClass('menu__item-accordion--active')
3077      container.find('.menu__item-accordion-items').slideDown(200)
3078    }
3079  })
3080
3081  $(document).on('click', '.js-menu-open', function () {
3082    $('.menu')
3083      .addClass('menu--open')
3084      .fadeIn(fadeDuration)
3085
3086    $('.header--short').addClass('header--menu-open')
3087  })
3088
3089  $(document).on('click', '.js-menu-close', function () {
3090    closemenu()
3091  })
3092
3093  $(document).on('click', '.js-related-slide-arrow', function () {
3094    const button = $(this)
3095    const slider = button.closest('.related__inner').find('.related__carousel')
3096
3097    if (button.hasClass('related__top-arrow--next')) {
3098      relatedSlide(slider, 'next')
3099    } else {
3100      relatedSlide(slider, 'previous')
3101    }
3102  })
3103
3104  $(document).on('click', '.js-block-carousel-arrow', function () {
3105    const button = $(this)
3106    const carousel = button.closest('.block-media').find('.js-carousel')
3107
3108    if (button.hasClass('block-carousel-arrow--prev')) {
3109      carousel.flickity('previous')
3110    } else {
3111      carousel.flickity('next')
3112    }
3113  })
3114
3115  $(document).on('click', '.js-video-carousel-arrow', function () {
3116    const button = $(this)
3117    const slider = button.closest('.video-carousel__inner').find('.video-carousel__slider')
3118    const cellWidth = slider.children().eq(0).outerWidth()
3119    let scrollSize
3120    const container = button.closest('.video-carousel')
3121    const slideCells = Math.floor(container.width() / cellWidth)
3122
3123    jumpPosition = cellWidth * slideCells
3124
3125    // Not remove snap type on Safari
3126    if (!isSafari()) {
3127      slider.removeClass('video-carousel__slider--snap-active')
3128    }
3129
3130    if (button.hasClass('video-carousel__arrow--next')) {
3131      scrollSize = slider.scrollLeft() + jumpPosition
3132    } else {
3133      scrollSize = slider.scrollLeft() - jumpPosition
3134    }
3135
3136    slider.animate({
3137      scrollLeft: scrollSize + 'px'
3138    }, 250, () => slider.addClass('video-carousel__slider--snap-active'))
3139  })
3140
3141  $(document).on('click', '.js-open-overlayer', function (e) {
3142    if (overlayerLoaded) {
3143      return
3144    }
3145
3146    const el = $(this)
3147    const main = $('.main')
3148    let url = el.data('href')
3149
3150    if (el.is('a')) {
3151      url = el.attr('href')
3152    }
3153
3154    if ($('<a href="' + url + '"></a>').get(0).hostname != location.hostname) {
3155      this.blur()
3156      window.open(url)
3157      return
3158    }
3159
3160    overlayerLoaded = true
3161
3162    const saveScrollPosition = $(window).scrollTop()
3163
3164    main.data({
3165      scrollPosition: saveScrollPosition,
3166      pageTitle: $('title').text(),
3167      pageUrl: location.href
3168    })
3169
3170    main.addClass('main--lock fx-scrollbar')
3171    main.scrollTop(saveScrollPosition)
3172
3173    $('.js-for-scrollbar').addClass('fx-scrollbar-fixed-el')
3174
3175    fetch(url)
3176      .then(resp => resp.text())
3177      .then(data => {
3178        main.removeClass('fx-scrollbar')
3179        $('.js-for-scrollbar').removeClass('fx-scrollbar-fixed-el')
3180
3181        const content = $('<div/>').append(data.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, ''))
3182
3183        const overlayer = content.find('.overlayer')
3184
3185        overlayer.hide().appendTo($('body'))
3186
3187        overlayer.fadeIn(fadeDuration, function () {
3188          main.addClass('main--hide')
3189        })
3190
3191        window.history.pushState(null, null, url)
3192
3193        // Track pageview
3194        trackPageview(url)
3195
3196        document.title = content.find('title').text()
3197
3198        overlayerLoaded = false
3199
3200        const buyButtons = overlayer.find('.js-shop-button:not(.shopify-buy-frame)')
3201        if (buyButtons.length) {
3202          ShopifyBuyInit(buyButtons)
3203        }
3204
3205        initFunctions()
3206      })
3207  })
3208
3209  $(document).on('click', '.js-close-overlayer', function () {
3210    const main = $('.main')
3211    const button = $(this)
3212    const overlayer = button.closest('.overlayer')
3213
3214    if (!main.length) {
3215      location.href = button.data('href')
3216    } else {
3217      main.removeClass('main--hide')
3218
3219      overlayer.fadeOut(fadeDuration, function () {
3220        overlayer.remove()
3221        resetMain()
3222      })
3223    }
3224  })
3225
3226  $(document).on('click', '.js-client-character', function () {
3227    const item = $(this)
3228    const section = $('.client__group[data-char="' + item.data('char') + '"]')
3229    const charsList = $('.clients-characters')
3230    const header = $('.header').eq(0)
3231
3232    if (!item.hasClass('client-character--selected')) {
3233      // let scrollPosition = section.offset().top - charsList.outerHeight() - header.height() + 3
3234      $('.js-client-character').removeClass('client-character--selected')
3235      item.addClass('client-character--selected')
3236
3237      if (item.data('char') == 'all') {
3238        $('.client__groups').removeClass('client__groups--filtered')
3239        $('.client__group').removeClass('client__group--active')
3240      } else {
3241        $('.client__groups').addClass('client__groups--filtered')
3242        $('.client__group').removeClass('client__group--active')
3243        section.addClass('client__group--active')
3244      }
3245    }
3246  })
3247
3248  $(document).on('click', '.js-issue-year', function () {
3249    const item = $(this)
3250    const filterItems = item.closest('.journal-filter__items')
3251    const issues = $('.preview-issue[data-year="' + item.data('year') + '"]')
3252    const previewItems = $('.preview-issues')
3253
3254    if (!item.hasClass('journal-year--selected')) {
3255      filterItems.addClass('journal-filter__items--filtered')
3256      item.addClass('journal-year--selected')
3257
3258      previewItems.addClass('preview-issues--filtered')
3259      $('.preview-issue').removeClass('preview-issue--active')
3260      issues.addClass('preview-issue--active')
3261    }
3262  })
3263
3264  $(document).on('click', '.js-journal-filter-open', function () {
3265    const filter = $(this).closest('.journal-filter')
3266
3267    filter.addClass('journal-filter--open')
3268  })
3269
3270  $(document).on('click', '.js-journal-filter-close', function () {
3271    const filter = $(this).closest('.journal-filter')
3272    const previewItems = $('.preview-issues')
3273
3274    filter.removeClass('journal-filter--open')
3275
3276    filter.find('.journal-filter__items').removeClass('journal-filter__items--filtered')
3277    filter.find('.journal-year').removeClass('journal-year--selected')
3278
3279    previewItems.removeClass('preview-issues--filtered')
3280    $('.preview-issue').removeClass('preview-issue--active')
3281  })
3282
3283  $(document).on('click', '.js-journal-filter-open', function () {
3284    const filter = $(this).closest('.journal-filter')
3285
3286    filter.addClass('journal-filter--open')
3287  })
3288
3289  $(document).on('click', '.js-criticism-filter-close', function () {
3290    const filter = $(this).closest('.journal-filter')
3291    const selectedItems = filter.find('.filter-item-clickable--selected')
3292
3293    if (selectedItems.length) {
3294      selectedItems.removeClass('filter-item-clickable--selected')
3295      updateSearchResults()
3296    } else {
3297      filter.removeClass('journal-filter--open')
3298    }
3299  })
3300
3301  $(document).on('click', '.js-sidebar__toggle', function () {
3302    const sidebar = $(this).closest('.sidebar')
3303
3304    if (sidebar.hasClass('sidebar--open')) {
3305      sidebar.removeClass('sidebar--open')
3306    } else {
3307      sidebar.addClass('sidebar--open')
3308    }
3309  })
3310
3311  $(document).on('click', '.js-filter__toggle', function () {
3312    const filter = $('.filter')
3313    const filterButton = $('.filter__toggle')
3314
3315    if (filter.hasClass('filter--open')) {
3316      filter.removeClass('filter--open')
3317      filterButton.removeClass('filter__toggle--open')
3318    } else {
3319      filter.addClass('filter--open')
3320      filterButton.addClass('filter__toggle--open')
3321    }
3322  })
3323
3324  $(document).on('click', '.footnote-reference', function () {
3325    const footnoteRef = $(this)
3326
3327    footnote = $('.js-article__footnote-number[data-footnoteindex="' + footnoteRef.data('index') + '"]')
3328
3329    if ($('.article__doubletake').length) {
3330      const column = $(this).closest('.article__body-doubletake')
3331      footnote = column.find('.js-article__footnote-number[data-footnoteindex="' + footnoteRef.data('index') + '"]')
3332    }
3333
3334    if (footnote.length) {
3335      let position = footnote.offset().top - $('.overlayer  .header').height()
3336
3337      if ($('.article__doubletake').length && !isMobile()) {
3338        position = position - $('.article__doubletake-artists').outerHeight()
3339      }
3340
3341      $('html,body').animate({
3342        scrollTop: position
3343      }, 300)
3344    }
3345  })
3346
3347  $(document).on('click', '.js-article__footnote-number', function () {
3348    const footnote = $(this)
3349    let footnoteRef = $('#footnote-' + footnote.data('footnoteindex') + '-reference')
3350
3351    if ($('.article__doubletake').length) {
3352      const column = $(this).closest('.article__body-doubletake')
3353      footnoteRef = column.find('#footnote-' + footnote.data('footnoteindex') + '-reference')
3354    }
3355
3356    if (footnoteRef.length) {
3357      let position = footnoteRef.offset().top - $('.overlayer .header').height()
3358
3359      if ($('.article__doubletake').length && !isMobile()) {
3360        position = position - $('.article__doubletake-artists').outerHeight()
3361      }
3362
3363      $('html,body').animate({
3364        scrollTop: position
3365      }, 300)
3366    }
3367  })
3368
3369  $(document).on('click', '.js-journalshow__top-style', function () {
3370    const el = $(this)
3371    let articles = $('.preview-journalarticles')
3372
3373    if (el.data('container')) {
3374      articles = $('.' + el.data('container'))
3375
3376      if (!el.hasClass('journalshow__top-style--selected')) {
3377        $('.js-journalshow__top-style').removeClass('journalshow__top-style--selected')
3378        el.addClass('journalshow__top-style--selected')
3379
3380        articles.removeClass('preview-videos--images preview-videos--list')
3381        articles.addClass('preview-videos--' + el.data('style'))
3382
3383        lazySizes.autoSizer.checkElems()
3384      }
3385    } else {
3386      if (!el.hasClass('journalshow__top-style--selected')) {
3387        $('.js-journalshow__top-style').removeClass('journalshow__top-style--selected')
3388        el.addClass('journalshow__top-style--selected')
3389
3390        articles.removeClass('preview-journalarticles--images preview-journalarticles--list')
3391        articles.addClass('preview-journalarticles--' + el.data('style'))
3392
3393        lazySizes.autoSizer.checkElems()
3394      }
3395    }
3396  })
3397
3398  $(document).on('click', '.js-announcement-map-toggle', function () {
3399    const button = $(this)
3400    const block = button.closest('.announcement__map')
3401    const container = block.find('.announcement__map-content')
3402    const map = block.find('.announcement__map-item')
3403
3404    if (block.hasClass('announcement__map--open')) {
3405      block.removeClass('announcement__map--open')
3406
3407      if (isMobile()) {
3408        container.css('height', '')
3409      }
3410    } else {
3411      block.addClass('announcement__map--open')
3412
3413      if (isMobile()) {
3414        container.css('height', parseInt(map.css('height')) + 'px')
3415      }
3416    }
3417  })
3418
3419  $(document).on('click', '.js-form-open', function () {
3420    $('.overlayer-form[data-overlayer="institutions"]').fadeIn(fadeDuration)
3421  })
3422
3423  $(document).on('click', '.js-overlayer-form__close', function () {
3424    closeOverlayerForm($(this).closest('.overlayer-form'))
3425  })
3426
3427  $(document).on('click', '.js-selected-toggle', function () {
3428    const container = $(this).closest('.form__wrap-select')
3429
3430    if (container.hasClass('form__wrap-select--open')) {
3431      container.removeClass('form__wrap-select--open')
3432    } else {
3433      container.addClass('form__wrap-select--open')
3434    }
3435  })
3436
3437  $(document).on('click', '.js-select-option', function () {
3438    const option = $(this)
3439    const container = option.closest('.form__wrap-select')
3440    const dropdown = option.closest('.form__select-dropdown')
3441
3442    dropdown.find('.form__select-dropdown-wrap').removeClass('form__select-dropdown-wrap--selected')
3443    option.closest('.form__select-dropdown-wrap').addClass('form__select-dropdown-wrap--selected')
3444
3445    container.find('.js-selected-toggle').html(option.html())
3446    container.find('.js-selected-value').val(option.data('value'))
3447
3448    container.removeClass('form__wrap-select--open')
3449  })
3450
3451  $(document).on('click', '.js-landing-subscribe-close', function () {
3452    closeSubscribeInfo($(this))
3453  })
3454
3455  let timeoutReaderImageHover
3456  $(document).on('mouseenter', '.js-reader__images', function () {
3457    const el = $(this)
3458
3459    el.addClass('reader__images--hover')
3460
3461    timeoutReaderImageHover = setTimeout(function () {
3462      el.addClass('reader__images--change-postion')
3463    }, 200)
3464  })
3465
3466  $(document).on('mouseleave', '.js-reader__images', function () {
3467    const el = $(this)
3468
3469    el.removeClass('reader__images--hover')
3470
3471    clearTimeout(timeoutReaderImageHover)
3472
3473    timeoutReaderImageHover = setTimeout(function () {
3474      el.removeClass('reader__images--change-postion')
3475    }, 200)
3476  })
3477
3478  $(document).on('mouseenter', '.js-form__checkbox-label', function () {
3479    const el = $(this)
3480    const serviceNum = el.attr("id");
3481    const tooltip = $(".form__service-tooltip[id='" + serviceNum + "']");
3482    tooltip.addClass('form__service-tooltip--hovered');
3483
3484  })
3485
3486  $(document).on('mouseleave', '.js-form__checkbox-label', function () {
3487    const el = $(this)
3488    const serviceNum = el.attr("id");
3489    const tooltip = $(".form__service-tooltip[id='" + serviceNum + "']");
3490
3491    tooltip.removeClass('form__service-tooltip--hovered')
3492  })
3493
3494  $(document).on('click', '.js-accordion-more', function () {
3495    $(this).closest('.article-accordion').addClass('article-accordion--open')
3496  })
3497
3498  $(document).on('click', '.js-accordion-less', function () {
3499    $(this).closest('.article-accordion').removeClass('article-accordion--open')
3500  })
3501
3502  $(document).on('change', '.form__checkbox-input', function () {
3503    $(this).closest('.form__wrap--error').removeClass('form__wrap--error')
3504  })
3505
3506  $(document).on('focus', '.form__input, .form__textarea', function () {
3507    $(this).closest('.form__wrap--error').removeClass('form__wrap--error')
3508  })
3509
3510  $(document).on('click', '.js-get-player', function (e) {
3511    e.preventDefault()
3512
3513    const el = $(this)
3514    const itemId = el.data('id');
3515
3516    $('.inline-audio--overlay').each(function () {
3517      const currentId = $(this).data('id');
3518      if (currentId !== itemId) {
3519        const player = $(this)
3520        if (player.hasClass('inline-audio--overlay-active')) {
3521          player.removeClass('inline-audio--overlay-active')
3522          player.find('.js-player-audio').cbplayer('mediaStop')
3523        }
3524      }
3525    });
3526
3527    const player = $('.inline-audio--overlay[data-id="' + itemId + '"]')
3528    if (!player.length) {
3529      return;
3530    }
3531
3532    player.addClass('inline-audio--overlay-active')
3533    if (el.find('.podcast__play').hasClass('podcast__play--is-playing')) {
3534      player.find('.js-player-audio').cbplayer('mediaPause')
3535      $('.podcast__play--is-playing').removeClass('podcast__play--is-playing')
3536      el.find('.podcast__play').removeClass('podcast__play--is-playing')
3537    } else {
3538      player.find('.js-player-audio').cbplayer('mediaPlay')
3539      $('.podcast__play--is-playing').removeClass('podcast__play--is-playing')
3540      el.find('.podcast__play').addClass('podcast__play--is-playing')
3541    }
3542  })
3543
3544  $(document).on('click', '.js-inline-audio__close', function () {
3545    const button = $(this)
3546
3547    button.closest('.overlayer').removeClass('overlayer--player-active')
3548    button.closest('.inline-audio').removeClass('inline-audio--overlay-active')
3549    button.closest('.cb-player').cbplayer('mediaStop')
3550  })
3551
3552  $(document).on('click', '.js-inline-accordion-toggle', function () {
3553    const el = $(this)
3554    const container = el.closest('.inline-accordion')
3555    const content = container.find('.inline-accordion__content')
3556
3557    if (container.hasClass('inline-accordion--open')) {
3558      container.removeClass('inline-accordion--open')
3559      content.slideUp(fadeDuration)
3560    } else {
3561      container.addClass('inline-accordion--open')
3562      content.slideDown(fadeDuration)
3563    }
3564  })
3565
3566  $(document).on('click', '.js-description-more', function () {
3567    $(this).closest('.overview__description').addClass('overview__description--show-long')
3568  })
3569
3570  $(document).on('click', '.js-description-less', function () {
3571    $(this).closest('.overview__description').removeClass('overview__description--show-long')
3572  })
3573
3574  $(document).on('click', '.js-overlayer-search-close', function () {
3575    $('.overlayer-search').removeClass('overlayer-search--open')
3576  })
3577  $(document).on('click', '.tt-suggestion', function () {
3578    $('.overlayer-search').removeClass('overlayer-search--open')
3579
3580    $('.js-overlayer-search__input').val($(this).text())
3581  })
3582  $(document).on('click', '.js-menu-search', function () {
3583
3584    const el = $(this)
3585/*    const container = el.closest('.main, .overlayer')*/
3586    searchInput = $('.js-overlayer-search__input')
3587
3588    $('.overlayer-search').addClass('overlayer-search--open')
3589    $('.menu').removeClass('.menu--open')
3590
3591    searchInput.focus()
3592
3593    const tempValue = searchInput.val()
3594    searchInput.val('')
3595    searchInput.val(tempValue)
3596  })
3597
3598  $(document).on('click', '.js-overlayer-search-submit', function () {
3599    $(this).closest('.overlayer-search__form').submit()
3600  })
3601
3602  $(document).on('click', '.js-show-video-overlayer', function () {
3603    const overlayer = $(this).closest('.overlayer')
3604    const videoOverlayer = overlayer.find('.video-overlayer')
3605    const player = videoOverlayer.find('.js-videoplayer')
3606
3607    videoOverlayer.fadeIn(fadeDuration)
3608
3609    if (player.hasClass('cb-media-is-ready')) {
3610      player.cbplayer('mediaPlay')
3611    } else {
3612      player.cbplayer({
3613        tpl: false,
3614        autoplay: true,
3615        overlaySpinner: false,
3616        overlayButton: false,
3617        disableClick: true
3618      })
3619    }
3620  })
3621
3622  $(document).on('click', '.js-close-video-overlayer', function () {
3623    const overlayer = $(this).closest('.overlayer')
3624    const videoOverlayer = overlayer.find('.video-overlayer')
3625
3626    videoOverlayer.find('.js-videoplayer').cbplayer('mediaPauseAll')
3627
3628    videoOverlayer.fadeOut(fadeDuration)
3629  })
3630
3631  let mapReady = false
3632  if ($('#map').length) {
3633    const el = $('#map')
3634
3635    mapboxgl.accessToken = 'pk.eyJ1IjoiZWZsdXgiLCJhIjoiY2tvdWtlYmRrMG0yZDJwbGduc29xYnhmYSJ9._VbyfiocV_cdHHlcMri-Dg'
3636    const mapBounds = sessionStorage.getItem('mapBounds')
3637    const map = new mapboxgl.Map({
3638      container: el.get(0),
3639      style: 'mapbox://styles/eflux/ckpx4an1j53vv17n3t5ck4ljz',
3640      center: [6.125833, 51.795556],
3641      zoom: 2,
3642      bounds: mapBounds ? JSON.parse(mapBounds) : false
3643    })
3644
3645    map.addControl(new mapboxgl.NavigationControl({showCompass: false}), 'top-right')
3646
3647    // map.scrollZoom.disable();
3648    map.dragRotate.disable()
3649    map.doubleClickZoom.disable()
3650    map.touchZoomRotate.disableRotation()
3651
3652    const bounds = [
3653      [999, 999],
3654      [-999, -999]
3655    ]
3656
3657    const saveMapState = function () {
3658      sessionStorage.setItem('mapBounds', JSON.stringify(map.getBounds().toArray()))
3659    }
3660
3661    map.on('moveend', saveMapState)
3662    map.on('zoomend', saveMapState)
3663
3664    const markers = {}
3665    let markersOnScreen = {}
3666
3667    map.on('load', function () {
3668      let pointsFromMarkup = {
3669        "type": "FeatureCollection",
3670        "features": [
3671
3672        ]
3673      }
3674      $(".js-map-sidebar-item").each(function(index){
3675        let ths = $(this)
3676        if(ths.find('.mapshow-sidebar-item__title').text()){
3677          pointsFromMarkup.features.push( {
3678            "id": ths.data('id'),
3679            "type": "Feature",
3680            "geometry": {"type": "Point", "coordinates": [ths.data('lng'), ths.data('lat')]},
3681            "properties": {
3682              "order": 1+index,
3683              "title": ths.find('.mapshow-sidebar-item__title').text(),
3684              "type": ths.data('announcementtype'),
3685              "date": ths.find('.mapshow-sidebar-item__date').text(),
3686              "client": ths.find('.mapshow-sidebar-item__client').text(),
3687              "image": ths.find('.mapshow-sidebar-item__image').attr('src'),
3688              "url": ths.find('.mapshow-sidebar-item__title--link').attr('href'),
3689              "overlay": false,
3690              "directionUrl": ths.find('.button--map.coords').attr('href')
3691            }
3692          })
3693        }
3694
3695      })
3696
3697      map.addSource('points', {
3698        type: 'geojson',
3699        data: pointsFromMarkup,
3700        cluster: true,
3701        clusterMaxZoom: 20,
3702        clusterRadius: 50
3703      })
3704
3705      // Add a circle layer
3706      map.addLayer({
3707        id: 'circle',
3708        type: 'circle',
3709        source: 'points',
3710        paint: {
3711          'circle-color': 'transparent',
3712          'circle-radius': 12,
3713          'circle-stroke-width': 0
3714        }
3715      })
3716
3717      if (!mapBounds) {
3718        window.fetch('/v2/api/map/' + el.data('id'))
3719          .then(response => response.json())
3720          .then(geojson => {
3721            geojson.features.forEach(function (feature) {
3722              if (feature.geometry.coordinates[0] < bounds[0][0]) {
3723                bounds[0][0] = feature.geometry.coordinates[0]
3724              }
3725
3726              if (feature.geometry.coordinates[1] < bounds[0][1]) {
3727                bounds[0][1] = feature.geometry.coordinates[1]
3728              }
3729
3730              if (feature.geometry.coordinates[0] > bounds[1][0]) {
3731                bounds[1][0] = feature.geometry.coordinates[0]
3732              }
3733
3734              if (feature.geometry.coordinates[1] > bounds[1][1]) {
3735                bounds[1][1] = feature.geometry.coordinates[1]
3736              }
3737            })
3738
3739            map.fitBounds(bounds, {
3740              duration: 0,
3741              padding: 50
3742            })
3743          })
3744      }
3745
3746      let moveTimeout
3747      map.on('dragend', function () {
3748        clearTimeout(moveTimeout)
3749
3750        moveTimeout = setTimeout(function () {
3751          showMarkersInSidebar(map)
3752        }, 200)
3753      })
3754
3755      map.on('zoomend', function () {
3756        clearTimeout(moveTimeout)
3757
3758        moveTimeout = setTimeout(function () {
3759          showMarkersInSidebar(map)
3760        }, 200)
3761
3762      })
3763
3764      map.on('render', function () {
3765        if (!map.isSourceLoaded('points')) {
3766          return
3767        }
3768
3769        const newMarkers = {}
3770        const features = map.querySourceFeatures('points')
3771        features.forEach(function (feature) {
3772          let marker = markers[feature.id]
3773
3774          if (!marker) {
3775            const el = $('<div class="map__marker"></div>')
3776
3777            if (feature.properties.cluster) {
3778              const clusterId = feature.properties.cluster_id
3779
3780              el.addClass('map__marker--cluster')
3781              if (!isMobile()) {
3782                el.addClass('js-map-cluster-zoom')
3783              }
3784
3785              el.append('<div class="map__marker-label">' + feature.properties.point_count + '</div>')
3786              el.attr({
3787                'data-id': clusterId,
3788                'data-size': feature.properties.point_count,
3789                'data-center': JSON.stringify(feature.geometry.coordinates)
3790              })
3791            } else {
3792              el.addClass('clickable-block js-mapshow-scroll')
3793                .data({
3794                  order: feature.properties.order,
3795                  title: feature.properties.title,
3796                  date: feature.properties.date,
3797                  client: feature.properties.client,
3798                  directionUrl: feature.properties.directionUrl,
3799                  overlay: feature.properties.overlay,
3800                  // url: feature.properties.url
3801                })
3802                .attr('data-id', feature.id)
3803
3804
3805              // if (feature.properties.overlay && !isMobile()) {
3806              //   el.addClass('js-open-overlayer').data('href', feature.properties.url)
3807              // }
3808            }
3809
3810            marker = new mapboxgl.Marker(el[0])
3811              .setLngLat(feature.geometry.coordinates)
3812            markers[feature.id] = marker
3813          }
3814
3815          newMarkers[feature.id] = marker
3816
3817          if (!markersOnScreen[feature.id]) {
3818            marker.addTo(map)
3819          }
3820        })
3821
3822        for (id in markersOnScreen) {
3823          if (!newMarkers[id]) {
3824            markersOnScreen[id].remove()
3825          }
3826        }
3827
3828        markersOnScreen = newMarkers
3829
3830        if (!mapReady) {
3831          showMarkersInSidebar(map)
3832          mapReady = true
3833        }
3834      })
3835
3836      $(document).on('click', '.js-map-cluster-zoom', function () {
3837        const center = $(this).data('center')
3838        map.getSource('points').getClusterExpansionZoom(
3839          $(this).data('id'),
3840          function (err, zoom) {
3841            if (err) return
3842            map.easeTo({
3843              center,
3844              zoom
3845            })
3846          }
3847        )
3848      })
3849    })
3850  }
3851
3852  // $(document).on('mouseenter', '.js-map-sidebar-item', function () {
3853  //   const item = $(this)
3854
3855  //   item.addClass('mapshow-sidebar-item--hover')
3856
3857  //   $('.map__marker[data-id="' + item.attr('data-id') + '"]').addClass('map__marker--hover')
3858  // })
3859
3860  // $(document).on('mouseleave', '.js-map-sidebar-item', function () {
3861  //   const item = $(this)
3862
3863  //   item.removeClass('mapshow-sidebar-item--hover')
3864
3865  //   $('.map__marker').removeClass('map__marker--hover')
3866  // })
3867
3868  // $(document).on(isTouch ? 'click' : 'mouseenter', '.map__marker', function (e) {
3869  //   const item = $(this)
3870
3871  //   if (item.hasClass('map__marker--hover')) {
3872  //     $('.map__marker').removeClass('map__marker--hover')
3873  //     $('.js-map-sidebar-item').removeClass('mapshow-sidebar-item--hover')
3874
3875  //     $('.mapshow__sidebar').removeClass('mapshow__sidebar--visible')
3876  //   } else {
3877  //     $('.map__marker').removeClass('map__marker--hover')
3878  //     $('.js-map-sidebar-item').removeClass('mapshow-sidebar-item--hover')
3879
3880  //     item.addClass('map__marker--hover')
3881
3882  //     $('.js-map-sidebar-item[data-id="' + item.data('id') + '"]').addClass('mapshow-sidebar-item--hover')
3883
3884  //     if (isMobile()) {
3885  //       const container = $('.js-map-sidebar-items')
3886  //       const selectedItems = container.find('.mapshow-sidebar-item--hover')
3887
3888  //       $('.mapshow__sidebar').addClass('mapshow__sidebar--visible')
3889
3890  //       container.addClass('mapshow-sidebar__items--disable-snap')
3891
3892  //       container.scrollLeft(0)
3893
3894  //       setTimeout(function () {
3895  //         container.removeClass('mapshow-sidebar__items--disable-snap')
3896  //       })
3897  //     }
3898  //   }
3899  // })
3900
3901  // $(document).on('mouseleave', '.map__marker', function () {
3902  //   const item = $(this)
3903
3904  //   if (isMobile()) {
3905  //     return
3906  //   }
3907
3908  //   item.removeClass('map__marker--hover')
3909
3910  //   $('.js-map-sidebar-item').removeClass('mapshow-sidebar-item--hover')
3911  // })
3912
3913  $(document).on('click', '.map__marker', function () {
3914    const marker = $(this)
3915    const sidebar = $('.mapshow__sidebar')
3916
3917    if (marker.hasClass('map__marker--hover')) {
3918
3919      marker.removeClass('map__marker--hover')
3920      sidebar.removeClass('mapshow__sidebar--hover')
3921      $('.js-map-sidebar-item').removeClass('mapshow-sidebar-item--hover')
3922
3923    } else {
3924
3925      let otherMarker = $('.map__marker--hover')
3926      if (otherMarker.length) {
3927        $('.js-map-sidebar-item').removeClass('mapshow-sidebar-item--hover')
3928        otherMarker.removeClass('map__marker--hover')
3929      }
3930
3931      const sidebarItem = $('.js-map-sidebar-item[data-id="' + marker.data('id') + '"]')
3932
3933      if ((!isMobile() && !marker.hasClass('js-map-cluster-zoom')) || isMobile()) {
3934        marker.addClass('map__marker--hover')
3935        sidebar.addClass('mapshow__sidebar--hover')
3936        sidebarItem.addClass('mapshow-sidebar-item--hover')
3937      }
3938
3939      if (isMobile()) {
3940        const container = $('.js-map-sidebar-items')
3941        const selectedItems = container.find('.mapshow-sidebar-item--hover')
3942
3943        $('.mapshow__sidebar').addClass('mapshow__sidebar--visible')
3944
3945        container.addClass('mapshow-sidebar__items--disable-snap')
3946
3947        container.scrollLeft(0)
3948
3949        setTimeout(function () {
3950          container.removeClass('mapshow-sidebar__items--disable-snap')
3951        })
3952      } else if (marker.hasClass('js-mapshow-scroll')) {
3953        const sidebarScroller = $('.mapshow__sidebar-scroller')
3954        let top = sidebarScroller.scrollTop() + sidebarItem.offset().top - $('.header').height()
3955
3956        sidebarScroller.animate({
3957          scrollTop: top
3958        }, 300)
3959      }
3960    }
3961  })
3962
3963  $(document).on('click', '.js-institution-map-button', function () {
3964    const nextBlock = $(this).closest('.mapshow').next()
3965
3966    if (nextBlock.length) {
3967      let top = nextBlock.offset().top - parseInt(nextBlock.css('margin-top'))
3968
3969      $('html, body').animate({
3970        scrollTop: top
3971      }, 300)
3972    }
3973  })
3974
3975  $(document).on('mouseenter', '.js-mouse-tracker-area', function () {
3976    const container = $(this)
3977    const tracker = container.find('.inline-media__tracker')
3978
3979    tracker.show()
3980  })
3981
3982  $(document).on('mousemove', '.js-mouse-tracker-area', function (e) {
3983    const container = $(this)
3984    const tracker = container.find('.inline-media__tracker')
3985
3986    tracker.css({
3987      top: e.offsetY,
3988      left: e.offsetX
3989    })
3990  })
3991
3992  $(document).on('mouseleave', '.js-mouse-tracker-area', function () {
3993    const container = $(this)
3994    const tracker = container.find('.inline-media__tracker')
3995
3996    tracker.hide()
3997  })
3998
3999  $('.inline-media').each(function () {
4000    let image = $(this)
4001    image.css('max-width', image.data('width')).addClass("inline-media--small")
4002  })
4003
4004  $(document).on('click', '.js-search-toggle-bio', function () {
4005    const button = $(this)
4006    const bio = $('.search-results__bio')
4007
4008    if (button.hasClass('header__inner-search-bio--open')) {
4009      $('.js-search-toggle-bio').removeClass('header__inner-search-bio--open')
4010      bio.slideUp(fadeDuration)
4011    } else {
4012      $('.js-search-toggle-bio').addClass('header__inner-search-bio--open')
4013      bio.slideDown(fadeDuration)
4014
4015      $('html, body').animate({
4016        scrollTop: 0
4017      }, 200)
4018    }
4019  })
4020
4021  $(document).on('click', '.js-preview-topic__arrow', function () {
4022    $(this).closest('.preview-topic').toggleClass('preview-topic--open')
4023  })
4024
4025  $(document).on('click', '.js-homepage-arrow', function () {
4026    const button = $(this)
4027    const carousel = button.closest('.homepage-section').find('.js-homepage-carousel')
4028
4029    if (button.hasClass('homepage-arrow--prev')) {
4030      carousel.flickity('previous')
4031    } else {
4032      carousel.flickity('next')
4033    }
4034  })
4035
4036  $(document).on('click', '.js-journalinfo-more', function () {
4037    $('.journal__info').addClass('journal__info--open')
4038  })
4039
4040  $(document).on('click', '.js-journalinfo-less', function () {
4041    $('.journal__info').removeClass('journal__info--open')
4042  })
4043
4044  $(document).on('click', '.js-header__dropdown', function () {
4045    const container = $(this).closest('.header__dropdown')
4046
4047    if (container.hasClass('header__dropdown--open')) {
4048      $('.header__dropdown').removeClass('header__dropdown--open')
4049    } else {
4050      $('.header__dropdown').addClass('header__dropdown--open')
4051    }
4052  })
4053
4054  $(window).on('hashchange', function (e) {
4055    console.log('hash changed')
4056    if (location.hash) {
4057      hash = location.hash.substr(1)
4058
4059      const videoAccordion = $('.video-accordion[data-hash="' + hash + '"]')
4060
4061      if (hash.substr(0, 4) == 'rsvp') {
4062        const form = $('.overlayer-form[data-overlayer="rsvp"]')
4063
4064        form.fadeIn(fadeDuration)
4065        form.find('.form__input').eq(0).focus()
4066        if (hash.substr(0, 5) == 'rsvp-') {
4067          $('[name="rsvp_email"]').val(hash.substr(5));
4068        }
4069      } else if (hash == 'subscribe') {
4070        const form = $('.overlayer-form[data-overlayer="subscribe"]')
4071
4072        form.fadeIn(fadeDuration)
4073        form.find('.form__input').eq(0).focus()
4074      } else if (hash == 'login') {
4075        const form = $('.overlayer-form[data-overlayer="login"]')
4076
4077        form.fadeIn(fadeDuration)
4078        form.find('.form__input').eq(0).focus()
4079      } else if (hash == 'issues') {
4080        e.preventDefault()
4081        if($('#issues').length){
4082          $(window).scrollTop($('#issues').offset().top - 65)
4083        }
4084
4085      } else if (hash == 'upcoming' || hash == 'archive') {
4086        e.preventDefault()
4087        setTimeout(() => $(`.js-header-jumplink[data-jump="${hash}"]`).trigger('click'))
4088      } else if (videoAccordion.length) {
4089        jumpToAccordion(videoAccordion)
4090      }
4091    }
4092  })
4093  $(window).trigger('hashchange')
4094
4095  $(window).on('popstate', function () {
4096    waitForElement('.video-accordion[data-hash]', 3000).then(function () {
4097      $(window).trigger('hashchange')
4098    }).catch(function () {})
4099  })
4100
4101  $(document).on('click', '.js-anchor-click', (e) => {
4102    location.hash = '#issues'
4103    $(window).trigger('hashchange')
4104    e.preventDefault()
4105  })
4106
4107  $(document).on('click', '.js-article-ad-sound', function () {
4108    const button = $(this)
4109    const player = button.closest('.article-ad__inner').find('.cb-player')
4110
4111    if (button.hasClass('article-ad__sound--off')) {
4112      button.removeClass('article-ad__sound--off')
4113      player.cbplayer('mediaSetVolume', 100)
4114    } else {
4115      button.addClass('article-ad__sound--off')
4116      player.cbplayer('mediaSetVolume', 0)
4117    }
4118  })
4119
4120  // Keep up to date with history changes
4121  window.addEventListener('popstate', function (e) {
4122    if (location.hash) {
4123      return false
4124    }
4125
4126    if (activeAfterPageLoad != false) {
4127      location.reload()
4128    }
4129  }, false)
4130
4131  function loadMore(panel) {
4132    panel.addClass('is-loading')
4133
4134    const pageUrl = panel.data('load-more-url')
4135    let currentPage = panel.data('current-page')
4136
4137    return new Promise(function (resolve, reject) {
4138      if (pageUrl != undefined && pageUrl != null) {
4139        panel.addClass('is-loading')
4140        if (currentPage == undefined) {
4141          currentPage = 0
4142        }
4143        currentPage = currentPage + 1
4144        panel.data('current-page', currentPage)
4145        fetch(pageUrl.replace('%d', currentPage))
4146          .then(res => res.text())
4147          .then(html => {
4148            html = $(html)
4149            const hasMore = html.children().length > 0
4150            if (hasMore) {
4151              // Show more items
4152              html.children().appendTo(panel)
4153            } else {
4154              // No more items, don’t try to load more items
4155              panel.data('load-more-url', null)
4156            }
4157            panel.removeClass('is-loading')
4158            resolve(hasMore)
4159          })
4160      }
4161    })
4162  }
4163
4164  $(document).on('click', '.js-header-jumplink', function () {
4165    const el = $(this)
4166    const section = $('.announcements__group[data-section="' + el.data('jump') + '"]')
4167    const marquee = el.closest('.main').find('.marquee')
4168
4169    if (section.length) {
4170      let position = section.offset().top - $('.header').height() + 1
4171
4172      if (el.closest('.header__dropdown').length) {
4173        el.closest('.header__dropdown').removeClass('header__dropdown--open')
4174      }
4175
4176      if (marquee.length) {
4177        position = position - marquee.height()
4178      }
4179
4180      $('html, body').animate({
4181        scrollTop: position
4182      }, 300)
4183    }
4184  })
4185
4186  $(document).on('click', '.related-dot', function () {
4187    const dot = $(this)
4188    const slider = dot.closest('.related').find('.related__carousel')
4189
4190    slider.removeClass('related__carousel-snap-active')
4191
4192    const selectedSlide = slider.find('.related__item').eq(dot.index())
4193
4194    const selectedSlidePosition = slider.scrollLeft() + selectedSlide.offset().left
4195
4196    slider.animate({
4197      scrollLeft: selectedSlidePosition + 'px'
4198    }, 250, () => slider.addClass('related__carousel-snap-active'))
4199  })
4200
4201  $(document).on('click', '.js-related__item-thumb', function () {
4202    const slide = $(this)
4203
4204    const container = $(this).closest('.block-media').find('.block-media-exhibition')
4205    const caption = container.find('.block-media-exhibition__caption')
4206    const image = container.find('.block-media-exhibition__image')
4207
4208    // Clear
4209    container.removeClass('block-media-exhibition--landscape block-media-exhibition--portrait')
4210    caption.empty()
4211    image.empty()
4212
4213    // Add new image
4214
4215    if (slide.data('ratio') >= 1) {
4216      container.addClass('block-media-exhibition--landscape')
4217    } else {
4218      container.addClass('block-media-exhibition--portrait')
4219    }
4220
4221    caption.html(slide.data('caption'))
4222    image.css('padding-bottom', 1 / slide.data('ratio') * 100 + '%');
4223    slide.find('img').clone().appendTo(image)
4224
4225
4226    lazySizes.autoSizer.checkElems()
4227
4228  })
4229
4230  $(document).on('click', '.js-form__checkbox-button', function (e) {
4231    const button = $(this)
4232    const checkbox = $('.form__checkbox-input[id="' + button.data('for') + '"]')
4233    let allCheckedCheckboxes = button.closest('.form__wrap-checkbox-group').find('.form__checkbox-input:checked')
4234    if (allCheckedCheckboxes.length == 0) {
4235      allCheckedCheckboxes = button.closest('.form__wrap-checkbox-group').find('.form__checkbox-input[defaultChecked=true]')
4236    }
4237
4238    if (allCheckedCheckboxes.length == 1) {
4239      if (!checkbox.prop('checked')) {
4240        checkbox.prop('checked', !checkbox.prop('checked'))
4241      }
4242    } else {
4243      checkbox.prop('checked', !checkbox.prop('checked'))
4244    }
4245  })
4246
4247    $(document).on('click', '.js-load-more-books', function () {
4248      const button = $(this)
4249      const books = $('.preview-books')
4250      books.find('.preview-item--hidden:lt(10)').removeClass("preview-item--hidden")
4251      if (books.find('.preview-item--hidden').length == 0) {
4252        button.hide()
4253      }
4254
4255    })
4256
4257
4258  $(window).on('scroll', function () {
4259    const wScrolltop = $(window).scrollTop()
4260    const wScrollbottom = wScrolltop + $(window).height()
4261
4262    // Load more on scroll
4263    $('.js-load-more-on-scroll:not(.is-loading)').each(function () {
4264      const panel = $(this)
4265
4266      if (wScrolltop + $(window).height() * 2 >= panel.offset().top + panel.height()) {
4267        loadMore(panel)
4268      }
4269    })
4270
4271    const container = $('.js-infinite-container')
4272
4273    if (container.length) {
4274      const trigger = container.find('.js-search-results-trigger')
4275      let pageUrl = /*container.data('page-url')*/ location.href
4276      if(pageUrl.indexOf("page=")!=-1){
4277        pageUrl = pageUrl.replace(/page=\d/i,"page=%d")
4278      }else{
4279        pageUrl+= "&page=%d"
4280      }
4281
4282      let currentPage = container.data('current-page')
4283
4284      if (trigger.hasClass('infinite-loading__spinner--active')) {
4285        return
4286      }
4287
4288      if (wScrollbottom > trigger.offset().top + trigger.outerHeight()) {
4289        if (pageUrl != undefined && pageUrl != null) {
4290          if (currentPage == undefined) {
4291            currentPage = 1
4292          }
4293
4294          trigger.addClass('infinite-loading__spinner--active')
4295
4296          currentPage = currentPage + 1
4297          container.data('current-page', currentPage)
4298
4299
4300          fetch(pageUrl.replace('%d', currentPage))
4301            .then(res => res.text())
4302            .then(html => {
4303              html = $(html).find(".js-infinite-container")
4304
4305              if (html.children().length > 0) {
4306                // Show more items
4307                html.children().appendTo(container)
4308
4309                trigger.appendTo(container)
4310              } else {
4311                // No more items, don’t try to load more items
4312                container.data('page-url', null)
4313              }
4314              trigger.removeClass('infinite-loading__spinner--active')
4315              container.find('.js-search-results-trigger').eq(0).remove()
4316            })
4317        }
4318      }
4319    }
4320
4321    const autoHeaderBorder = $('.js-header--border')
4322    if (autoHeaderBorder.length) {
4323      if (wScrolltop > 1) {
4324        autoHeaderBorder.addClass('header--border')
4325      } else {
4326        autoHeaderBorder.removeClass('header--border')
4327      }
4328    }
4329
4330    const homeAd = $('.js-article-ad-hide-on-scroll')
4331    const notesFixedHeader = $('.js-notes-variable-z-header');
4332    if (homeAd.length) {
4333      const trigger = $('.js-ad-trigger')
4334      if(trigger.length){
4335        if (trigger.offset().top < wScrolltop) {
4336          homeAd.addClass('article-ad--hidden')
4337          if (notesFixedHeader) {
4338            notesFixedHeader.addClass('notes-fixed-header-higher-z');
4339          }
4340        } else {
4341          homeAd.removeClass('article-ad--hidden')
4342          if (notesFixedHeader) {
4343            notesFixedHeader.removeClass('notes-fixed-header-higher-z');
4344          }
4345        }
4346      }else{
4347        homeAd.detach()
4348      }
4349
4350    }
4351
4352    hideSidebar()
4353    hideAd()
4354    hideTopHeader()
4355    hideHeader()
4356    appAnimation()
4357    fadeHeader()
4358  })
4359
4360  carouselHomepageJournal()
4361
4362  let afterResize
4363  $(window).on('resize', function () {
4364    if(!$('.js-ad-trigger').length){
4365      $('.js-ad-trigger').detach()
4366    }
4367    setScreenHeight()
4368    carouselArticlePreInit()
4369    relatedStyle()
4370    videoCarouselStyle()
4371    contentTopBorder()
4372    relatedGradient()
4373    videoCarouselGradient()
4374    hideSidebar()
4375    hideAd()
4376    hideHeader()
4377    sidebarHeightMobile()
4378    siebarScrollArea()
4379    journalImageHeight()
4380    scaleIssueTop()
4381    setMapHeight()
4382    buyButtonTooltip()
4383    overlayerBgPosition()
4384    appLayerSizes()
4385    topicBottomheight()
4386    sideAd()
4387    carouselHomepageJournal()
4388    adArticleHeight()
4389    criticismLimitPreview()
4390    alignRelatedMoreButton()
4391    featuredCarouselContentWidth()
4392
4393    clearTimeout(afterResize)
4394    afterResize = setTimeout(function () {
4395      initMarquee(true)
4396    }, 150)
4397
4398    fitFeaturedCarouselImages($('.featured-projects__carousel'))
4399  })
4400
4401  $(window).on('gesturechange', function (e) {
4402    if (e.originalEvent.scale > 1) {
4403      $('.article-ad--safari').addClass('article-ad--hide')
4404    }
4405  })
4406
4407  if (window.ShopifyBuy) {
4408    if (window.ShopifyBuy.UI) {
4409      ShopifyBuyInit()
4410    } else {
4411      loadScript()
4412    }
4413  } else {
4414    loadScript()
4415  }
4416
4417  //video 2 accordion
4418  $(document).on('click', '.js-video-accordion-toggle', function () {
4419    const accordion = $(this).closest('.video-accordion')
4420    const content = accordion.find('.video-accordion__content')
4421    const baseurl = $('.videos').data('baseurl')
4422
4423    if (accordion.hasClass('video-accordion--open')) {
4424      accordion.removeClass('video-accordion--open')
4425      content.hide()
4426
4427      window.history.pushState(null, null, baseurl)
4428
4429    } else {
4430      accordion.addClass('video-accordion--open')
4431      content.show()
4432
4433      videoCarouselStyle()
4434      videoCarouselGradient()
4435
4436      let url = baseurl + '#' + accordion.data('hash')
4437      window.history.pushState(null, null, url)
4438    }
4439  })
4440
4441  const filterCalendar = $('.js-filter-calendar')
4442  if (filterCalendar.length) {
4443
4444    let minYear = 2001
4445    if (filterCalendar.data('minyear')) {
4446      minYear = filterCalendar.data('minyear')
4447    }
4448
4449    const maxYear = new Date().getFullYear() + 1
4450
4451    filterCalendar.daterangepicker({
4452      locale: {
4453        format: 'MM/DD/YYYY',
4454        daysOfWeek: [
4455          'S',
4456          'M',
4457          'T',
4458          'W',
4459          'T',
4460          'F',
4461          'S'
4462        ],
4463        applyLabel: 'Select'
4464      },
4465      autoUpdateInput: false,
4466      linkedCalendars: false,
4467      showDropdowns: true,
4468      minYear: minYear,
4469      maxYear: maxYear
4470    });
4471
4472    filterCalendar.on('show.daterangepicker', function (e, p) {
4473      $(this).closest('.filter-category').addClass('filter-category--open')
4474
4475      const calendar = $(p.container[0])
4476
4477      if (!calendar.find('.daterangepicker__inner').length) {
4478        calendar.children().wrapAll('<div class="daterangepicker__inner"></div>')
4479        calendar.find('.daterangepicker__inner').append('<div class="daterangepicker__close"></div>')
4480      }
4481    })
4482
4483    filterCalendar.on('hide.daterangepicker', function (e, p) {
4484      $(this).closest('.filter-category').removeClass('filter-category--open')
4485    })
4486
4487    filterCalendar.on('apply.daterangepicker', function (e, p) {
4488
4489      const dates = $(this).closest('.filter-category').find('.filter-dates')
4490      const selectedItems = $(this).closest('.filter-category').find('.filter-category__selected')
4491
4492      // $('#filterstartdate').val(p.startDate.format('MM/DD/YYYY'))
4493      // $('#filterenddate').val(p.endDate.format('MM/DD/YYYY'))
4494
4495      const label = p.startDate.format('MM/DD/YYYY') + ' - ' + p.endDate.format('MM/DD/YYYY')
4496      const value = p.startDate.format('YYYY-MM-DD') + ',' + p.endDate.format('YYYY-MM-DD')
4497
4498      // Remove current selection
4499      dates.empty()
4500      selectedItems.empty()
4501
4502      // Add filter item
4503      $('<span class="filter-item-clickable filter-item-clickable--selected js-filter-item" />')
4504        .data('filter', value)
4505        .data('id', value)
4506        .data('name', 'ed')
4507        .appendTo(dates)
4508
4509      // Add selected item
4510      $('<span class="filter-category__selected-item" />')
4511        .data('id', value)
4512        .text(label)
4513        .appendTo(selectedItems)
4514
4515      // Show selected items
4516      selectedItems.addClass('filter-category__selected--visible')
4517
4518      // Reset select
4519      $(this).data('daterangepicker').setStartDate(moment().format("MM-DD-YYYY")); //date now
4520      $(this).data('daterangepicker').setEndDate(moment().format("MM-DD-YYYY")); //date now
4521
4522      updateSearchResults()
4523    })
4524
4525    $(document).on('click', '.daterangepicker__close', function () {
4526      filterCalendar.data('daterangepicker').hide()
4527    })
4528
4529    $(window).on('scroll', function () {
4530      if (!isMobile()) {
4531        filterCalendar.data('daterangepicker').hide()
4532      }
4533    })
4534  }
4535
4536
4537
4538  $(document).on('click', '.js-dubletake-
4538artist', function () {
4539    const button = $(this)
4540    const container = $('.article__doubletake')
4541    const selectedClass = 'article__doubletake--' + button.data('dubletake')
4542
4543    if (container.hasClass(selectedClass)) {
4544      container.removeClass(selectedClass)
4545    } else {
4546
4547      if (container.hasClass('article__doubletake--first') || container.hasClass('article__doubletake--second')) {
4548        container.removeClass('article__doubletake--first article__doubletake--second')
4549      }
4550
4551      container.addClass(selectedClass)
4552    }
4553  })
4554
4555  $(document).on('click', '.js-backtotop', function () {
4556    $('html, body').animate({
4557      scrollTop: 0
4558    }, 500)
4559  })
4560
4561/*  $(document)
4562    .on('click', '.clickable-block', function (e) {
4563      if ($(this).hasClass('js-open-overlayer')) {
4564        return
4565      }
4566
4567      if ($(e.target).is('a')) {
4568        return
4569      }
4570      const href = $(this).data('href')
4571      if (!href) {
4572        return
4573      }
4574
4575      const a = document.createElement('a')
4576      a.href = href
4577      if (a.hostname != location.hostname) {
4578        window.open(href)
4579        return false
4580      }
4581
4582      location.href = href
4583      return false
4584    })*/
4585
4586/*  $(document)
4587    .on('click', 'a', function (e) {
4588      if ($(this).closest('.js-open-overlayer').length || $(this).hasClass('.js-get-player')) {
4589        e.preventDefault()
4590        return
4591      }
4592
4593      if ($(this).hasClass('js-subscribe-close')) {
4594        closeSubscribeInfo($(this))
4595      }
4596
4597      if ((this.hostname != location.hostname || $(this).hasClass('open-in-new-tab') || $(this).attr('href').substr(0, 7) == '/files/') && $(this).attr('href').substr(0, 7) != 'mailto:') {
4598        this.blur()
4599        window.open(this.href)
4600        e.preventDefault()
4601      }
4602    })*/
4603
4604
4605  window.addEventListener('beforeprint', (event) => {
4606    $('.js-inline-print-image').each(function () {
4607      let image = $(this)
4608
4609      image
4610        .attr('src', image.data('image'))
4611        .addClass('inline-print-image--active')
4612    })
4613  });
4614
4615
4616  window.addEventListener('afterprint', (event) => {
4617    $('.js-inline-print-image').each(function () {
4618      let image = $(this)
4619
4620      image
4621        .removeClass('inline-print-image--active')
4622    })
4623  })
4624
4625  // $(window).on('keydown', function (e) {
4626  //   if (e.which == 71) {
4627  //     $('#grid').toggleClass('grid--hidden')
4628  //   }
4629  // })
4630})
4631
4632
4633/**
4634 * Wait for an element before resolving a promise
4635 * @param {String} querySelector - Selector of element to wait for
4636 * @param {Integer} timeout - Milliseconds to wait before timing out, or 0 for no timeout
4637 */
4638function waitForElement(querySelector, timeout){
4639  return new Promise((resolve, reject)=>{
4640    var timer = false;
4641    var element = document.querySelectorAll(querySelector)[0]
4642
4643    if(element) return resolve();
4644    const observer = new MutationObserver(()=>{
4645      var element = document.querySelectorAll(querySelector)[0]
4646
4647      if(element){
4648        observer.disconnect();
4649        if(timer !== false) clearTimeout(timer);
4650        return resolve();
4651      }
4652    });
4653    observer.observe(document.body, {
4654      childList: true,
4655      subtree: true
4656    });
4657    if(timeout) timer = setTimeout(()=>{
4658      observer.disconnect();
4659      reject();
4660    }, timeout);
4661  });
4662}
4663
4664function createShareLinks(){
4665/*  $(".menu__shop").attr("href",function (){
4666    let href = undefined
4667    fetch("/api/getLastShop")
4668      .then(resp => resp.json())
4669      .then(data => {
4670        href = data.href
4671      })
4672  })*/
4673
4674    $(".js-set-fb-link").attr("href",(
4675      "https://www.facebook.com/sharer.php?u="
4676      +location.href
4677      +"&t="
4678      + encodeURI($("title").text())
4679    ));
4680    $(".js-set-mail-link").each(function (){
4681      $(this).attr("href",(
4682        "mailto:?subject="
4683        + encodeURI($("title").text())
4684        +"&body="
4685        +$(this).attr('data-body')+ " " + location.href
4686    ))
4687    })
4688
4689
4690
4691
4692    $(".js-set-twitter-link").attr("href",(
4693      "https://x.com/intent/tweet?url="
4694      +location.href
4695      +"&text="
4696      + $("title").text()
4697    ));
4698
4699
4700  return true
4701}
4702$(document).ready(function(){
4703  $("img").on("load",function (){
4704    $(window).trigger('resize');
4705  })
4706  $(document).on("click",".js-slowcroll", function (){
4707    document.querySelector($(this).attr('data-to')).scrollIntoView({
4708      behavior: 'smooth'
4709    });
4710  })
4711})
4712function initSidebarArrow(){
4713  $('.js-related-items').each(function () {
4714    const related = $(this)
4715
4716    const relatedItems = related.find('.related__item')
4717
4718
4719    if (relatedItems.length) {
4720      related.addClass('related--visible')
4721
4722      $('.js-sidebar-related').addClass('sidebar__bottom-related--visible')
4723
4724      relatedStyle()
4725      relatedGradient()
4726      sidebarHeightMobile()
4727      siebarScrollArea()
4728    }
4729  })
4730}
4731function initCalendar(){
4732
4733  const filterCalendar = $('.js-filter-calendar')
4734  if (filterCalendar.length) {
4735
4736    let minYear = 2001
4737    if (filterCalendar.data('minyear')) {
4738      minYear = filterCalendar.data('minyear')
4739    }
4740
4741    const maxYear = new Date().getFullYear() + 1
4742
4743    filterCalendar.daterangepicker({
4744      locale: {
4745        format: 'MM/DD/YYYY',
4746        daysOfWeek: [
4747          'S',
4748          'M',
4749          'T',
4750          'W',
4751          'T',
4752          'F',
4753          'S'
4754        ],
4755        applyLabel: 'Select'
4756      },
4757      autoUpdateInput: false,
4758      linkedCalendars: false,
4759      showDropdowns: true,
4760      minYear: minYear,
4761      maxYear: maxYear
4762    });
4763
4764    filterCalendar.on('show.daterangepicker', function (e, p) {
4765      $(this).closest('.filter-category').addClass('filter-category--open')
4766
4767      const calendar = $(p.container[0])
4768
4769      if (!calendar.find('.daterangepicker__inner').length) {
4770        calendar.children().wrapAll('<div class="daterangepicker__inner"></div>')
4771        calendar.find('.daterangepicker__inner').append('<div class="daterangepicker__close"></div>')
4772      }
4773    })
4774
4775    filterCalendar.on('hide.daterangepicker', function (e, p) {
4776      $(this).closest('.filter-category').removeClass('filter-category--open')
4777    })
4778
4779    filterCalendar.on('apply.daterangepicker', function (e, p) {
4780
4781      const dates = $(this).closest('.filter-category').find('.filter-dates')
4782      const selectedItems = $(this).closest('.filter-category').find('.filter-category__selected')
4783
4784      // $('#filterstartdate').val(p.startDate.format('MM/DD/YYYY'))
4785      // $('#filterenddate').val(p.endDate.format('MM/DD/YYYY'))
4786
4787      const label = p.startDate.format('MM/DD/YYYY') + ' - ' + p.endDate.format('MM/DD/YYYY')
4788      const value = p.startDate.format('YYYY-MM-DD') + ',' + p.endDate.format('YYYY-MM-DD')
4789
4790      // Remove current selection
4791      dates.empty()
4792      selectedItems.empty()
4793
4794      // Add filter item
4795      $('<span class="filter-item-clickable filter-item-clickable--selected js-filter-item" />')
4796        .data('filter', value)
4797        .data('id', value)
4798        .data('name', 'ed')
4799        .appendTo(dates)
4800
4801      // Add selected item
4802      $('<span class="filter-category__selected-item" />')
4803        .data('id', value)
4804        .text(label)
4805        .appendTo(selectedItems)
4806
4807      // Show selected items
4808      selectedItems.addClass('filter-category__selected--visible')
4809
4810      // Reset select
4811      $(this).data('daterangepicker').setStartDate(moment().format("MM-DD-YYYY")); //date now
4812      $(this).data('daterangepicker').setEndDate(moment().format("MM-DD-YYYY")); //date now
4813
4814      updateSearchResults()
4815    })
4816
4817    $(document).on('click', '.daterangepicker__close', function () {
4818      filterCalendar.data('daterangepicker').hide()
4819    })
4820
4821    $(window).on('scroll', function () {
4822      if (!isMobile()) {
4823        filterCalendar.data('daterangepicker').hide()
4824      }
4825    })
4826  }
4827}
4828function triggerResize(){
4829  $(window).trigger('scroll')
4830  $(window).trigger('resize')
4831}
4832function loadShopify(){
4833
4834  if ($('.js-shop-button-custom:not(.triggered)').length) {
4835
4836    $('.js-shop-button-custom:not(.triggered)').addClass('triggered')
4837    const script = document.createElement('script')
4838    script.async = true
4839    script.src = scriptURL;
4840    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script)
4841
4842    if ($('.js-shop-button-custom').length) {
4843      const items = $('.js-shop-button-custom')
4844
4845      script.onload = function () {
4846        ShopifyBuyInit(items)
4847        scriptIsLoaded = true
4848      }
4849    }
4850  }
4851}
4852function reinitForm(){
4853  $('.js-overlayer-form').ajaxForm({
4854    beforeSubmit: function (formData, form, options) {
4855      const captcha = $('input[name="g-recaptcha-response"][value!=""]')
4856      let error = false
4857      console.log(captcha.val())
4858      if (captcha.val()=="") {
4859        $(".js-overlayer-subscribeform #error-captcha").text("Please submit the captcha")
4860        error = true
4861      }
4862
4863      window.fetch("https://backend-api.e-flux-systems.com/api/checkCaptcha?g-recaptcha-response="+captcha.val(),{
4864        method: 'POST',
4865        dataType: 'json',
4866        data:{
4867          "g-recaptcha-response": captcha.val()??""
4868        }
4869      }).then(function (response) {
4870        if(!response.ok){
4871          error = true
4872        }
4873      })
4874
4875      if (error) {
4876        return false
4877      }
4878      form.find('.button--submit').prop('disabled', true)
4879    },
4880    success: function (response, status, xhr, form) {
4881      if (response.ok) {
4882        if (form.hasClass('js-close-after-submit')) {
4883          closeOverlayerForm(form.closest('.overlayer-form'))
4884        } else {
4885          form.addClass('el-hidden')
4886
4887          if (form.closest('.overlayer-form--inline').length) {
4888            form.closest('.overlayer-form--inline').find('.overlayer-form__successful').removeClass('el-hidden')
4889          } else {
4890            form.closest('.overlayer-form__content').find('.overlayer-form__successful').removeClass('el-hidden')
4891            window.history.pushState(null, null, window.location.origin + window.location.pathname)
4892          }
4893          $(".button--rsvpbutton--ticket").hide()
4894        }
4895      } else {
4896        if (response.missing) {
4897          const prefix = form.data('type')
4898
4899          $.each(response.missing, function (i, fieldName) {
4900            $('[name="' + prefix + '_' + fieldName + '"]').closest('.form__wrap-input, .form__wrap-checkbox, .form__wrap-textarea').addClass('form__wrap--error')
4901          })
4902        }
4903      }
4904    }
4905  })
4906
4907  $('.js-overlayer-subscribeform').ajaxForm({
4908    beforeSubmit: function (formData, form, options) {
4909      let error = false
4910
4911      const email = form.find('input[name="email"]')
4912      if (email.val()) {
4913        if (!isEmail(email.val())) {
4914          email.closest('.form__wrap-input').addClass('form__wrap--error')
4915          error = true
4916        }
4917      } else {
4918        email.closest('.form__wrap-input').addClass('form__wrap--error')
4919        error = true
4920      }
4921
4922      const privacy = form.find('input[name="privacy"]')
4923      if (!privacy.is(':checked')) {
4924        privacy.closest('.form__wrap-checkbox ').addClass('form__wrap--error')
4925        error = true
4926      }
4927      const captcha = $('input[name="g-recaptcha-response"][value!=""]')
4928
4929      window.fetch("https://backend-api.e-flux-systems.com/api/checkCaptcha?g-recaptcha-response="+captcha.val(),{
4930        method: 'POST',
4931        dataType: 'json',
4932        data:{
4933          "g-recaptcha-response": captcha.val()??""
4934        }
4935      }).then(function (response) {
4936        if(!response.ok){
4937          error = true
4938        }
4939      })
4940      if (captcha.val()=="") {
4941        $(".js-overlayer-subscribeform #error-captcha").text("Please submit the captcha")
4942        error = true
4943      }else {
4944        $(".js-overlayer-subscribeform #error-captcha").text("")
4945      }
4946      if (error) {
4947        return false
4948      }
4949
4950      form.find('.button--submit').prop('disabled', true)
4951    },
4952    success: function (response, status, xhr, form) {
4953      if (response.ok) {
4954        form.addClass('el-hidden')
4955        form.closest('.overlayer-form__content').find('.overlayer-form__successful').removeClass('el-hidden')
4956        window.history.pushState(null, null, window.location.origin + window.location.pathname)
4957      } else {
4958        if (response.missing) {
4959          $.each(response.missing, function (i, fieldName) {
4960            $('[name="' + fieldName + '"]').closest('.form__wrap-input, .form__wrap-checkbox').addClass('form__wrap--error')
4961          })
4962        }
4963
4964        form.find('.button--submit').prop('disabled', false)
4965      }
4966    }
4967  })
4968}
4969// Subscribe handle
4970const subscribeBanner = $('.landing-subscribe')
4971const subscribePopup = $('.subscribe-popup-custom')
4972
4973let subscribePopupActive = false
4974
4975if (!getCookie('hidesubscribepopup')) {
4976  // Show subscribe popup after 10s
4977  subscribePopupActive = true
4978
4979  setTimeout(() => {
4980    $(".subscribe-popup-custom").fadeIn(300)
4981  }, 10000)
4982}
4983
4984$(document).on('click', '.js-subscribe-popup-close', function () {
4985  closeSubscribePopup($(this))
4986})
4987
4988// Show bottom banner
4989if (!getCookie('hidesubscribeform') && subscribePopupActive === false) {
4990
4991  // Log page loads
4992  logPageLoads()
4993
4994  // After 3 page loads show bottom subscribe banner
4995  if (readPageLoads() >= 3) {
4996    subscribeBanner.show()
4997  }
4998} else if (getCookie('hidesubscribeform')) {
4999  resetPageLoads()
5000}
5001
5002$(document).on('click', '.js-landing-subscribe-close', function () {
5003  closeSubscribeInfo($(this))
5004})
5005
5006
5007
5008function closeSubscribePopup(item) {
5009  item.fadeOut()
5010
5011  // Hide popup for one day
5012  const d = new Date();
5013  d.setTime(d.getTime() + (24 * 60 * 60 * 1000));
5014  const expires = "expires=" + d.toUTCString();
5015
5016  document.cookie = 'hidesubscribepopup=1; ' + expires + ';path=/'
5017}
5018
5019function readPageLoads() {
5020  const key = 'subscribe-banner-page-loads'
5021  return localStorage.getItem(key)
5022}
5023
5024function resetPageLoads() {
5025  const key = 'subscribe-banner-page-loads'
5026  localStorage.setItem(key, 0)
5027}
5028function initVideo() {
5029  $('.js-videoheaderplayer').cbplayer({
5030    tpl: false,
5031    autoplay: false,
5032    overlaySpinner: false,
5033    overlayButton: false,
5034    disableClick: true
5035  })
5036}
5037function initInlineVideo() {
5038  $('.js-videoplayer').cbplayer({
5039    tpl: false,
5040    autoplay: false,
5041    overlaySpinner: false,
5042    overlayButton: false,
5043    disableClick: true
5044  })
5045}
5046function lightbox() {
5047  $('.js-lightbox').cblightbox({
5048    margin: [0, 150],
5049    captionPosition: 'inside',
5050    counter: false,
5051    closeOutsideClick: false,
5052    zoom: true,
5053    zoomSize: 10,
5054    zoomControlls: true,
5055    zoomSteps: 5
5056  })
5057}
5058
5059function logPageLoads() {
5060  const key = 'subscribe-banner-page-loads'
5061  let count = parseInt(readPageLoads())
5062
5063  if (!count) {
5064    count = 0
5065  }
5066
5067  count = count + 1
5068
5069  if (count >= 3) {
5070    count = 3
5071  }
5072
5073  return localStorage.setItem(key, count)
5074}
5075
5076function getCookie(cname) {
5077  let name = cname + "=";
5078  let decodedCookie = decodeURIComponent(document.cookie);
5079  let ca = decodedCookie.split(';');
5080  for (let i = 0; i < ca.length; i++) {
5081    let c = ca[i];
5082    while (c.charAt(0) == ' ') {
5083      c = c.substring(1);
5084    }
5085    if (c.indexOf(name) == 0) {
5086      return c.substring(name.length, c.length);
5087    }
5088  }
5089  return "";
5090}
5091
5092
5093function initContentAd() {
5094  $("*").unwrap(".js-unwrap")
5095  const articleBody = $('.article__body--with-ad')
5096  if (articleBody.length) {
5097    console.log(1)
5098    console.log(articleBody.find('.js-article-ad').length)
5099    if (!articleBody.find('.js-article-ad').length) {
5100      const tags = articleBody.children()
5101      console.log(tags)
5102      const selectedTag = tags.eq(5)
5103      console.log(selectedTag)
5104      const currentLayer = articleBody.closest('.overlayer__inner')
5105      console.log(currentLayer)
5106      const ad = currentLayer.find('.js-article-ad.article-ad--hidden')
5107      console.log(ad)
5108      ad.clone().removeClass('article-ad--hidden').insertAfter(selectedTag)
5109    } else {
5110      console.log(2)
5111      articleBody.find('.js-article-ad').removeClass('article-ad--hidden')
5112    }
5113  }
5114}
5115
5116function calculateVideoHeight(){
5117  let block = $(".js-calculate-height")
5118  let video = block.find('video')
5119  video.css("height","auto")
5120  block.css('padding-bottom',video.outerHeight())
5121  $("video").on("loadeddata", function (){
5122    let block = $(".js-calculate-height")
5123    let video = block.find('video')
5124    video.css("height","auto")
5125    block.css('padding-bottom',video.outerHeight())
5126  });
5127}

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.