1 2window.mr = window.mr || {}; 3 4mr = (function (mr, $, window, document){ 5 "use strict"; 6 7 mr = mr || {}; 8 9 var components = {documentReady: [],documentReadyDeferred: [], windowLoad: [], windowLoadDeferred: []}; 10 11 mr.status = {documentReadyRan: false, windowLoadPending: false}; 12 13 $(document).ready(documentReady); 14 $(window).on("load", windowLoad); 15 16 function documentReady(context){ 17 18 context = typeof context === typeof undefined ? $ : context; 19 components.documentReady.concat(components.documentReadyDeferred).forEach(function(component){ 20 component(context); 21 }); 22 mr.status.documentReadyRan = true; 23 if(mr.status.windowLoadPending){ 24 windowLoad(mr.setContext()); 25 } 26 } 27 28 function windowLoad(context){ 29 if(mr.status.documentReadyRan){ 30 mr.status.windowLoadPending = false; 31 context = typeof context === "object" ? $ : context; 32 components.windowLoad.concat(components.windowLoadDeferred).forEach(function(component){ 33 component(context); 34 }); 35 }else{ 36 mr.status.windowLoadPending = true; 37 } 38 } 39 40 mr.setContext = function (contextSelector){ 41 var context = $; 42 if(typeof contextSelector !== typeof undefined){ 43 return function(selector){ 44 return $(contextSelector).find(selector); 45 }; 46 } 47 return context; 48 }; 49 50 mr.components = components; 51 mr.documentReady = documentReady; 52 mr.windowLoad = windowLoad; 53 54 return mr; 55}(window.mr, jQuery, window, document)); 56 57 58//////////////// Utility Functions 59mr = (function (mr, $, window, document){ 60 "use strict"; 61 mr.util = {}; 62 63 mr.util.requestAnimationFrame = window.requestAnimationFrame || 64 window.mozRequestAnimationFrame || 65 window.webkitRequestAnimationFrame || 66 window.msRequestAnimationFrame; 67 68 mr.util.documentReady = function($){ 69 var today = new Date(); 70 var year = today.getFullYear(); 71 $('.update-year').text(year); 72 }; 73 74 mr.util.windowLoad = function($){ 75 $('[data-delay-src]').each(function(){ 76 var $el = $(this); 77 $el.attr('src', $el.attr('data-delay-src')); 78 $el.removeAttr('data-delay-src'); 79 }); 80 }; 81 82 mr.util.getURLParameter = function(name) { 83 return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [undefined, ""])[1].replace(/\+/g, '%20')) || null; 84 }; 85 86 87 mr.util.capitaliseFirstLetter = function(string) { 88 return string.charAt(0).toUpperCase() + string.slice(1); 89 }; 90 91 mr.util.slugify = function(text, spacesOnly){ 92 if(typeof spacesOnly !== typeof undefined){ 93 return text.replace(/ +/g, ''); 94 }else{ 95 return text 96 .toLowerCase() 97 .replace(/[\~\!\@\#\$\%\^\&\*\(\)\-\_\=\+\]\[\}\{\'\"\;\\\:\?\/\>\<\.\,]+/g, '') 98 .replace(/ +/g, '-'); 99 } 100 }; 101 102 mr.util.sortChildrenByText = function(parentElement, reverse){ 103 var $parentElement = $(parentElement); 104 var items = $parentElement.children().get(); 105 var order = -1; 106 var order2 = 1; 107 if(typeof reverse !== typeof undefined){order = 1; order2 = -1;} 108 109 items.sort(function(a,b){ 110 var keyA = $(a).text(); 111 var keyB = $(b).text(); 112 113 if (keyA < keyB) return order; 114 if (keyA > keyB) return order2; 115 return 0; 116 }); 117 118 // Append back into place 119 $parentElement.empty(); 120 $(items).each(function(i, itm){ 121 $parentElement.append(itm); 122 }); 123 }; 124 125 // Set data-src attribute of element from src to be restored later 126 mr.util.idleSrc = function(context, selector){ 127 128 selector = (typeof selector !== typeof undefined) ? selector : '';
129 var elems = context.is(selector+'[src]') ? context : context.find(selector+'[src]'); 130 131 elems.each(function(index, elem){ 132 elem = $(elem); 133 var currentSrc = elem.attr('src'), 134 dataSrc = elem.attr('data-src'); 135 136 // If there is no data-src, save current source to it 137 if(typeof dataSrc === typeof undefined){ 138 elem.attr('data-src', currentSrc); 139 } 140 141 // Clear the src attribute 142 elem.attr('src', ''); 143 144 }); 145 }; 146 147 // Set src attribute of element from its data-src where it was temporarily stored earlier 148 mr.util.activateIdleSrc = function(context, selector){ 149 150 selector = (typeof selector !== typeof undefined) ? selector : ''; 151 var elems = context.is(selector+'[data-src]') ? context : context.find(selector+'[data-src]'); 152 153 elems.each(function(index, elem){ 154 elem = $(elem); 155 var dataSrc = elem.attr('data-src'); 156 157 // Write the 'src' attribute using the 'data-src' value 158 elem.attr('src', dataSrc); 159 }); 160 }; 161 162 mr.util.pauseVideo = function(context){ 163 var elems = context.is('video') ? context : context.find('video'); 164 165 elems.each(function(index, video){ 166 var playingVideo = $(video).get(0); 167 playingVideo.pause(); 168 }); 169 }; 170 171 // Take a text value in either px (eg. 150px) or vh (eg. 65vh) and return a number in pixels. 172 mr.util.parsePixels = function(text){ 173 var windowHeight = $(window).height(), value; 174 175 // Text text against regular expression for px value. 176 if(/^[1-9]{1}[0-9]*[p][x]$/.test(text)){ 177 return parseInt(text.replace('px', ''),10); 178 } 179 // Otherwise it is vh value. 180 else if(/^[1-9]{1}[0-9]*[v][h]$/.test(text)){ 181 value = parseInt(text.replace('vh', ''),10); 182 // Return conversion to percentage of window height. 183 return windowHeight * (value/100); 184 }else{ 185 // If it is not proper text, return -1 to indicate bad value. 186 return -1; 187 } 188 }; 189 190 mr.util.removeHash = function() { 191 // Removes hash from URL bar without reloading and without losing search query 192 history.pushState("", document.title, window.location.pathname + window.location.search); 193 } 194 195 mr.components.documentReady.push(mr.util.documentReady); 196 mr.components.windowLoad.push(mr.util.windowLoad); 197 return mr; 198 199}(mr, jQuery, window, document)); 200 201//////////////// Window Functions 202mr = (function (mr, $, window, document){ 203 "use strict"; 204 205 mr.window = {}; 206 mr.window.height = $(window).height(); 207 mr.window.width = $(window).width(); 208 209 $(window).on('resize',function(){ 210 mr.window.height = $(window).height(); 211 mr.window.width = $(window).width(); 212 }); 213 214 return mr; 215}(mr, jQuery, window, document)); 216 217 218//////////////// Scroll Functions 219mr = (function (mr, $, window, document){ 220 "use strict"; 221 222 223 mr.scroll = {}; 224 var raf = window.requestAnimationFrame || 225 window.mozRequestAnimationFrame || 226 window.webkitRequestAnimationFrame || 227 window.msRequestAnimationFrame; 228 mr.scroll.listeners = []; 229 mr.scroll.busy = false; 230 mr.scroll.y = 0; 231 mr.scroll.x = 0; 232 233 var documentReady = function($){ 234
235 //////////////// Capture Scroll Event and fire scroll function 236 jQuery(window).off('scroll.mr'); 237 jQuery(window).on('scroll.mr', function(evt) { 238 if(mr.scroll.busy === false){ 239 240 mr.scroll.busy = true; 241 raf(function(evt){ 242 mr.scroll.update(evt); 243 }); 244 245 } 246 if(evt.stopPropagation){ 247 evt.stopPropagation(); 248 } 249 }); 250 251 }; 252 253 mr.scroll.update = function(event){ 254 255 // Loop through all mr scroll listeners 256 var parallax = typeof window.mr_parallax !== typeof undefined ? true : false; 257 mr.scroll.y = (parallax ? mr_parallax.mr_getScrollPosition() : window.pageYOffset); 258 mr.scroll.busy = false; 259 if(parallax){ 260 mr_parallax.mr_parallaxBackground(); 261 } 262 263 264 if(mr.scroll.listeners.length > 0){ 265 for (var i = 0, l = mr.scroll.listeners.length; i < l; i++) { 266 mr.scroll.listeners[i](event); 267 } 268 } 269 270 }; 271 272 mr.scroll.documentReady = documentReady; 273 274 mr.components.documentReady.push(documentReady); 275 276 return mr; 277 278}(mr, jQuery, window, document)); 279 280 281//////////////// Scroll Class Modifier 282mr = (function (mr, $, window, document){ 283 "use strict"; 284 285 mr.scroll.classModifiers = {}; 286 // Globally accessible list of elements/rules 287 mr.scroll.classModifiers.rules = []; 288 289 mr.scroll.classModifiers.parseScrollRules = function(element){ 290 var text = element.attr('data-scroll-class'), 291 rules = text.split(";"); 292
293 rules.forEach(function(rule){ 294 var ruleComponents, scrollPoint, ruleObject = {}; 295 ruleComponents = rule.replace(/\s/g, "").split(':'); 296 if(ruleComponents.length === 2){ 297 scrollPoint = mr.util.parsePixels(ruleComponents[0]); 298 if(scrollPoint > -1){ 299 ruleObject.scrollPoint = scrollPoint; 300 if(ruleComponents[1].length){ 301 var toggleClass = ruleComponents[1]; 302 ruleObject.toggleClass = toggleClass; 303 // Set variable in object to indicate that element already has class applied 304 ruleObject.hasClass = element.hasClass(toggleClass); 305 ruleObject.element = element.get(0); 306 mr.scroll.classModifiers.rules.push(ruleObject); 307 }else{ 308 // Error: toggleClass component does not exist. 309 //console.log('Error - toggle class not found.'); 310 return false; 311 } 312 }else{ 313 // Error: scrollpoint component was malformed 314 //console.log('Error - Scrollpoint not found.'); 315 return false; 316 } 317 } 318 }); 319 320 if(mr.scroll.classModifiers.rules.length){ 321 return true; 322 }else{ 323 return false; 324 } 325 }; 326 327 mr.scroll.classModifiers.update = function(event){ 328 var currentScroll = mr.scroll.y, 329 scrollRules = mr.scroll.classModifiers.rules, 330 l = scrollRules.length, 331 currentRule; 332 333 // Given the current scrollPoint, check for necessary changes 334 while(l--) { 335 336 currentRule = scrollRules[l]; 337 338 if(currentScroll > currentRule.scrollPoint && !currentRule.hasClass){ 339 // Set local copy and glogal copy at the same time; 340 currentRule.element.classList.add(currentRule.toggleClass); 341 currentRule.hasClass = mr.scroll.classModifiers.rules[l].hasClass = true; 342 } 343 if(currentScroll < currentRule.scrollPoint && currentRule.hasClass){ 344 // Set local copy and glogal copy at the same time; 345 currentRule.element.classList.remove(currentRule.toggleClass); 346 currentRule.hasClass = mr.scroll.classModifiers.rules[l].hasClass = false; 347 } 348 } 349 }; 350 351 var fixedElementSizes = function(){ 352 $('.main-container [data-scroll-class*="pos-fixed"]').each(function(){ 353 var element = $(this); 354 element.css('max-width',element.parent().outerWidth()); 355 element.parent().css('min-height',element.outerHeight()); 356 }); 357 }; 358 359 var documentReady = function($){ 360 // Collect info on all elements that require class modification at load time 361 // Each element has data-scroll-class with a formatted value to represent class to add/remove at a particular scroll point. 362 $('[data-scroll-class]').each(function(){ 363 var element = $(this); 364 365 // Test the rules to be added to an array of rules. 366 if(!mr.scroll.classModifiers.parseScrollRules(element)){ 367 console.log('Error parsing scroll rules on: '+element); 368 } 369 }); 370 371 // For 'position fixed' elements, give them a max-width for correct fixing behaviour 372 fixedElementSizes(); 373 $(window).on('resize', fixedElementSizes); 374 375 // If there are valid scroll rules add classModifiers update function to the scroll event processing queue. 376 if(mr.scroll.classModifiers.rules.length){ 377 mr.scroll.listeners.push(mr.scroll.classModifiers.update); 378 } 379 }; 380 381 mr.components.documentReady.push(documentReady); 382 mr.scroll.classModifiers.documentReady = documentReady; 383 384 385 386 return mr; 387 388}(mr, jQuery, window, document)); 389 390 391//////////////// Accordions 392mr = (function (mr, $, window, document){ 393 "use strict"; 394 395 mr.accordions = mr.accordions || {}; 396 397 mr.accordions.documentReady = function($){ 398 $('.accordion__title').on('click', function(){ 399 mr.accordions.activatePanel($(this)); 400 }); 401 402 $('.accordion').each(function(){ 403 var accordion = $(this); 404 var minHeight = accordion.outerHeight(true); 405 accordion.css('min-height',minHeight); 406 }); 407 408 if(window.location.hash !== '' && window.location.hash !== '#' && window.location.hash.match(/#\/.*/) === null){ 409 if($('.accordion > li > .accordion__title'+window.location.hash).length){ 410 mr.accordions.activatePanelById(window.location.hash, true); 411 } 412 } 413 414 jQuery(document).on('click', 'a[href^="#"]:not(a[href="#"])', function(){ 415 416 if($('.accordion > li > .accordion__title'+$(this).attr('href')).length){ 417 mr.accordions.activatePanelById($(this).attr('href'), true); 418 } 419 }); 420 }; 421 422 423 424 mr.accordions.activatePanel = function(panel, forceOpen){ 425 426 var $panel = $(panel), 427 accordion = $panel.closest('.accordion'), 428 li = $panel.closest('li'), 429 openEvent = document.createEvent('Event'), 430 closeEvent = document.createEvent('Event'); 431 432 openEvent.initEvent('panelOpened.accordions.mr', true, true); 433 closeEvent.initEvent('panelClosed.accordions.mr', true, true); 434 435 436 437 if(li.hasClass('active')){ 438 439 if(forceOpen !== true){ 440 441 li.removeClass('active'); 442 $panel.trigger('panelClosed.accordions.mr').get(0).dispatchEvent(closeEvent); 443 } 444 }else{ 445 446 if(accordion.hasClass('accordion--oneopen')){ 447 448 var wasActive = accordion.find('li.active'); 449 if(wasActive.length){ 450 wasActive.removeClass('active'); 451 wasActive.trigger('panelClosed.accordions.mr').get(0).dispatchEvent(closeEvent); 452 } 453 li.addClass('active'); 454 li.trigger('panelOpened.accordions.mr').get(0).dispatchEvent(openEvent); 455 456 }else{ 457 458 if(!li.is('.active')){ 459 li.trigger('panelOpened.accordions.mr').get(0).dispatchEvent(openEvent); 460 } 461 li.addClass('active'); 462 } 463 } 464 }; 465 466 mr.accordions.activatePanelById = function(id, forceOpen){ 467 var panel; 468 469 if(id !== '' && id !== '#' && id.match(/#\/.*/) === null){ 470 panel = $('.accordion > li > .accordion__title#'+id.replace('#', '')); 471 if(panel.length){ 472 $('html, body').stop(true).animate({ 473 scrollTop: (panel.offset().top - 50) 474 }, 1200); 475 476 mr.accordions.activatePanel(panel, forceOpen); 477 } 478 } 479 }; 480 481 mr.components.documentReady.push(mr.accordions.documentReady); 482 return mr; 483 484}(mr, jQuery, window, document)); 485 486 487//////////////// Alerts 488mr = (function (mr, $, window, document){ 489 "use strict"; 490 491 mr.alerts = mr.alerts || {}; 492 493 mr.alerts.documentReady = function($){ 494 $('.alert__close').on('click touchstart', function(){ 495 jQuery(this).closest('.alert').addClass('alert--dismissed'); 496 }); 497 }; 498 499 mr.components.documentReady.push(mr.alerts.documentReady); 500 return mr; 501 502}(mr, jQuery, window, document)); 503 504
505//////////////// Backgrounds 506mr = (function (mr, $, window, document){ 507 "use strict"; 508 509 mr.backgrounds = mr.backgrounds || {}; 510 511 mr.backgrounds.documentReady = function($){ 512 513 //////////////// Append .background-image-holder <img>'s as CSS backgrounds 514 515 $('.background-image-holder').each(function() { 516 var imgSrc = $(this).children('img').attr('src'); 517 $(this).css('background', 'url("' + imgSrc + '")').css('background-position', 'initial').css('opacity','1'); 518 }); 519 }; 520 521 mr.components.documentReady.push(mr.backgrounds.documentReady); 522 return mr; 523 524}(mr, jQuery, window, document)); 525 526//////////////// Bars 527mr = (function (mr, $, window, document){ 528 "use strict"; 529 530 mr.bars = mr.bars || {}; 531 532 mr.bars.documentReady = function($){ 533 $('.nav-container .bar[data-scroll-class*="fixed"]:not(.bar--absolute)').each(function(){ 534 var bar = $(this), 535 barHeight = bar.outerHeight(true); 536 bar.closest('.nav-container').css('min-height',barHeight); 537 }); 538 }; 539 540 mr.components.documentReady.push(mr.bars.documentReady); 541 return mr; 542 543}(mr, jQuery, window, document)); 544 545//////////////// Cookies 546mr = (function (mr, $, window, document){ 547 "use strict"; 548 549 mr.cookies = { 550 551 getItem: function (sKey) { 552 if (!sKey) { return null; } 553 return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null; 554 }, 555 setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) { 556 if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; } 557 var sExpires = ""; 558 if (vEnd) { 559 switch (vEnd.constructor) { 560 case Number: 561 sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd; 562 break; 563 case String: 564 sExpires = "; expires=" + vEnd; 565 break; 566 case Date: 567 sExpires = "; expires=" + vEnd.toUTCString(); 568 break; 569 } 570 } 571 document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : ""); 572 return true; 573 }, 574 removeItem: function (sKey, sPath, sDomain) { 575 if (!this.hasItem(sKey)) { return false; } 576 document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : ""); 577 return true; 578 }, 579 hasItem: function (sKey) { 580 if (!sKey) { return false; } 581 return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); 582 }, 583 keys: function () { 584 var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/); 585 for (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); } 586 return aKeys; 587 } 588 }; 589 590 return mr; 591 592}(mr, jQuery, window, document)); 593 594//////////////// Countdown 595mr = (function (mr, $, window, document){ 596 "use strict"; 597 598 mr.countdown = mr.countdown || {}; 599 mr.countdown.options = mr.countdown.options || {}; 600 601 mr.countdown.documentReady = function($){ 602 603 $('.countdown[data-date]').each(function(){ 604 var element = $(this), 605 date = element.attr('data-date'), 606 daysText = typeof element.attr('data-days-text') !== typeof undefined ? '%D '+element.attr('data-days-text')+' %H:%M:%S': '%D days %H:%M:%S', 607 daysText = typeof mr.countdown.options.format !== typeof undefined ? mr.countdown.options.format : daysText, 608 dateFormat = typeof element.attr('data-date-format') !== typeof undefined ? element.attr('data-date-format'): daysText, 609 610 fallback; 611 612 if(typeof element.attr('data-date-fallback') !== typeof undefined){ 613 fallback = element.attr('data-date-fallback') || "Timer Done"; 614 } 615 616 element.countdown(date, function(event) { 617 if(event.elapsed){ 618 element.text(fallback); 619 }else{ 620 element.text( 621 event.strftime(dateFormat) 622 ); 623 } 624 }); 625 }); 626 627 }; 628 629 mr.components.documentReadyDeferred.push(mr.countdown.documentReady); 630 return mr; 631 632}(mr, jQuery, window, document)); 633
634//////////////// Datepicker 635mr = (function (mr, $, window, document){ 636 "use strict"; 637 638 mr.datepicker = mr.datepicker || {}; 639 640 var options = mr.datepicker.options || {}; 641 642 mr.datepicker.documentReady = function($){ 643 if($('.datepicker').length){ 644 $('.datepicker').pickadate(options); 645 } 646 }; 647 648 mr.components.documentReadyDeferred.push(mr.datepicker.documentReady); 649 return mr; 650 651}(mr, jQuery, window, document)); 652 653//////////////// Dropdowns 654mr = (function (mr, $, window, document){ 655 "use strict"; 656 657 mr.dropdowns = mr.dropdowns || {}; 658 659 mr.dropdowns.done = false; 660 661 mr.dropdowns.documentReady = function($){ 662 663 var rtl = false; 664 665 if($('html[dir="rtl"]').length){ 666 rtl = true; 667 } 668 669 if(!mr.dropdowns.done){ 670 jQuery(document).on('click','body:not(.dropdowns--hover) .dropdown, body.dropdowns--hover .dropdown.dropdown--click',function(event){ 671 var dropdown = jQuery(this); 672 if(jQuery(event.target).is('.dropdown--active > .dropdown__trigger')){ 673 dropdown.siblings().removeClass('dropdown--active').find('.dropdown').removeClass('dropdown--active'); 674 dropdown.toggleClass('dropdown--active'); 675 }else{ 676 $('.dropdown--active').removeClass('dropdown--active'); 677 dropdown.addClass('dropdown--active'); 678 } 679 }); 680 jQuery(document).on('click touchstart', 'body:not(.dropdowns--hover)', function(event){ 681 if(!jQuery(event.target).is('[class*="dropdown"], [class*="dropdown"] *')){ 682 $('.dropdown--active').removeClass('dropdown--active'); 683 } 684 }); 685 jQuery('body.dropdowns--hover .dropdown').on('click', function(event){ 686 event.stopPropagation(); 687 var hoverDropdown = jQuery(this); 688 hoverDropdown.toggleClass('dropdown--active'); 689 }); 690 691 // Append a container to the body for measuring purposes 692 jQuery('body').append('<div class="container containerMeasure" style="opacity:0;pointer-events:none;"></div>'); 693 694 695 696 697 // Menu dropdown positioning 698 if(rtl === false){ 699 mr.dropdowns.repositionDropdowns($); 700 jQuery(window).on('resize', function(){mr.dropdowns.repositionDropdowns($);}); 701 }else{ 702 mr.dropdowns.repositionDropdownsRtl($); 703 jQuery(window).on('resize', function(){mr.dropdowns.repositionDropdownsRtl($);}); 704 } 705 706 mr.dropdowns.done = true; 707 } 708 }; 709 710 mr.dropdowns.repositionDropdowns = function($){ 711 $('.dropdown__container').each(function(){ 712 var container, containerOffset, masterOffset, menuItem, content; 713 714 jQuery(this).css('left', ''); 715 716 container = jQuery(this); 717 containerOffset = container.offset().left; 718 masterOffset = jQuery('.containerMeasure').offset().left; 719 menuItem = container.closest('.dropdown').offset().left; 720 content = null; 721 722 container.css('left',((-containerOffset)+(masterOffset))); 723 724 if(container.find('.dropdown__content:not([class*="lg-12"])').length){ 725 content = container.find('.dropdown__content'); 726 content.css('left', ((menuItem)-(masterOffset))); 727 } 728 729 }); 730 $('.dropdown__content').each(function(){ 731 var dropdown, offset, width, offsetRight, winWidth, leftCorrect; 732 733 dropdown = jQuery(this); 734 offset = dropdown.offset().left; 735 width = dropdown.outerWidth(true); 736 offsetRight = offset + width; 737 winWidth = jQuery(window).outerWidth(true); 738 leftCorrect = jQuery('.containerMeasure').outerWidth() - width; 739 740 if(offsetRight > winWidth){ 741 dropdown.css('left', leftCorrect); 742 } 743 744 }); 745 }; 746 747 mr.dropdowns.repositionDropdownsRtl = function($){ 748 749 var windowWidth = jQuery(window).width(); 750 751 $('.dropdown__container').each(function(){ 752 var container, containerOffset, masterOffset, menuItem, content; 753 754 jQuery(this).css('left', ''); 755 756 container = jQuery(this); 757 containerOffset = windowWidth - (container.offset().left + container.outerWidth(true)); 758 masterOffset = jQuery('.containerMeasure').offset().left; 759 menuItem = windowWidth - (container.closest('.dropdown').offset().left + container.closest('.dropdown').outerWidth(true)); 760 content = null; 761 762 container.css('right',((-containerOffset)+(masterOffset))); 763 764 if(container.find('.dropdown__content:not([class*="lg-12"])').length){ 765 content = container.find('.dropdown__content'); 766 content.css('right', ((menuItem)-(masterOffset))); 767 } 768 }); 769 $('.dropdown__content').each(function(){ 770 var dropdown, offset, width, offsetRight, winWidth, rightCorrect; 771 772 dropdown = jQuery(this); 773 offset = windowWidth - (dropdown.offset().left + dropdown.outerWidth(true)); 774 width = dropdown.outerWidth(true); 775 offsetRight = offset + width; 776 winWidth = jQuery(window).outerWidth(true); 777 rightCorrect = jQuery('.containerMeasure').outerWidth() - width; 778 779 if(offsetRight > winWidth){ 780 dropdown.css('right', rightCorrect); 781 } 782 783 }); 784 }; 785 786 787 mr.components.documentReady.push(mr.dropdowns.documentReady); 788 return mr; 789 790}(mr, jQuery, window, document)); 791
792//////////////// Forms 793 794mr = (function (mr, $, window, document){ 795 "use strict"; 796 797 mr.forms = mr.forms || {}; 798 mr.forms.captcha = {}; 799 mr.forms.captcha.widgets = []; 800 mr.forms.captcha.done = false; 801 802 mr.forms.documentReady = function($){ 803 804 mr.forms.captcha.widgets = []; 805 806 /// Checkbox & Radio Inputs 807 808 $('.input-checkbox input[type="checkbox"], .input-radio input[type="radio"]').each(function(index){ 809 var input = $(this), 810 label = input.siblings('label'), 811 id = "input-assigned-"+index; 812 if(typeof input.attr('id') === typeof undefined || input.attr('id') === ""){ 813 input.attr('id',id); 814 label.attr('for',id); 815 }else{ 816 id = input.attr('id'); 817 label.attr('for',id); 818 } 819 }); 820 821 //////////////// Number Inputs 822 823 $('.input-number__controls > span').off('click.mr').on('click.mr',function(){ 824 var control = jQuery(this), 825 parent = control.closest('.input-number'), 826 input = parent.find('input[type="number"]'), 827 max = input.attr('max'), 828 min = input.attr('min'), 829 step = 1, 830 current = parseInt(input.val(),10); 831 832 if(parent.is('[data-step]')){ 833 step = parseInt(parent.attr('data-step'),10); 834 } 835 836 if(control.hasClass('input-number__increase')){ 837 if((current+step) <= max){ 838 input.val(current+step); 839 } 840 }else{ 841 if((current-step) >= min){ 842 input.val(current-step); 843 } 844 } 845 }); 846 847
848 //////////////// File Uploads 849 850 $('.input-file .btn').off('click.mr').on('click.mr',function(){ 851 $(this).siblings('input').trigger('click'); 852 return false; 853 }); 854 855 //////////////// Handle Form Submit 856 857 $('form.form-email, form[action*="list-manage.com"], form[action*="createsend.com"]').attr('novalidate', true).off('submit').on('submit', mr.forms.submit); 858 859 //////////////// Handle Form Submit 860 $(document).on('change, input, paste, keyup', '.attempted-submit .field-error', function(){ 861 $(this).removeClass('field-error'); 862 }); 863 864 //////////////// Check forms for Google reCaptcha site keys 865 866 $('form[data-recaptcha-sitekey]:not([data-recaptcha-sitekey=""])').each(function(){ 867 var $thisForm = jQuery(this), 868 $captchaDiv = $thisForm.find('div.recaptcha'), 869 $insertBefore, $column, widgetObject, $script, scriptSrc, widgetColourTheme, widgetSize; 870 871 widgetColourTheme = $thisForm.attr('data-recaptcha-theme'); 872 widgetColourTheme = typeof widgetColourTheme !== typeof undefined ? widgetColourTheme : ''; 873 874 widgetSize = $thisForm.attr('data-recaptcha-size'); 875 widgetSize = typeof widgetSize !== typeof undefined ? widgetSize : ''; 876 877 // Store the site key for later use 878 mr.forms.captcha.sitekey = $thisForm.attr('data-recaptcha-sitekey'); 879 880 if($captchaDiv.length){ 881 // If a div.recaptcha was already present on this form, do nothing at this stage, 882 // It will be populated with a captcha widget later. 883 }else{ 884 // Create a captcha div and insert it before the submit button. 885 $insertBefore = $thisForm.find('button[type=submit]').closest('[class*="col-"]'); 886 $captchaDiv = jQuery('<div>').addClass('recaptcha'); 887 $column = jQuery('<div>').addClass('col-12').append($captchaDiv); 888 $column.insertBefore($insertBefore); 889 } 890 891 892 // Add the widget div to the widgets array 893 widgetObject = { 894 element: $captchaDiv.get(0), 895 parentForm: $thisForm, 896 theme: widgetColourTheme, 897 size: widgetSize, 898 }; 899 900 901 902 mr.forms.captcha.widgets.push(widgetObject); 903 904 // mr.forms.captcha.done indicates whether the api script has been appended yet. 905 if(mr.forms.captcha.done === false){ 906 if(!jQuery('script[src*="recaptcha/api.js"]').length){ 907 $script = jQuery('<script async defer>'); 908 scriptSrc = 'https://www.google.com/recaptcha/api.js?onload=mrFormsCaptchaInit&render=explicit'; 909 $script.attr('src', scriptSrc); 910 jQuery('body').append($script); 911 mr.forms.captcha.done = true; 912 } 913 }else{ 914 if(typeof grecaptcha !== typeof undefined){ 915 mr.forms.captcha.renderWidgets(); 916 } 917 } 918 919 }); 920 921 922 }; 923 924 mr.forms.submit = function(e){ 925 // return false so form submits through jQuery rather than reloading page. 926 if (e.preventDefault) e.preventDefault(); 927 else e.returnValue = false; 928 929 var body = $('body'), 930 thisForm = $(e.target).closest('form'), 931 formAction = typeof thisForm.attr('action') !== typeof undefined ? thisForm.attr('action') : "", 932 submitButton = thisForm.find('button[type="submit"], input[type="submit"]'), 933 error = 0, 934 originalError = thisForm.attr('original-error'), 935 captchaUsed = thisForm.find('div.recaptcha').length ? true:false, 936 successRedirect, formError, formSuccess, errorText, successText; 937 938 body.find('.form-error, .form-success').remove(); 939 submitButton.attr('data-text', submitButton.text()); 940 errorText = thisForm.attr('data-error') ? thisForm.attr('data-error') : "Please fill all fields correctly"; 941 successText = thisForm.attr('data-success') ? thisForm.attr('data-success') : "Thanks, we'll be in touch shortly"; 942 body.append('<div class="form-error" style="display: none;">' + errorText + '</div>'); 943 body.append('<div class="form-success" style="display: none;">
943' + successText + '</div>'); 944 formError = body.find('.form-error'); 945 formSuccess = body.find('.form-success'); 946 thisForm.addClass('attempted-submit'); 947 948 // Do this if the form is intended to be submitted to MailChimp or Campaign Monitor 949 if (formAction.indexOf('createsend.com') !== -1 || formAction.indexOf('list-manage.com') !== -1 ) { 950 951 console.log('Mail list form signup detected.'); 952 if (typeof originalError !== typeof undefined && originalError !== false) { 953 formError.html(originalError); 954 } 955 956 // validateFields returns 1 on error; 957 if (mr.forms.validateFields(thisForm) !== 1) { 958 959 thisForm.removeClass('attempted-submit'); 960 961 // Hide the error if one was shown 962 formError.fadeOut(200); 963 // Create a new loading spinner in the submit button. 964 submitButton.addClass('btn--loading'); 965 966 try{ 967 $.ajax({
968 url: thisForm.attr('action'), 969 crossDomain: true, 970 data: thisForm.serialize(), 971 method: "GET", 972 cache: false, 973 dataType: 'json', 974 contentType: 'application/json; charset=utf-8', 975 success: function(data){ 976 // Request was a success, what was the response? 977 978 if (data.result !== "success" && data.Status !== 200) { 979 980 // Got an error from Mail Chimp or Campaign Monitor 981 982 // Keep the current error text in a data attribute on the form 983 formError.attr('original-error', formError.text()); 984 // Show the error with the returned error text. 985 formError.html(data.msg).stop(true).fadeIn(1000); 986 formSuccess.stop(true).fadeOut(1000); 987 988 submitButton.removeClass('btn--loading'); 989 } else { 990 991 // Got success from Mail Chimp or Campaign Monitor 992 993 submitButton.removeClass('btn--loading'); 994 995 successRedirect = thisForm.attr('data-success-redirect'); 996 // For some browsers, if empty `successRedirect` is undefined; for others, 997 // `successRedirect` is false. Check for both. 998 if (typeof successRedirect !== typeof undefined && successRedirect !== false && successRedirect !== "") { 999 window.location = successRedirect; 1000 }else{ 1001 mr.forms.resetForm(thisForm); 1002 mr.forms.showFormSuccess(formSuccess, formError, 1000, 5000, 500); 1003 } 1004 } 1005 } 1006 }); 1007 }catch(err){ 1008 // Keep the current error text in a data attribute on the form 1009 formError.attr('original-error', formError.text()); 1010 // Show the error with the returned error text. 1011 formError.html(err.message); 1012 mr.forms.showFormError(formSuccess, formError, 1000, 5000, 500); 1013 1014 submitButton.removeClass('btn--loading'); 1015 } 1016 1017 1018 1019 } else { 1020 // There was a validation error - show the default form error message 1021 mr.forms.showFormError(formSuccess, formError, 1000, 5000, 500); 1022 } 1023 } else { 1024 // If no MailChimp or Campaign Monitor form was detected then this is treated as an email form instead. 1025 if (typeof originalError !== typeof undefined && originalError !== false) { 1026 formError.text(originalError); 1027 } 1028 1029 error = mr.forms.validateFields(thisForm); 1030 1031 if (error === 1) { 1032 mr.forms.showFormError(formSuccess, formError, 1000, 5000, 500); 1033 } else { 1034 1035 thisForm.removeClass('attempted-submit'); 1036 1037 // Hide the error if one was shown 1038 formError.fadeOut(200); 1039 1040 // Create a new loading spinner in the submit button. 1041 submitButton.addClass('btn--loading'); 1042 1043 jQuery.ajax({ 1044 type: "POST", 1045 url: (formAction !== "" ? formAction : "mail/mail.php"), 1046 data: thisForm.serialize()+"&url="+window.location.href+"&captcha="+captchaUsed, 1047 success: function(response) { 1048 // Swiftmailer always sends back a number representing number of emails sent. 1049 // If this is numeric (not Swift Mailer error text) AND greater than 0 then show success message. 1050 1051 submitButton.removeClass('btn--loading'); 1052 1053 if ($.isNumeric(response)) { 1054 if (parseInt(response,10) > 0) { 1055 // For some browsers, if empty 'successRedirect' is undefined; for others, 1056 // 'successRedirect' is false. Check for both. 1057 successRedirect = thisForm.attr('data-success-redirect'); 1058 if (typeof successRedirect !== typeof undefined && successRedirect !== false && successRedirect !== "") { 1059 window.location = successRedirect; 1060 } 1061 1062 mr.forms.resetForm(thisForm); 1063 mr.forms.showFormSuccess(formSuccess, formError, 1000, 5000, 500); 1064 mr.forms.captcha.resetWidgets(); 1065 } 1066 } 1067 // If error text was returned, put the text in the .form-error div and show it. 1068 else { 1069 // Keep the current error text in a data attribute on the form 1070 formError.attr('original-error', formError.text()); 1071 // Show the error with the returned error text. 1072 formError.text(response).stop(true).fadeIn(1000); 1073 formSuccess.stop(true).fadeOut(1000); 1074 } 1075 }, 1076 error: function(errorObject, errorText, errorHTTP) { 1077 // Keep the current error text in a data attribute on the form 1078 formError.attr('original-error', formError.text()); 1079 // Show the error with the returned error text. 1080 formError.text(errorHTTP).stop(true).fadeIn(1000); 1081 formSuccess.stop(true).fadeOut(1000); 1082 submitButton.removeClass('btn--loading'); 1083 } 1084 }); 1085 } 1086 } 1087 return false; 1088 }; 1089 1090 mr.forms.validateFields = function(form) { 1091 var body = $(body), 1092 error = false, 1093 originalErrorMessage, 1094 name, 1095 thisElement; 1096 1097 form = $(form); 1098 1099 1100 1101 1102 form.find('.validate-required[type="checkbox"]').each(function() { 1103 var checkbox = $(this); 1104 if (!$('[name="' + $(this).attr('name') + '"]:checked').length) { 1105 error = 1; 1106 name = $(this).attr('data-name') || 'check'; 1107 checkbox.parent().addClass('field-error'); 1108 //body.find('.form-error').text('Please tick at least one ' + name + ' box.'); 1109 } 1110 }); 1111 1112 form.find('.validate-required, .required, [required]').not('input[type="checkbox"]').each(function() { 1113 if ($(this).val() === '') { 1114 $(this).addClass('field-error'); 1115 error = 1; 1116 } else { 1117 $(this).removeClass('field-error'); 1118 } 1119 }); 1120 1121 form.find('.validate-email, .email, [name*="cm-"][type="email"]').each(function() { 1122 if (!(/(.+)@(.+){2,}\.(.+){2,}/.test($(this).val()))) { 1123 $(this).addClass('field-error'); 1124 error = 1; 1125 } else { 1126 $(this).removeClass('field-error'); 1127 } 1128 }); 1129 1130 form.find('.validate-number-dash').each(function() { 1131 if (!(/^[0-9][0-9-]+[0-9]$/.test($(this).val()))) { 1132 $(this).addClass('field-error'); 1133 error = 1; 1134 } else { 1135 $(this).removeClass('field-error'); 1136 } 1137 }); 1138 1139 // Validate recaptcha 1140 if(form.find('div.recaptcha').length && typeof form.attr('data-recaptcha-sitekey') !== typeof undefined){ 1141 thisElement = $(form.find('div.recaptcha')); 1142 1143 if(grecaptcha.getResponse(form.data('recaptchaWidgetID')) !== ""){ 1144 thisElement.removeClass('field-error'); 1145 }else{ 1146 thisElement.addClass('field-error'); 1147 error = 1; 1148 } 1149 } 1150 1151 if (!form.find('.field-error').length) { 1152 body.find('.form-error').fadeOut(1000); 1153 }else{ 1154 1155 var firstError = $(form).find('.field-error:first'); 1156 1157 if(firstError.length){ 1158 $('html, body').stop(true).animate({ 1159 scrollTop: (firstError.offset().top - 100) 1160 }, 1200, function(){firstError.focus();}); 1161 } 1162 } 1163 1164 1165 1166 return error; 1167 }; 1168 1169 mr.forms.showFormSuccess = function(formSuccess, formError, fadeOutError, wait, fadeOutSuccess){ 1170 1171 formSuccess.stop(true).fadeIn(fadeOutError); 1172 1173 formError.stop(true).fadeOut(fadeOutError); 1174 setTimeout(function() { 1175 formSuccess.stop(true).fadeOut(fadeOutSuccess); 1176 }, wait); 1177 }; 1178 1179 mr.forms.showFormError = function(formSuccess, formError, fadeOutSuccess, wait, fadeOutError){ 1180 1181 formError.stop(true).fadeIn(fadeOutSuccess); 1182 1183 formSuccess.stop(true).fadeOut(fadeOutSuccess); 1184 setTimeout(function() { 1185 formError.stop(true).fadeOut(fadeOutError); 1186 }, wait); 1187 }; 1188 1189 // Reset form to empty/default state. 1190 mr.forms.resetForm = function(form){ 1191 form = $(form); 1192 form.get(0).reset(); 1193 form.find('.input-radio, .input-checkbox').removeClass('checked'); 1194 form.find('[data-default-value]').filter('[type="text"],[type="number"],[type="email"],[type="url"],[type="search"],[type="tel"]').each(function(){ 1195 var elem = jQuery(this); 1196 elem.val(elem.attr('data-default-value')); 1197 }); 1198 1199 }; 1200 1201 // Defined on the window scope as the recaptcha js api seems not to be able to call function in mr scope 1202 window.mrFormsCaptchaInit = function(){ 1203 mr.forms.captcha.renderWidgets(); 1204 }; 1205 1206 mr.forms.captcha.renderWidgets = function(){
1207 mr.forms.captcha.widgets.forEach(function(widget){ 1208 if(widget.element.innerHTML.replace(/[\s\xA0]+/g,'') === ''){ 1209 widget.id = grecaptcha.render(widget.element, { 1210 'sitekey' : mr.forms.captcha.sitekey, 1211 'theme' : widget.theme, 1212 'size' : widget.size, 1213 'callback' : mr.forms.captcha.setHuman 1214 }); 1215 widget.parentForm.data('recaptchaWidgetID', widget.id); 1216 } 1217 }); 1218 }; 1219 1220 mr.forms.captcha.resetWidgets = function(){ 1221 mr.forms.captcha.widgets.forEach(function(widget){ 1222 grecaptcha.reset(widget.id); 1223 }); 1224 }; 1225 1226 mr.forms.captcha.setHuman = function(){ 1227 jQuery('div.recaptcha.field-error').removeClass('field-error'); 1228 }; 1229 1230 mr.components.documentReadyDeferred.push(mr.forms.documentReady); 1231 return mr; 1232 1233}(mr, jQuery, window, document)); 1234 1235//////////////// Granim 1236mr = (function (mr, $, window, document){ 1237 "use strict"; 1238 1239 mr.granim = mr.granim || {}; 1240 1241 mr.granim.documentReady = function($){ 1242 $('[data-gradient-bg]').each(function(index,element){ 1243 var granimParent = $(this), 1244 granimID = 'granim-'+index+'', 1245 colours = granimParent.attr('data-gradient-bg'), 1246 pairs = [], 1247 tempPair = [], 1248 ao = {}, 1249 count, 1250 passes, 1251 i, 1252 themeDefaults, 1253 1254 options; 1255 1256 // Canvas element forms the gradient background 1257 granimParent.prepend('<canvas id="'+granimID+'"></canvas>'); 1258 1259 // Regular expression to match comma separated list of hex colour values 1260 passes = /^(#[0-9|a-f|A-F]{6}){1}([ ]*,[ ]*#[0-9|a-f|A-F]{6})*$/.test(colours); 1261 1262 if(passes === true){ 1263 colours = colours.replace(' ',''); 1264 colours = colours.split(','); 1265 count = colours.length; 1266 // If number of colours is odd - duplicate last colour to make even array 1267 if(count%2 !== 0){ 1268 colours.push(colours[count-1]); 1269 } 1270 for(i = 0; i < (count/2); i++){ 1271 tempPair = []; 1272 tempPair.push(colours.shift()); 1273 tempPair.push(colours.shift()); 1274 pairs.push(tempPair); 1275 } 1276 1277 // attribute overrides - allows per-gradient override of global options. 1278 ao.states = { 1279 "default-state": { 1280 gradients: pairs 1281 } 1282 } 1283 } 1284 1285 themeDefaults = { 1286 element: '#'+granimID, 1287 name: 'basic-gradient', 1288 direction: 'left-right', 1289 opacity: [1, 1], 1290 isPausedWhenNotInView: true, 1291 states : { 1292 "default-state": { 1293 gradients: pairs 1294 } 1295 } 1296 }; 1297 1298 options = jQuery.extend({}, themeDefaults, mr.granim.options, ao); 1299 $(this).data('gradientOptions', options); 1300 var granimElement = $(this); 1301 var granimInstance = new Granim(options); 1302 }); 1303 }; 1304 1305 mr.components.documentReadyDeferred.push(mr.granim.documentReady); 1306 return mr; 1307 1308}(mr, jQuery, window, document)); 1309 1310 1311//////////////// Maps 1312mr = (function (mr, $, window, document){ 1313 "use strict"; 1314 1315 mr.maps = mr.maps || {}; 1316 mr.maps.options = mr.maps.options || {}; 1317 1318 mr.maps.documentReady = function($){ 1319 // Interact with Map once the user has clicked (to prevent scrolling the page = zooming the map 1320 1321 $('.map-holder').on('click', function() { 1322 $(this).addClass('interact'); 1323 }).removeClass('interact'); 1324 1325 var mapsOnPage = $('.map-container[data-maps-api-key]'); 1326 if(mapsOnPage.length){ 1327 mapsOnPage.addClass('gmaps-active'); 1328 mr.maps.initAPI($); 1329 mr.maps.init(); 1330 } 1331 1332 }; 1333 1334 mr.maps.initAPI = function($){ 1335 // Load Google MAP API JS with callback to initialise when fully loaded 1336 if(document.querySelector('[data-maps-api-key]') && !document.querySelector('.gMapsAPI')){ 1337 if($('[data-maps-api-key]').length){ 1338 var script = document.createElement('script'); 1339 var apiKey = $('[data-maps-api-key]:first').attr('data-maps-api-key'); 1340 apiKey = typeof apiKey !== typeof undefined ? apiKey : ''; 1341 if(apiKey !== ''){
1342 script.type = 'text/javascript'; 1343 script.src = 'https://maps.googleapis.com/maps/api/js?key='+apiKey+'&callback=mr.maps.init'; 1344 script.className = 'gMapsAPI'; 1345 document.body.appendChild(script); 1346 } 1347 } 1348 } 1349 }; 1350 1351 mr.maps.init = function(){ 1352 if(typeof window.google !== "undefined"){ 1353 if(typeof window.google.maps !== "undefined"){ 1354 1355 mr.maps.instances = []; 1356 1357 1358 jQuery('.gmaps-active').each(function(){ 1359 var mapElement = this, 1360 mapInstance = jQuery(this), 1361 isDraggable = jQuery(document).width() > 766 ? true : false, 1362 showZoomControl = typeof mapInstance.attr('data-zoom-controls') !== typeof undefined ? true : false, 1363 zoomControlPos = typeof mapInstance.attr('data-zoom-controls') !== typeof undefined ? mapInstance.attr('data-zoom-controls'): false, 1364 latlong = typeof mapInstance.attr('data-latlong') !== typeof undefined ? mapInstance.attr('data-latlong') : false, 1365 latitude = latlong ? 1 *latlong.substr(0, latlong.indexOf(',')) : false, 1366 longitude = latlong ? 1 * latlong.substr(latlong.indexOf(",") + 1) : false, 1367 geocoder = new google.maps.Geocoder(), 1368 address = typeof mapInstance.attr('data-address') !== typeof undefined ? mapInstance.attr('data-address').split(';'): [""], 1369 map, marker, markerDefaults,mapDefaults,mapOptions, markerOptions, mapAo = {}, markerAo = {}, mapCreatedEvent; 1370 1371 mapCreatedEvent = document.createEvent('Event'); 1372 mapCreatedEvent.initEvent('mapCreated.maps.mr', true, true); 1373 1374 1375 1376 1377 mapDefaults = { 1378 disableDefaultUI: true, 1379 draggable: isDraggable, 1380 scrollwheel: false, 1381 styles: [{"featureType":"landscape","stylers":[{"saturation":-100},{"lightness":65},{"visibility":"on"}]},{"featureType":"poi","stylers":[{"saturation":-100},{"lightness":51},{"visibility":"simplified"}]},{"featureType":"road.highway","stylers":[{"saturation":-100},{"visibility":"simplified"}]},{"featureType":"road.arterial","stylers":[{"saturation":-100},{"lightness":30},{"visibility":"on"}]},{"featureType":"road.local","stylers":[{"saturation":-100},{"lightness":40},{"visibility":"on"}]},{"featureType":"transit","stylers":[{"saturation":-100},{"visibility":"simplified"}]},{"featureType":"administrative.province","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"labels","stylers":[{"visibility":"on"},{"lightness":-25},{"saturation":-100}]},{"featureType":"water","elementType":"geometry","stylers":[{"hue":"#ffff00"},{"lightness":-25},{"saturation":-97}]}], 1382 zoom: 17, 1383 zoomControl: false, 1384 }; 1385 1386 // Attribute overrides - allows data attributes on the map to override global options 1387 mapAo.styles = typeof mapInstance.attr('data-map-style') !== typeof undefined ? JSON.parse(mapInstance.attr('data-map-style')): undefined; 1388 mapAo.zoom = mapInstance.attr('data-map-zoom') ? parseInt(mapInstance.attr('data-map-zoom'),10) : undefined; 1389 mapAo.zoomControlOptions = zoomControlPos !== false ? {position: google.maps.ControlPosition[zoomControlPos]} : undefined; 1390 1391 markerDefaults = { 1392 icon: {url:( typeof mr_variant !== typeof undefined ? '../': '' )+'img/mapmarker.png', scaledSize: new google.maps.Size(50,50)}, 1393 title: 'We Are Here', 1394 optimised: false 1395 }; 1396 1397 markerAo.icon = typeof mapInstance.attr('data-marker-image') !== typeof undefined ? {url: mapInstance.attr('data-marker-image'), scaledSize: new google.maps.Size(50,50)} : undefined; 1398 markerAo.title = mapInstance.attr('data-marker-title'); 1399 1400 mapOptions = jQuery.extend({}, mapDefaults, mr.maps.options.map, mapAo); 1401 markerOptions = jQuery.extend({}, markerDefaults, mr.maps.options.marker, markerAo); 1402 1403 1404 if(address !== undefined && address[0] !== ""){ 1405 geocoder.geocode( { 'address': address[0].replace('[nomarker]','')}, function(results, status) { 1406 if (status === google.maps.GeocoderStatus.OK) { 1407 map = new google.maps.Map(mapElement, mapOptions); 1408 1409 1410 mr.maps.instances.push(map); 1411 jQuery(mapElement).trigger('mapCreated.maps.mr').get(0).dispatchEvent(mapCreatedEvent); 1412 map.setCenter(results[0].geometry.location); 1413 1414 address.forEach(function(address){ 1415 var markerGeoCoder; 1416 1417 if(/(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)/.test(address) ){ 1418 var latlong = address.split(','), 1419 marker = new google.maps.Marker(jQuery.extend({}, markerOptions, { 1420 position: { lat: 1*latlong[0], lng: 1*latlong[1] }, 1421 map: map, 1422 })); 1423 }
1424 else if(address.indexOf('[nomarker]') < 0){ 1425 markerGeoCoder = new google.maps.Geocoder(); 1426 markerGeoCoder.geocode( { 'address': address.replace('[nomarker]','')}, function(results, status) { 1427 if (status === google.maps.GeocoderStatus.OK) { 1428 marker = new google.maps.Marker(jQuery.extend({}, markerOptions, { 1429 map: map, 1430 position: results[0].geometry.location, 1431 })); 1432 } 1433 else{ 1434 console.log('Map marker error: '+status); 1435 } 1436 }); 1437 } 1438 1439 }); 1440 } else { 1441 console.log('There was a problem geocoding the address.'); 1442 } 1443 }); 1444 } 1445 else if(typeof latitude !== typeof undefined && latitude !== "" && latitude !== false && typeof longitude !== typeof undefined && longitude !== "" && longitude !== false ){ 1446 1447 mapOptions.center = { lat: latitude, lng: longitude}; 1448 map = new google.maps.Map(mapElement, mapOptions); 1449 marker = new google.maps.Marker(jQuery.extend({}, markerOptions, { 1450 position: { lat: latitude, lng: longitude }, 1451 map: map })); 1452 mr.maps.instances.push(map); 1453 jQuery(mapElement).trigger('mapCreated.maps.mr').get(0).dispatchEvent(mapCreatedEvent); 1454 1455 1456 } 1457 1458 1459 1460 }); 1461 } 1462 } 1463 }; 1464 1465 mr.components.documentReady.push(mr.maps.documentReady); 1466 return mr; 1467 1468}(mr, jQuery, window, document)); 1469 1470 1471//////////////// Masonry 1472mr = (function (mr, $, window, document){ 1473 "use strict"; 1474 1475 mr.masonry = mr.masonry || {}; 1476 1477 mr.masonry.documentReady = function($){ 1478 1479 mr.masonry.updateFilters(); 1480 1481 $(document).on('click touchstart', '.masonry__filters li:not(.js-no-action)', function(){ 1482 var masonryFilter = $(this); 1483 var masonryContainer = masonryFilter.closest('.masonry').find('.masonry__container'); 1484 var filterValue = '*'; 1485 if(masonryFilter.attr('data-masonry-filter') !== '*'){ 1486 filterValue = '.filter-'+masonryFilter.attr('data-masonry-filter'); 1487 } 1488 masonryFilter.siblings('li').removeClass('active'); 1489 masonryFilter.addClass('active'); 1490 masonryContainer.removeClass('masonry--animate'); 1491 masonryContainer.on('layoutComplete',function(){ 1492 $(this).addClass('masonry--active'); 1493 if(typeof mr_parallax !== typeof undefined){ 1494 setTimeout(function(){ mr_parallax.profileParallaxElements(); },100); 1495 } 1496 }); 1497 masonryContainer.isotope({ filter: filterValue }); 1498 1499 }); 1500 1501 }; 1502 1503 mr.masonry.windowLoad = function(){ 1504 1505 $('.masonry').each(function(){ 1506 var masonry = $(this).find('.masonry__container'), 1507 masonryParent = $(this), 1508 defaultFilter = '*', 1509 themeDefaults, ao = {}; 1510 1511 themeDefaults = { 1512 itemSelector: '.masonry__item', 1513 filter: '*', 1514 masonry: { 1515 columnWidth: '.masonry__item' 1516 } 1517 }; 1518 1519 // Check for a default filter attribute 1520 if(masonryParent.is('[data-default-filter]')){ 1521 defaultFilter = masonryParent.attr('data-default-filter').toLowerCase(); 1522 defaultFilter = '.filter-'+defaultFilter; 1523 masonryParent.find('li[data-masonry-filter]').removeClass('active'); 1524 masonryParent.find('li[data-masonry-filter="'+masonryParent.attr("data-default-filter").toLowerCase()+'"]').addClass('active'); 1525 } 1526 1527 // Use data attributes to override the default settings and provide a per-masonry customisation where necessary. 1528 ao.filter = defaultFilter !== '*' ? defaultFilter : undefined; 1529 1530 masonry.on('layoutComplete',function(){ 1531 masonry.addClass('masonry--active'); 1532 if(typeof mr_parallax !== typeof undefined){ 1533 setTimeout(function(){ mr_parallax.profileParallaxElements(); },100); 1534 } 1535 }); 1536 1537 1538 masonry.isotope(jQuery.extend({}, themeDefaults, mr.masonry.options, ao)); 1539 1540 }); 1541 }; 1542 1543 mr.masonry.updateFilters = function(masonry){ 1544 1545 // If no argument is supplied, just apply the update to all masonry sets on the page. 1546 masonry = typeof masonry !== typeof undefined ? masonry : '.masonry'; 1547 1548 var $masonry = $(masonry); 1549 1550 $masonry.each(function(){ 1551 var $masonry = $(this), 1552 masonryContainer = $masonry.find('.masonry__container'), 1553 filters = $masonry.find('.masonry__filters'), 1554 // data-filter-all-text can be used to set the word for "all" 1555 filterAllText = typeof filters.attr('data-filter-all-text') !== typeof undefined ? filters.attr('data-filter-all-text') : "All", 1556 filtersList; 1557 1558 // Ensure we are working with a .masonry element 1559 if($masonry.is('.masonry')){ 1560 // If a filterable masonry item exists 1561 if(masonryContainer.find('.masonry__item[data-masonry-filter]').length){ 1562 1563 // Create empty ul for filters 1564 filtersList = filters.find('> ul'); 1565 1566 if(!filtersList.length){ 1567 filtersList = filters.append('<ul></ul>').find('> ul'); 1568 } 1569 1570 // To avoid cases where user leave filter attribute blank 1571 // only take items that have filter attribute 1572 masonryContainer.find('.masonry__item[data-masonry-filter]').each(function(){ 1573 var masonryItem = $(this), 1574 filterString = masonryItem.attr('data-masonry-filter'), 1575 filtersArray = []; 1576 1577 // If not undefined or empty 1578 if(typeof filterString !== typeof undefined && filterString !== ""){ 1579 // Split tags from string into array 1580 filtersArray = filterString.split(','); 1581 } 1582 $(filtersArray).each(function(index, tag){ 1583 1584 // Slugify the tag 1585 1586 var slug = mr.util.slugify(tag); 1587 1588 // Add the filter class to the masonry item 1589 1590 masonryItem.addClass('filter-'+slug); 1591 1592 // If this tag does not appear in the list already, add it 1593 if(!filtersList.find('[data-masonry-filter="'+slug+'"]').length){ 1594 filtersList.append('<li data-masonry-filter="'+slug+'">'+tag+'</li>'); 1595 1596 } 1597 }); 1598 }); 1599
1600 // Remove any unnused filter options in list 1601 filtersList.find('[data-masonry-filter]').each(function(){ 1602 var $this = $(this), 1603 filter = $this.text(); 1604 1605 if($(this).attr('data-masonry-filter') !== "*"){ 1606 if(!$masonry.find('.masonry__item[data-masonry-filter*="'+filter+'"]').length){ 1607 $this.remove(); 1608 } 1609 } 1610 }); 1611 1612 mr.util.sortChildrenByText($(this).find('.masonry__filters ul')); 1613 // Add a filter "all" option 1614 if(!filtersList.find('[data-masonry-filter="*"]').length){ 1615 filtersList.prepend('<li class="active" data-masonry-filter="*">'+filterAllText+'</li>'); 1616 } 1617 1618 } 1619 //End of "if filterable masonry item exists" 1620 } 1621 //End of "if $masonry is .masonry" 1622 }); 1623 1624 }; 1625 1626 mr.masonry.updateLayout = function(masonry){ 1627 1628 // If no argument is supplied, just apply the update to all masonry sets on the page. 1629 masonry = typeof masonry !== typeof undefined ? masonry : '.masonry'; 1630 1631 var $masonry = $(masonry); 1632 1633 1634 $masonry.each(function(){ 1635 var collection = $(this), 1636 newItems = collection.find('.masonry__item:not([style])'), 1637 masonryContainer = collection.find('.masonry__container'); 1638 1639 if(collection.is('.masonry')){ 1640 if(newItems.length){ 1641 masonryContainer.isotope('appended', newItems).isotope( 'layout'); 1642 } 1643 1644 masonryContainer.isotope('layout'); 1645 } 1646 }); 1647 }; 1648 1649 mr.components.documentReady.push(mr.masonry.documentReady); 1650 mr.components.windowLoad.push(mr.masonry.windowLoad); 1651 return mr; 1652 1653}(mr, jQuery, window, document)); 1654 1655 1656//////////////// Modals 1657mr = (function (mr, $, window, document){ 1658 "use strict"; 1659 1660 mr.modals = mr.modals || {}; 1661 1662 mr.modals.documentReady = function($){ 1663 var allPageModals = "<div class=\"all-page-modals\"></div>", 1664 mainContainer = $('div.main-container'); 1665 1666 if(mainContainer.length){ 1667 jQuery(allPageModals).insertAfter(mainContainer); 1668 mr.modals.allModalsContainer = $('div.all-page-modals'); 1669 } 1670 else{ 1671 jQuery('body').append(allPageModals); 1672 mr.modals.allModalsContainer = jQuery('body div.all-page-modals'); 1673 } 1674 1675 $('.modal-container').each(function(){ 1676 1677 // Add modal close if none exists 1678 1679 var modal = $(this), 1680 $window = $(window), 1681 modalContent = modal.find('.modal-content'); 1682 1683 1684 if(!modal.find('.modal-close').length){ 1685 modal.find('.modal-content').append('<div class="modal-close modal-close-cross"></div>'); 1686 } 1687 1688 // Set modal height 1689 1690 if(modalContent.attr('data-width') !== undefined){ 1691 var modalWidth = modalContent.attr('data-width').substr(0,modalContent.attr('data-width').indexOf('%')) * 1; 1692 modalContent.css('width',modalWidth + '%'); 1693 } 1694 if(modalContent.attr('data-height') !== undefined){ 1695 var modalHeight = modalContent.attr('data-height').substr(0,modalContent.attr('data-height').indexOf('%')) * 1; 1696 modalContent.css('height',modalHeight + '%'); 1697 } 1698 1699 // Set iframe's src to data-src to stop autoplaying iframes 1700 mr.util.idleSrc(modal, 'iframe'); 1701 1702 }); 1703 1704 1705 $('.modal-instance').each(function(index){ 1706 var modalInstance = $(this); 1707 var modal = modalInstance.find('.modal-container'); 1708 var modalContent = modalInstance.find('.modal-content');
1709 var trigger = modalInstance.find('.modal-trigger'); 1710 1711 // Link modal with modal-id attribute 1712 1713 trigger.attr('data-modal-index',index); 1714 modal.attr('data-modal-index',index); 1715 1716 // Set unique id for multiple triggers 1717 1718 if(typeof modal.attr('data-modal-id') !== typeof undefined){ 1719 trigger.attr('data-modal-id', modal.attr('data-modal-id')); 1720 } 1721 1722 1723 // Attach the modal to the body 1724 modal = modal.detach(); 1725 mr.modals.allModalsContainer.append(modal); 1726 }); 1727 1728 1729 $('.modal-trigger').on('click', function(){ 1730 1731 var modalTrigger = $(this); 1732 var uniqueID, targetModal; 1733 // Determine if the modal id is set by user or is set programatically 1734 1735 if(typeof modalTrigger.attr('data-modal-id') !== typeof undefined){ 1736 uniqueID = modalTrigger.attr('data-modal-id'); 1737 targetModal = mr.modals.allModalsContainer.find('.modal-container[data-modal-id="'+uniqueID+'"]'); 1738 }else{ 1739 uniqueID = $(this).attr('data-modal-index'); 1740 targetModal = mr.modals.allModalsContainer.find('.modal-container[data-modal-index="'+uniqueID+'"]'); 1741 } 1742 1743 mr.util.activateIdleSrc(targetModal, 'iframe'); 1744 mr.modals.autoplayVideo(targetModal); 1745 1746 mr.modals.showModal(targetModal); 1747 1748 return false; 1749 }); 1750 1751 jQuery(document).on('click', '.modal-close', mr.modals.closeActiveModal); 1752 1753 jQuery(document).keyup(function(e) { 1754 if (e.keyCode === 27) { // escape key maps to keycode `27` 1755 mr.modals.closeActiveModal(); 1756 } 1757 }); 1758 1759 $('.modal-container:not(.modal--prevent-close)').on('click', function(e) { 1760 if( e.target !== this ) return; 1761 mr.modals.closeActiveModal(); 1762 }); 1763 1764 // Trigger autoshow modals 1765 $('.modal-container[data-autoshow]').each(function(){ 1766 var modal = $(this); 1767 var millisecondsDelay = modal.attr('data-autoshow')*1; 1768 1769 mr.util.activateIdleSrc(modal); 1770 mr.modals.autoplayVideo(modal); 1771 1772 // If this modal has a cookie attribute, check to see if a cookie is set, and if so, don't show it. 1773 if(typeof modal.attr('data-cookie') !== typeof undefined){ 1774 if(!mr.cookies.hasItem(modal.attr('data-cookie'))){ 1775 mr.modals.showModal(modal, millisecondsDelay); 1776 } 1777 }else{ 1778 mr.modals.showModal(modal, millisecondsDelay); 1779 } 1780 }); 1781 1782 // Exit modals 1783 $('.modal-container[data-show-on-exit]').each(function(){ 1784 var modal = jQuery(this), 1785 exitSelector = modal.attr('data-show-on-exit'), 1786 delay = 0; 1787 1788 if(modal.attr('data-delay')){ 1789 delay = parseInt(modal.attr('data-delay'), 10) || 0; 1790 } 1791 1792 // If a valid selector is found, attach leave event to show modal. 1793 if($(exitSelector).length){ 1794 modal.prepend($('<i class="ti-close close-modal">')); 1795 jQuery(document).on('mouseleave', exitSelector, function(){ 1796 if(!$('.modal-active').length){ 1797 if(typeof modal.attr('data-cookie') !== typeof undefined){ 1798 if(!mr.cookies.hasItem(modal.attr('data-cookie'))){ 1799 mr.modals.showModal(modal, delay); 1800 } 1801 }else{ 1802 mr.modals.showModal(modal, delay); 1803 } 1804 } 1805 }); 1806 } 1807 }); 1808 1809 1810 // Autoshow modal by ID from location href 1811 if(window.location.href.split('#').length === 2){ 1812 var modalID = window.location.href.split('#').pop(); 1813 if($('[data-modal-id="'+modalID+'"]').length){ 1814 mr.modals.closeActiveModal(); 1815 mr.modals.showModal($('[data-modal-id="'+modalID+'"]')); 1816 } 1817 } 1818 1819 jQuery(document).on('click','a[href^="#"]', function(){ 1820 var modalID = $(this).attr('href').replace('#', ''); 1821 if($('[data-modal-id="'+modalID+'"]').length){ 1822 mr.modals.closeActiveModal(); 1823 setTimeout(mr.modals.showModal, 500,'[data-modal-id="'+modalID+'"]', 0); 1824 } 1825 }); 1826 1827 // Make modal scrollable 1828 jQuery(document).on('wheel mousewheel scroll','.modal-content, .modal-content .scrollable', function(evt){ 1829 if(evt.preventDefault){evt.preventDefault();} 1830 if(evt.stopPropagation){evt.stopPropagation();} 1831 this.scrollTop += (evt.originalEvent.deltaY); 1832 }); 1833 };
1834 //////////////// 1835 //////////////// End documentReady 1836 //////////////// 1837 1838 mr.modals.showModal = function(modal, millisecondsDelay){ 1839 1840 var delay = (typeof millisecondsDelay !== typeof undefined) ? (1*millisecondsDelay) : 0, $modal = $(modal); 1841 1842 if($modal.length){ 1843 setTimeout(function(){ 1844 var openEvent = document.createEvent('Event'); 1845 openEvent.initEvent('modalOpened.modals.mr', true, true); 1846 $(modal).addClass('modal-active').trigger('modalOpened.modals.mr').get(0).dispatchEvent(openEvent); 1847 1848 },delay); 1849 } 1850 }; 1851 1852 mr.modals.closeActiveModal = function(){ 1853 var modal = jQuery('body div.modal-active'), 1854 closeEvent = document.createEvent('Event'); 1855 1856 mr.util.idleSrc(modal, 'iframe'); 1857 mr.util.pauseVideo(modal); 1858 1859 // If this modal requires to be closed permanently using a cookie, set the cookie now. 1860 if(typeof modal.attr('data-cookie') !== typeof undefined){ 1861 mr.cookies.setItem(modal.attr('data-cookie'), "true", Infinity, '/'); 1862 } 1863 1864 if(modal.length){ 1865 // Remove hash from URL bar if this modal was opened via url bar ID 1866 if(modal.is('[data-modal-id]') && window.location.hash === '#'+modal.attr('data-modal-id')){ 1867 mr.util.removeHash(); 1868 } 1869 closeEvent.initEvent('modalClosed.modals.mr', true, true); 1870 modal.removeClass('modal-active').trigger('modalClosed.modals.mr').get(0).dispatchEvent(closeEvent); 1871 } 1872 }; 1873 1874 mr.modals.autoplayVideo = function(modal){ 1875 // If modal contains HTML5 video with autoplay, play the video 1876 if(modal.find('video[autoplay]').length){ 1877 var video = modal.find('video').get(0); 1878 video.play(); 1879 } 1880 }; 1881 1882 mr.components.documentReady.push(mr.modals.documentReady); 1883 return mr; 1884 1885}(mr, jQuery, window, document)); 1886 1887//////////////// Newsletter Providers 1888mr = (function (mr, $, window, document){ 1889 "use strict"; 1890 1891 mr.newsletters = mr.newsletters || {}; 1892 1893 mr.newsletters.documentReady = function($){ 1894 1895 var form,checkbox,label,id,parent,radio; 1896 1897 // Treat Campaign Monitor forms 1898 $('form[action*="createsend.com"]').each(function(){ 1899 form = $(this); 1900 1901 // Override browser validation and allow us to use our own 1902 form.attr('novalidate', 'novalidate'); 1903 1904 // Give each text input a placeholder value 1905 1906 if(!form.is('.form--no-placeholders')){ 1907 form.find('input:not([checkbox]):not([radio])').each(function(){ 1908 var $input = $(this); 1909 if(typeof $input.attr('placeholder') !== typeof undefined){ 1910 if($input.attr('placeholder') === ""){ 1911 if($input.siblings('label').length){ 1912 $input.attr('placeholder', $input.siblings('label').first().text()); 1913 if(form.is('.form--no-labels')){ 1914 $input.siblings('label').first().remove(); 1915 } 1916 } 1917 } 1918 }else if($input.siblings('label').length){ 1919 $input.attr('placeholder', $input.siblings('label').first().text()); 1920 if(form.is('.form--no-labels')){ 1921 $input.siblings('label').first().remove(); 1922 } 1923 } 1924 if($input.parent().is('p')){ 1925 $input.unwrap(); 1926 } 1927 }); 1928 }else{ 1929 form.find('input[placeholder]').removeAttr('placeholder'); 1930 } 1931 1932 1933 // Wrap select elements in template code 1934 1935 form.find('select').wrap('<div class="input-select"></div>'); 1936 1937 // Wrap radios elements in template code 1938 1939 form.find('input[type="radio"]').wrap('<div class="input-radio"></div>'); 1940 1941 // Wrap checkbox elements in template code 1942 1943 form.find('input[type="checkbox"]').each(function(){ 1944 checkbox = $(this); 1945 id = checkbox.attr('id'); 1946 label = form.find('label[for='+id+']'); 1947 if(!label.length){ 1948 label = $('<label for="'+id+'"></label>'); 1949 } 1950 1951 checkbox.before('<div class="input-checkbox" data-id="'+id+'"></div>'); 1952 $('.input-checkbox[data-id="'+id+'"]').prepend(checkbox); 1953 $('.input-checkbox[data-id="'+id+'"]').prepend(label); 1954 }); 1955 1956 form.find('button[type="submit"]').each(function(){ 1957 var button = $(this); 1958 button.addClass('btn'); 1959 if(button.parent().is('p')){ 1960 button.unwrap(); 1961 } 1962 }); 1963 1964 form.find('[required]').attr('required', 'required').addClass('validate-required'); 1965 1966 form.addClass('form--active'); 1967 1968 mr.newsletters.prepareAjaxAction(form); 1969 1970 1971 }); 1972 1973 // Treat MailChimp forms 1974 $('form[action*="list-manage.com"]').each(function(){ 1975 form = $(this); 1976 1977 // Override browser validation and allow us to use our own 1978 form.attr('novalidate', 'novalidate'); 1979 1980 // Give each text input a placeholder value 1981 if(!form.is('.form--no-placeholders')){
1982 form.find('input:not([checkbox]):not([radio])').each(function(){ 1983 var $input = $(this); 1984 if(typeof $input.attr('placeholder') !== typeof undefined){ 1985 if($input.attr('placeholder') === ""){ 1986 if($input.siblings('label').length){ 1987 $input.attr('placeholder', $input.siblings('label').first().text()); 1988 if(form.is('.form--no-labels')){ 1989 $input.siblings('label').first().remove(); 1990 } 1991 } 1992 } 1993 }else if($input.siblings('label').length){ 1994 $input.attr('placeholder', $input.siblings('label').first().text()); 1995 if(form.is('.form--no-labels')){ 1996 $input.siblings('label').first().remove(); 1997 } 1998 } 1999 }); 2000 }else{ 2001 form.find('input[placeholder]').removeAttr('placeholder'); 2002 } 2003 2004 if(form.is('.form--no-labels')){ 2005 form.find('input:not([checkbox]):not([radio])').each(function(){ 2006 var $input = $(this); 2007 if($input.siblings('label').length){ 2008 $input.siblings('label').first().remove(); 2009 } 2010 }); 2011 } 2012 2013 // Wrap select elements in template code 2014 2015 form.find('select').wrap('<div class="input-select"></div>'); 2016 2017 // Wrap checboxes elements in template code 2018 2019 form.find('input[type="checkbox"]').each(function(){ 2020 checkbox = jQuery(this); 2021 parent = checkbox.parent(); 2022 label = parent.find('label'); 2023 if(!label.length){ 2024 label = jQuery('<label>'); 2025 } 2026 checkbox.before('<div class="input-checkbox"></div>'); 2027 parent.find('.input-checkbox').append(checkbox); 2028 parent.find('.input-checkbox').append(label); 2029 }); 2030 2031 // Wrap radio elements in template code 2032 2033 form.find('input[type="radio"]').each(function(){ 2034 radio = jQuery(this); 2035 parent = radio.closest('li'); 2036 label = parent.find('label'); 2037 if(!label.length){ 2038 label = jQuery('<label>'); 2039 } 2040 radio.before('<div class="input-radio"></div>'); 2041 parent.find('.input-radio').prepend(radio); 2042 parent.find('.input-radio').prepend(label); 2043 }); 2044 2045 // Convert MailChimp input[type="submit"] to div.button 2046 2047 form.find('input[type="submit"]').each(function(){ 2048 var submit = $(this); 2049 2050 var newButton = jQuery('<button/>').attr('type','submit').attr('class', submit.attr('class')).addClass('btn').text(submit.attr('value')); 2051 2052 if(submit.parent().is('div.clear')){ 2053 submit.unwrap(); 2054 } 2055 2056 newButton.insertBefore(submit); 2057 submit.remove(); 2058 }); 2059 2060 form.find('input').each(function(){ 2061 var input = $(this); 2062 if(input.hasClass('required')){ 2063 input.removeClass('required').addClass('validate-required'); 2064 } 2065 }); 2066 2067 form.find('input[type="email"]').removeClass('email').addClass('validate-email'); 2068 2069 form.find('#mce-responses').remove(); 2070 2071 form.find('.mc-field-group').each(function(){ 2072 $(this).children().first().unwrap(); 2073 }); 2074 2075 form.find('[required]').attr('required', 'required').addClass('validate-required'); 2076 2077 form.addClass('form--active'); 2078 2079 mr.newsletters.prepareAjaxAction(form); 2080 2081 }); 2082 2083 // Reinitialize the forms so interactions work as they should 2084 2085 mr.forms.documentReady(mr.setContext('form.form--active')); 2086 2087 }; 2088 2089 mr.newsletters.prepareAjaxAction = function(form){ 2090 var action = $(form).attr('action'); 2091 2092 // Alter action for a Mail Chimp-compatible ajax request url. 2093 if(/list-manage\.com/.test(action)){ 2094 action = action.replace('/post?', '/post-json?') + "&c=?"; 2095 if(action.substr(0,2) === "//"){ 2096 action = 'http:' + action; 2097 } 2098 } 2099 2100 // Alter action for a Campaign Monitor-compatible ajax request url. 2101 if(/createsend\.com/.test(action)){ 2102 action = action + '?callback=?'; 2103 } 2104 2105 // Set action on the form 2106 $(form).attr('action', action); 2107 2108 }; 2109 2110 2111 2112 mr.components.documentReady.push(mr.newsletters.documentReady); 2113 return mr; 2114 2115}(mr, jQuery, window, document)); 2116
2117//////////////// Notifications 2118mr = (function (mr, $, window, document){ 2119 "use strict"; 2120 2121 mr.notifications = mr.notifications || {}; 2122 2123 mr.notifications.documentReady = function($){ 2124 2125 $('.notification').each(function(){ 2126 var notification = $(this); 2127 if(!notification.find('.notification-close').length){ 2128 notification.append('<div class="notification-close-cross notification-close"></div>'); 2129 } 2130 }); 2131 2132 2133 $('.notification[data-autoshow]').each(function(){ 2134 var notification = $(this); 2135 var millisecondsDelay = parseInt(notification.attr('data-autoshow'),10); 2136 2137 // If this notification has a cookie attribute, check to see if a cookie is set, and if so, don't show it. 2138 if(typeof notification.attr('data-cookie') !== typeof undefined){ 2139 if(!mr.cookies.hasItem(notification.attr('data-cookie'))){ 2140 mr.notifications.showNotification(notification, millisecondsDelay); 2141 } 2142 }else{ 2143 mr.notifications.showNotification(notification, millisecondsDelay); 2144 } 2145 }); 2146 2147 $('[data-notification-link]:not(.notification)').on('click', function(){ 2148 var notificationID = jQuery(this).attr('data-notification-link'); 2149 var notification = $('.notification[data-notification-link="'+notificationID+'"]'); 2150 jQuery('.notification--reveal').addClass('notification--dismissed'); 2151 notification.removeClass('notification--dismissed'); 2152 mr.notifications.showNotification(notification, 0); 2153 return false; 2154 }); 2155 2156 $('.notification-close').on('click', function(){ 2157 var closeButton = jQuery(this); 2158 // Pass the closeNotification function a reference to the close button 2159 mr.notifications.closeNotification(closeButton); 2160 2161 if(closeButton.attr('href') === '#'){ 2162 return false; 2163 } 2164 }); 2165 2166 $('.notification .inner-link').on('click', function(){ 2167 var notificationLink = jQuery(this).closest('.notification').attr('data-notification-link'); 2168 mr.notifications.closeNotification(notificationLink); 2169 }); 2170 2171 }; 2172 2173 2174 mr.notifications.showNotification = function(notification, millisecondsDelay){ 2175 var $notification = jQuery(notification), 2176 delay = (typeof millisecondsDelay !== typeof undefined) ? (1*millisecondsDelay) : 0, 2177 openEvent = document.createEvent('Event'); 2178 2179 setTimeout(function(){ 2180 openEvent.initEvent('notificationOpened.notifications.mr', true, true); 2181 $notification.addClass('notification--reveal').trigger('notificationOpened.notifications.mr').get(0).dispatchEvent(openEvent); 2182 $notification.closest('nav').addClass('notification--reveal'); 2183 if($notification.find('input').length){ 2184 $notification.find('input').first().focus(); 2185 } 2186 2187 2188 2189 },delay); 2190 // If notification has autohide attribute, set a timeout 2191 // for the autohide time plus the original delay time in case notification was called 2192 // on page load 2193 if(notification.is('[data-autohide]')){ 2194 var hideDelay = parseInt(notification.attr('data-autohide'),10); 2195 setTimeout(function(){ 2196 mr.notifications.closeNotification(notification); 2197 },hideDelay+delay); 2198 } 2199 }; 2200 2201 mr.notifications.closeNotification = function(notification){ 2202 var $notification = jQuery(notification), 2203 closeEvent = document.createEvent('Event'); 2204 notification = $notification.is('.notification') ? 2205 $notification : 2206 $notification.is('.notification-close') ? 2207 $notification.closest('.notification') : 2208 $('.notification[data-notification-link="'+notification+'"]'); 2209 2210 closeEvent.initEvent('notificationClosed.notifications.mr', true, true); 2211 notification.addClass('notification--dismissed').trigger('notificationClosed.notifications.mr').get(0).dispatchEvent(closeEvent); 2212 notification.closest('nav').removeClass('notification--reveal'); 2213 2214 // If this notification requires to be closed permanently using a cookie, set the cookie now. 2215 if(typeof notification.attr('data-cookie') !== typeof undefined){ 2216 mr.cookies.setItem(notification.attr('data-cookie'), "true", Infinity, '/'); 2217 } 2218 }; 2219 2220 mr.components.documentReady.push(mr.notifications.documentReady); 2221 return mr; 2222 2223}(mr, jQuery, window, document)); 2224
2225//////////////// Parallax 2226mr = (function (mr, $, window, document){ 2227 "use strict"; 2228 2229 mr.parallax = mr.parallax || {}; 2230 2231 mr.parallax.documentReady = function($){ 2232 2233 var $window = $(window); 2234 var windowWidth = $window.width(); 2235 var windowHeight = $window.height(); 2236 var navHeight = $('nav').outerHeight(true); 2237 2238 if (windowWidth > 768) { 2239 var parallaxHero = $('.parallax:nth-of-type(1)'), 2240 parallaxHeroImage = $('.parallax:nth-of-type(1) .background-image-holder'); 2241 2242 parallaxHeroImage.css('top', -(navHeight)); 2243 if(parallaxHero.outerHeight(true) === windowHeight){ 2244 parallaxHeroImage.css('height', windowHeight + navHeight); 2245 } 2246 } 2247 }; 2248 2249 mr.parallax.update = function(){ 2250 if(typeof mr_parallax !== typeof undefined){ 2251 mr_parallax.profileParallaxElements(); 2252 mr_parallax.mr_parallaxBackground(); 2253 } 2254 }; 2255 2256 mr.components.documentReady.push(mr.parallax.documentReady); 2257 return mr; 2258 2259}(mr, jQuery, window, document)); 2260 2261//////////////// Progress Horizontal (bars) 2262mr = (function (mr, $, window, document){ 2263 "use strict"; 2264 2265 mr.progressHorizontal = mr.progressHorizontal || {}; 2266 2267 mr.progressHorizontal.documentReady = function($){ 2268 2269 var progressBars = []; 2270 2271 $('.progress-horizontal').each(function(){ 2272 var bar = jQuery(this).find('.progress-horizontal__bar'), 2273 barObject = {}, 2274 progress = jQuery('<div class="progress-horizontal__progress"></div>'); 2275 2276 bar.prepend(progress); 2277 2278 barObject.element = bar; 2279 barObject.progress = progress; 2280 barObject.value = parseInt(bar.attr('data-value'),10)+"%"; 2281 barObject.offsetTop = bar.offset().top; 2282 barObject.animate = false; 2283 2284 if(jQuery(this).hasClass('progress-horizontal--animate')){ 2285 barObject.animate = true; 2286 }else{ 2287 progress.css('width',barObject.value); 2288 } 2289 progressBars.push(barObject); 2290 }); 2291 }; 2292 2293 mr.components.documentReady.push(mr.progressHorizontal.documentReady); 2294 return mr; 2295 2296}(mr, jQuery, window, document)); 2297 2298//////////////// EasyPiecharts 2299mr = (function (mr, $, window, document){ 2300 "use strict"; 2301 2302 mr.easypiecharts = mr.easypiecharts || {}; 2303 mr.easypiecharts.pies = []; 2304 mr.easypiecharts.options = mr.easypiecharts.options || {}; 2305 2306 mr.easypiecharts.documentReady = function($){ 2307 2308 $('.radial').each(function(){ 2309 var chart = jQuery(this), 2310 value = 0, 2311 color = '#000000', 2312 time = 2000, 2313 pieSize = 110, 2314 barWidth = 3, 2315 defaults = {}, 2316 attributeOverrides = {}, 2317 options; 2318 2319 defaults = { 2320 animate: ({duration: time, enabled: true}), 2321 barColor: color, 2322 scaleColor: false, 2323 size: pieSize, 2324 lineWidth: barWidth 2325 }; 2326 2327 if(typeof mr.easypiecharts.options.size !== typeof undefined){ 2328 pieSize = mr.easypiecharts.options.size; 2329 } 2330 if(typeof chart.attr('data-timing') !== typeof undefined){ 2331 attributeOverrides.animate = {duration: parseInt(chart.attr('data-timing'), 10), enabled: true}; 2332 } 2333 if(typeof chart.attr('data-color') !== typeof undefined){ 2334 attributeOverrides.barColor = chart.attr('data-color'); 2335 } 2336 if(typeof chart.attr('data-size') !== typeof undefined){ 2337 pieSize = attributeOverrides.size = parseInt(chart.attr('data-size'), 10); 2338 } 2339 if(typeof chart.attr('data-bar-width') !== typeof undefined){ 2340 attributeOverrides.lineWidth = parseInt(chart.attr('data-bar-width'), 10); 2341 } 2342 2343 chart.css('height',pieSize).css('width',pieSize); 2344 2345 2346 2347 if(typeof mr.easypiecharts.options === 'object'){ 2348 options = jQuery.extend({}, defaults, mr.easypiecharts.options, attributeOverrides); 2349 } 2350 2351 chart.easyPieChart(options); 2352 chart.data('easyPieChart').update(0); 2353 }); 2354 2355 if($('.radial').length){ 2356 mr.easypiecharts.init($); 2357 mr.easypiecharts.activate(); 2358 mr.scroll.listeners.push(mr.easypiecharts.activate); 2359 } 2360 2361 }; 2362 2363 mr.easypiecharts.init = function($){ 2364 2365 mr.easypiecharts.pies = []; 2366 2367 $('.radial').each(function(){ 2368 var pieObject = {}, 2369 currentPie = jQuery(this); 2370 2371 pieObject.element = currentPie; 2372 pieObject.value = parseInt(currentPie.attr('data-value'),10); 2373 pieObject.top = currentPie.offset().top; 2374 pieObject.height = currentPie.height()/2; 2375 pieObject.active = false; 2376 mr.easypiecharts.pies.push(pieObject); 2377 }); 2378 }; 2379 2380 mr.easypiecharts.activate = function(){
2381 mr.easypiecharts.pies.forEach(function(pie){ 2382 if(Math.round((mr.scroll.y + mr.window.height)) >= Math.round(pie.top+pie.height)){ 2383 if(pie.active === false){ 2384 2385 pie.element.data('easyPieChart').enableAnimation(); 2386 pie.element.data('easyPieChart').update(pie.value); 2387 pie.element.addClass('radial--active'); 2388 pie.active = true; 2389 } 2390 } 2391 }); 2392 }; 2393 2394 mr.components.documentReadyDeferred.push(mr.easypiecharts.documentReady); 2395 return mr; 2396 2397}(mr, jQuery, window, document)); 2398 2399//////////////// Flickity 2400mr = (function (mr, $, window, document){ 2401 "use strict"; 2402 2403 mr.sliders = mr.sliders || {}; 2404 2405 mr.sliders.documentReady = function($){ 2406 2407 $('.slider').each(function(index){ 2408 2409 var slider = $(this); 2410 var sliderInitializer = slider.find('div.slides'); 2411 sliderInitializer.find('>div').addClass('slide'); 2412 var childnum = sliderInitializer.find('div').length; 2413 2414 var themeDefaults = { 2415 cellSelector: '.slide', 2416 cellAlign: 'left', 2417 wrapAround: true, 2418 pageDots: false, 2419 prevNextButtons: false, 2420 autoPlay: true, 2421 draggable: (childnum < 2 ? false: true), 2422 imagesLoaded: true, 2423 accessibility: true, 2424 rightToLeft: false, 2425 initialIndex: 0, 2426 freeScroll: false 2427 }; 2428 2429 // Attribute Overrides - options that are overridden by data attributes on the slider element 2430 var ao = {}; 2431 ao.pageDots = (slider.attr('data-paging') === 'true' && sliderInitializer.find('div').length > 1) ? true : undefined; 2432 ao.prevNextButtons = slider.attr('data-arrows') === 'true'? true: undefined; 2433 ao.draggable = slider.attr('data-draggable') === 'false'? false : undefined; 2434 ao.autoPlay = slider.attr('data-autoplay') === 'false'? false: (slider.attr('data-timing') ? parseInt(slider.attr('data-timing'), 10): undefined); 2435 ao.accessibility = slider.attr('data-accessibility') === 'false'? false : undefined; 2436 ao.rightToLeft = slider.attr('data-rtl') === 'true'? true : undefined; 2437 ao.initialIndex = slider.attr('data-initial') ? parseInt(slider.attr('data-initial'), 10) : undefined; 2438 ao.freeScroll = slider.attr('data-freescroll') === "true" ? true: undefined; 2439 2440 // Set data attribute to inidicate the number of children in the slider 2441 slider.attr('data-children',childnum); 2442 2443 2444 $(this).data('sliderOptions', jQuery.extend({}, themeDefaults, mr.sliders.options, ao)); 2445 2446 $(sliderInitializer).flickity($(this).data('sliderOptions')); 2447 2448 $(sliderInitializer).on( 'scroll.flickity', function( event, progress ) { 2449 if(slider.find('.is-selected').hasClass('controls--dark')){ 2450 slider.addClass('controls--dark'); 2451 }else{ 2452 slider.removeClass('controls--dark'); 2453 } 2454 }); 2455 }); 2456 2457 if(mr.parallax.update){ mr.parallax.update(); } 2458 2459 }; 2460 2461 mr.components.documentReadyDeferred.push(mr.sliders.documentReady); 2462 return mr; 2463 2464}(mr, jQuery, window, document)); 2465 2466//////////////// Smoothscroll 2467mr = (function (mr, $, window, document){ 2468 "use strict"; 2469 2470 mr.smoothscroll = mr.smoothscroll || {}; 2471 mr.smoothscroll.sections = []; 2472 2473 mr.smoothscroll.init = function(){ 2474 mr.smoothscroll.sections = []; 2475 2476 2477 2478 $('a.inner-link').each(function(){ 2479 var sectionObject = {}, 2480 link = $(this), 2481 href = link.attr('href'), 2482 validLink = new RegExp('^#[^\r\n\t\f\v\#\.]+$','gm'); 2483 2484 if(validLink.test(href)){ 2485 2486 if($('section'+href).length){ 2487 2488 sectionObject.id = href; 2489 sectionObject.top = Math.round($(href).offset().top); 2490 sectionObject.height = Math.round($(href).outerHeight()); 2491 sectionObject.link = link.get(0); 2492 sectionObject.active = false; 2493 2494 mr.smoothscroll.sections.push(sectionObject); 2495 } 2496 } 2497 }); 2498 2499 mr.smoothscroll.highlight(); 2500 }; 2501 2502 mr.smoothscroll.highlight = function(){ 2503 mr.smoothscroll.sections.forEach(function(section){ 2504 if(mr.scroll.y >= section.top && mr.scroll.y < (section.top + section.height)){ 2505 if(section.active === false){ 2506 section.link.classList.add("inner-link--active"); 2507 section.active = true; 2508 } 2509 }else{ 2510 section.link.classList.remove("inner-link--active"); 2511 section.active = false; 2512 } 2513 }); 2514 }; 2515 2516 mr.scroll.listeners.push(mr.smoothscroll.highlight); 2517 2518 mr.smoothscroll.documentReady = function($){ 2519 // Smooth scroll to inner links 2520 var innerLinks = $('a.inner-link'), offset, themeDefaults, ao = {}; 2521 2522 themeDefaults = { 2523 selector: '.inner-link', 2524 selectorHeader: null, 2525 speed: 750, 2526 easing: 'easeInOutCubic', 2527 offset: 0 2528 }; 2529 2530 if(innerLinks.length){ 2531 innerLinks.each(function(index){ 2532 var link = $(this), 2533 href = link.attr('href'); 2534 if(href.charAt(0) !== "#"){ 2535 link.removeClass('inner-link'); 2536 } 2537 }); 2538 2539 mr.smoothscroll.init(); 2540 $(window).on('resize', mr.smoothscroll.init); 2541 2542 offset = 0; 2543 if($('body[data-smooth-scroll-offset]').length){ 2544 offset = $('body').attr('data-smooth-scroll-offset'); 2545 offset = offset*1; 2546 } 2547 2548 ao.offset = offset !== 0 ? offset: undefined; 2549 2550 smoothScroll.init(jQuery.extend({}, themeDefaults, mr.smoothscroll.options, ao)); 2551 } 2552 }; 2553 2554 mr.components.documentReady.push(mr.smoothscroll.documentReady); 2555 mr.components.windowLoad.push(mr.smoothscroll.init); 2556 return mr; 2557 2558}(mr, jQuery, window, document)); 2559
2560//////////////// Tabs 2561mr = (function (mr, $, window, document){ 2562 "use strict"; 2563 2564 mr.tabs = mr.tabs || {}; 2565 2566 mr.tabs.documentReady = function($){ 2567 $('.tabs').each(function(){ 2568 var tabs = $(this); 2569 tabs.after('<ul class="tabs-content">'); 2570 tabs.find('li').each(function(){ 2571 var currentTab = $(this), 2572 tabContent = currentTab.find('.tab__content').wrap('<li></li>').parent(), 2573 tabContentClone = tabContent.clone(true,true); 2574 tabContent.remove(); 2575 currentTab.closest('.tabs-container').find('.tabs-content').append(tabContentClone); 2576 }); 2577 }); 2578 2579 $('.tabs > li').on('click', function(){ 2580 var clickedTab = $(this), hash; 2581 mr.tabs.activateTab(clickedTab); 2582 2583 // Update the URL bar if the currently clicked tab has an ID 2584 if(clickedTab.is('[id]')){ 2585 // Create the hash from the tab's ID 2586 hash = '#'+ clickedTab.attr('id'); 2587 // Check we are in a newish browser with the history API 2588 if(history.pushState) { 2589 history.pushState(null, null, hash); 2590 } 2591 else { 2592 location.hash = hash; 2593 } 2594 } 2595 }); 2596 2597 $('.tabs li.active').each(function(){ 2598 mr.tabs.activateTab(this); 2599 }); 2600 2601 if(window.location.hash !== ''){ 2602 mr.tabs.activateTabById(window.location.hash); 2603 } 2604 2605 $('a[href^="#"]').on('click', function(){ 2606 mr.tabs.activateTabById($(this).attr('href')); 2607 }); 2608 2609 }; 2610 2611 mr.tabs.activateTab = function(tab){ 2612 var clickedTab = $(tab), 2613 tabContainer = clickedTab.closest('.tabs-container'), 2614 activeIndex = (clickedTab.index()*1)+(1), 2615 activeContent = tabContainer.find('> .tabs-content > li:nth-of-type('+activeIndex+')'), 2616 openEvent = document.createEvent('Event'), 2617 iframe, radial; 2618 2619 openEvent.initEvent('tabOpened.tabs.mr', true, true); 2620 2621 2622 tabContainer.find('> .tabs > li').removeClass('active'); 2623 tabContainer.find('> .tabs-content > li').removeClass('active'); 2624 2625 clickedTab.addClass('active').trigger('tabOpened.tabs.mr').get(0).dispatchEvent(openEvent); 2626 activeContent.addClass('active'); 2627 2628 2629 2630 // If there is an <iframe> element in the tab, reload its content when the tab is made active. 2631 iframe = activeContent.find('iframe'); 2632 if(iframe.length){ 2633 iframe.attr('src', iframe.attr('src')); 2634 } 2635 }; 2636 2637 2638 2639 mr.tabs.activateTabById = function(id){ 2640 if(id !== '' && id !== '#' && id.match(/#\/.*/) === null){ 2641 if($('.tabs > li#'+id.replace('#', '')).length){ 2642 $('.tabs > li#'+id.replace('#', '')).click(); 2643 } 2644 } 2645 }; 2646 2647 mr.components.documentReady.push(mr.tabs.documentReady); 2648 return mr; 2649 2650}(mr, jQuery, window, document)); 2651 2652//////////////// Toggle Class 2653mr = (function (mr, $, window, document){ 2654 "use strict"; 2655 2656 mr.toggleClass = mr.toggleClass || {}; 2657 2658 mr.toggleClass.documentReady = function($){ 2659 $('[data-toggle-class]').each(function(){ 2660 var element = $(this), 2661 data = element.attr('data-toggle-class').split("|"); 2662 2663 2664 $(data).each(function(){ 2665 var candidate = element, 2666 dataArray = [], 2667 toggleClass = '', 2668 toggleElement = '', 2669 dataArray = this.split(";"); 2670 2671 if(dataArray.length === 2){ 2672 toggleElement = dataArray[0]; 2673 toggleClass = dataArray[1]; 2674 $(candidate).on('click',function(){ 2675 if(!candidate.hasClass('toggled-class')){ 2676 candidate.toggleClass('toggled-class'); 2677 }else{ 2678 candidate.removeClass('toggled-class'); 2679 } 2680 $(toggleElement).toggleClass(toggleClass); 2681 return false; 2682 }); 2683 }else{ 2684 console.log('Error in [data-toggle-class] attribute. This attribute accepts an element, or comma separated elements terminated witha ";" followed by a class name to toggle'); 2685 } 2686 }); 2687 }); 2688 }; 2689 2690 mr.components.documentReady.push(mr.toggleClass.documentReady); 2691 return mr; 2692 2693}(mr, jQuery, window, document)); 2694
2695//////////////// Typed Headline Effect 2696mr = (function (mr, $, window, document){ 2697 "use strict"; 2698 2699 mr.typed = mr.typed || {}; 2700 2701 2702 mr.typed.documentReady = function($){ 2703 $('.typed-text').each(function(){ 2704 var text = $(this); 2705 var strings = text.attr("data-typed-strings") ? text.attr("data-typed-strings").split(",") : [], 2706 themeDefaults = { 2707 strings: [], 2708 typeSpeed: 100, 2709 loop: true, 2710 showCursor: false 2711 }, ao = {}; 2712 2713 ao.strings = text.attr("data-typed-strings") ? text.attr("data-typed-strings").split(",") : undefined; 2714 2715 $(text).typed(jQuery.extend({}, themeDefaults, mr.typed.options, ao)); 2716 2717 }); 2718 }; 2719 2720 mr.components.documentReady.push(mr.typed.documentReady); 2721 return mr; 2722 2723}(mr, jQuery, window, document)); 2724 2725 2726//////////////// Video 2727mr = (function (mr, $, window, document){ 2728 "use strict"; 2729 2730 mr.video = mr.video || {}; 2731 mr.video.options = mr.video.options || {}; 2732 mr.video.options.ytplayer = mr.video.options.ytplayer || {}; 2733 2734 mr.video.documentReady = function($){ 2735
2736 //////////////// Youtube Background 2737 2738 if($('.youtube-background').length){ 2739 $('.youtube-background').each(function(){ 2740 2741 2742 var player = $(this), 2743 2744 themeDefaults = { 2745 containment: "self", 2746 autoPlay: true, 2747 mute: true, 2748 opacity: 1 2749 }, ao = {}; 2750 2751 // Attribute overrides - provides overrides to the global options on a per-video basis 2752 ao.videoURL = $(this).attr('data-video-url'); 2753 ao.startAt = $(this).attr('data-start-at')? parseInt($(this).attr('data-start-at'), 10): undefined; 2754 2755 2756 player.closest('.videobg').append('<div class="loading-indicator"></div>'); 2757 player.YTPlayer(jQuery.extend({}, themeDefaults, mr.video.options.ytplayer, ao)); 2758 player.on("YTPStart",function(){ 2759 player.closest('.videobg').addClass('video-active'); 2760 }); 2761 2762 }); 2763 } 2764 2765 if($('.videobg').find('video').length){ 2766 $('.videobg').find('video').closest('.videobg').addClass('video-active'); 2767 } 2768
2769 //////////////// Video Cover Play Icons 2770 2771 $('.video-cover').each(function(){ 2772 var videoCover = $(this); 2773 if(videoCover.find('iframe[src]').length){ 2774 videoCover.find('iframe').attr('data-src', videoCover.find('iframe').attr('src')); 2775 videoCover.find('iframe').attr('src',''); 2776 } 2777 }); 2778 2779 $('.video-cover .video-play-icon').on("click", function(){ 2780 var playIcon = $(this); 2781 var videoCover = playIcon.closest('.video-cover'); 2782 if(videoCover.find('video').length){ 2783 var video = videoCover.find('video').get(0); 2784 videoCover.addClass('reveal-video'); 2785 video.play(); 2786 return false; 2787 }else if(videoCover.find('iframe').length){ 2788 var iframe = videoCover.find('iframe'); 2789 iframe.attr('src',iframe.attr('data-src')); 2790 videoCover.addClass('reveal-video'); 2791 return false; 2792 } 2793 }); 2794 }; 2795 2796 mr.components.documentReady.push(mr.video.documentReady); 2797 return mr; 2798 2799}(mr, jQuery, window, document)); 2800 2801//////////////// Wizard 2802mr = (function (mr, $, window, document){ 2803 "use strict"; 2804 2805 mr.wizard = mr.wizard || {}; 2806 2807 mr.wizard.documentReady = function($){ 2808 2809 $('.wizard').each(function(){ 2810 var wizard = jQuery(this), themeDefaults = {}; 2811 2812 themeDefaults = { 2813 headerTag: "h5", 2814 bodyTag: "section", 2815 transitionEffect: "slideLeft", 2816 autoFocus: true 2817 } 2818 2819 2820 if(!wizard.is('[role="application"][id^="steps-uid"]')){ 2821 wizard.steps(jQuery.extend({}, themeDefaults, mr.wizard.options)); 2822 2823 wizard.addClass('active'); 2824 } 2825 2826 }); 2827 }; 2828 2829 mr.components.documentReady.push(mr.wizard.documentReady); 2830 return mr; 2831 2832}(mr, jQuery, window, document));
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.