var FE={};
jQuery(function(){
"use strict";
homebrew.Carousel.prototype.options.transitions.enable=Modernizr.csstransitions;
homebrew.Tooltip.prototype.options.appendTo='#mainContent';
homebrew.Tooltip.prototype.options.transitions.enable=Modernizr.csstransitions;
jQuery.extend(FE, {
$els:{
backToTop:jQuery('#globalBackToTop'),
body:jQuery('body'),
mainSite:jQuery('#mainSite'),
pageOverlay:jQuery('#pageOverlay'),
root:jQuery('html')
},
events: {
transitionEnd:homebrew.events.transitionEnd||'transitionend oTransitionEnd otransitionend webkitTransitionEnd msTransitionEnd',
animationEnd: homebrew.events.animationEnd||'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd'
},
browser:homebrew.browser,
baseURL:(typeof fileUrl==='string')
? fileUrl
: (window.location.href.indexOf('') > -1)
? ''
: ''
});
if(!FE.$els.pageOverlay.length){
FE.$els.pageOverlay=jQuery('<div class="page-overlay" id="pageOverlay" />').appendTo(FE.$els.mainSite);
}
if(!FE.$els.backToTop.length){
FE.$els.backToTop=jQuery('<a href="#top" title="Back To Top" class="main-back-to-top" id="mainBackToTop" />').appendTo('#mainContent');
FE.$els.backToTop.on('click', function(e){
e.preventDefault();
jQuery('html, body').animate({
scrollTop:0
}, 400);
});
jQuery(window).on('scroll.toggleBackToTop', homebrew.utils.throttle(function(){
FE.$els.backToTop.toggleClass('is-shown', jQuery(window).scrollTop() > jQuery(window).height()*0.5);
}, 50));
}
if(typeof FE.browser==='undefined'){
FE.browser={
ie:FE.$els.root.hasClass('ie'),
ie9:FE.$els.root.hasClass('ie9'),
lt9:FE.$els.root.hasClass('lt9'),
ie8:FE.$els.root.hasClass('ie8'),
lt8:FE.$els.root.hasClass('lt8'),
ie7:FE.$els.root.hasClass('ie7'),
firefox:(window.mozIndexedDB!==undefined)
}}
jQuery.extend(true, FE, {
alert:function(args){
this.showAlertPopup(args, 'alert');
},
confirm:function(args){
this.showAlertPopup(args, 'confirm');
},
showAlertPopup:function(args, method){
args=args||{};
var $popup=jQuery('#FE__alertPopup');
if(!$popup.length){
$popup=jQuery([
'<div class="ssf-popup text-center" id="FE__alertPopup">',
'<h2 class="title space-bottom-2x" />',
'<div class="popup-message" />',
'<div class="space-top-2x">',
'<a href="#/" class="button padded xlarge okay-button">Okay</a>',
'<a href="#/" class="button padded xlarge space-left cancel-button" style="display: none;">Cancel</a>',
'</div>',
'</div>'
].join('')).appendTo('body');
$popup.popupify({
addCloseBtns:false,
closeOnOverlay:false
});
}
if(jQuery('body').hasClass('popup-is-shown')
&& $popup.hasClass('is-shown')){
return;
}
var $title=$popup.find('.title'),
$message=$popup.find('.popup-message'),
$prevPopup=jQuery('.popup-is-shown').find('.ssf-popup.is-shown');
if(args.title) $title.html(args.title);
if(args.message) $message.html(args.message);
$popup.find('.cancel-button').toggle(method==='confirm');
$popup.find('.okay-button, .cancel-button')
.off('.alert')
.on('click.alert', function(){
if($prevPopup.length
&& typeof $prevPopup.eq(0).data('popupify')!=='undefined'){
$prevPopup.data('popupify').reveal();
}else{
$popup.data('popupify').conceal();
}
if(typeof args.onConfirm==='function'){
if(method==='confirm'){
args.onConfirm(jQuery(this).is('.okay-button'));
}else{
args.onConfirm();
}}
});
$popup.data('popupify').reveal();
},
FootnoteAnchor:function(){
this.init.apply(this, arguments);
},
Hasher:function(options){
this.options=options;
},
HeightSlider:function(heightSlider){
if(typeof heightSlider==='string') heightSlider=jQuery(heightSlider);
var self=this;
jQuery.extend(self, {
reveal:function(){
if(Modernizr.csstransitions){
if(heightSlider.height()!==0) return;
var targetHeight=0;
heightSlider.css('height', 'auto');
targetHeight=heightSlider.height();
heightSlider.css('height', '');
setTimeout(function(){
heightSlider
.off(FE.events.transitionEnd)
.on(FE.events.transitionEnd, function(){
heightSlider
.off(FE.events.transitionEnd)
.removeClass('is-transitionable')
.css('height', '')
.addClass('is-toggled');
})
.addClass('is-transitionable')
.css('height', targetHeight + 'px');
}, 1);
}else{
if(heightSlider.css('display')!=='none') return;
heightSlider.slideDown(400, function(){
jQuery(this).addClass('is-toggled');
});
}},
conceal:function(){
if(Modernizr.csstransitions){
if(heightSlider.height()===0) return;
heightSlider
.css('height', heightSlider.height() + 'px')
.removeClass('is-toggled');
setTimeout(function(){
heightSlider
.off(FE.events.transitionEnd)
.on(FE.events.transitionEnd, function(){
heightSlider.off(FE.events.transitionEnd);
heightSlider.removeClass('is-transitionable');
heightSlider.css('height', '');
})
.addClass('is-transitionable')
.css('height', '0px');
}, 1);
}else{
if(heightSlider.css('display')==='none') return;
heightSlider
.removeClass('is-toggled')
.slideUp(400);
}},
toggle:function(){
if(Modernizr.csstransitions){
heightSlider.trigger((heightSlider.height()===0) ? 'reveal':'conceal');
}else{
heightSlider.trigger((heightSlider.css('display')==='none') ? 'reveal':'conceal');
}}
});
heightSlider.data('height-slider', self);
},
StickyColumn:function(){
this.load.apply(this, arguments);
},
getHash:function(){
var hash=window.location.hash;
if(hash===''||hash.substr(1,1)==='.'){
return '';
}else{
return hash;
}},
getQueryStr: function(str){
var search=window.location.search;
if(!search) return false;
if(search.substr(0,1)==='?'){
search=search.substr(1);
}
var splitSearch=search.split('&');
keyValuePairs={};
splitSearch.map(function(searchStr){
var splitSearchStr=searchStr.split('=');
splitSearchStr=splitSearchStr.map(function(str){
return jQuery.trim(str);
});
keyValuePairs[splitSearchStr[0]]=splitSearchStr[1];
});
if(typeof str==='string'){
return (typeof keyValuePairs[str]==='undefined') ? false:keyValuePairs[str];
}else{
return keyValuePairs;
}},
initContentTabbers:function(){
jQuery('.js-togglerify-tabs').each(function(){
var $this=jQuery(this),
$nestedTabs=$this.find('.js-togglerify-tabs').find('.tab'),
$tabs=$this.find('.tab').not($nestedTabs),
$nestedContents=$this.find('.js-togglerify-tabs').find('.tab-content'),
$contents=$this.find('.tab-content').not($nestedContents);
$tabs
.togglerify('destroy')
.togglerify({
toggledClass: 'current',
selfToggleable: false,
singleActive: true,
content: function(index){
return $contents.eq(index);
}})
.on('afterToggleOn', function(){
jQuery(window).trigger('resize');
})
.on('toggleOff', function(e, $thisTab, $thisContent){
$thisContent.find('.video-holder').find('iframe').each(function(){
this.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
});
});
});
},
initContentShowers:function(){
var types={
TAB: 'tab',
TOGGLER: 'toggler',
NOTES: 'notes'
},
$notesToggler=jQuery('#notesToggler'),
$notesContent=jQuery('#notesContent');
jQuery('.js-show-content').each(function(){
var $this=jQuery(this),
thisHref=$this.attr('href');
if(typeof thisHref!=='string'){
console.log($this);
console.error("No target specified. Set the target's ID as the `href` attribute on the element.");
return
}
var $target=jQuery($this.attr('href'));
if(!$target.length){
console.log($this);
console.error("Target `" + $this.attr('href') + "` does not exist.");
return;
}
var data=$this.data('show-content-options');
if(!data){
console.log($this);
console.error('Options undeclared. Declare the options using the `data-show-content-options` attribute on the element.');
return;
}
var options=(typeof data==='string')
? homebrew.getKeyValuePairsFromString(data)
: {};
if(!options.type){
console.log($this);
console.error('Options declared, but no type specified.');
return;
}
var scrollArgs=[$target];
if(options.smoothScroll!==true){
scrollArgs.push('snap');
}
switch(options.type){
case types.TAB:
$this.on('click', function(e){
e.preventDefault();
var $tabContent=$target.closest('.tab-content'),
$heightSyncers=$tabContent.find('.js-sync-height-wrapper');
if($tabContent.hasClass('current')){
FE.scrollTo.apply(null, scrollArgs);
}else{
if($heightSyncers.length){
$heightSyncers.last().one('afterSync', function(){
FE.scrollTo.apply(null, scrollArgs);
});
$tabContent.data('togglerify').toggleOn();
}else{
$tabContent.data('togglerify').toggleOn();
FE.scrollTo.apply(null, scrollArgs);
}}
});
break;
case types.NOTES:
if(!$notesToggler.length||!$notesContent.length){
return;
}
$this.on('click', function(e){
e.preventDefault();
if(!$notesToggler.hasClass('is-toggled')){
$notesToggler.togglerify('toggleOn', { noSlide:true });
}
FE.scrollTo($target);
});
break;
default:
console.log($this);
var errorMsg=[
'The type `', options.type, '` is not supported. Our currently supported types are: '
];
jQuery.each(types, function(key, value){
errorMsg.push('\n' + value);
});
errorMsg.push('\n\nCheck the type again.');
console.error(errorMsg.join(''));
break;
}});
},
initDropdownSwitchers:function($scope){
var $holders=($scope&&$scope.length)
? $scope.find('.dropdown-switcher-holder')
: jQuery('.dropdown-switcher-holder');
if(!$holders.length) return;
$holders.each(function(){
var $dropdown=jQuery(this).find('.dropdown-switcher'),
$contents=jQuery(this).find('.dropdown-content');
$dropdown
.on('change', function(){
$contents
.hide()
.eq(this.selectedIndex)
.show();
})
.trigger('change');
});
},
initNumberTabbers:function(){
jQuery('.number-tabber').each(function(){
var $tabs=jQuery(this).find('.number-tabber__tabs').children('li'),
$contents=jQuery(this).find('.number-tabber__contents').children('li');
$tabs
.togglerify('destroy')
.togglerify({
toggledClass: 'current',
singleActive: true,
selfToggleable: false,
content: function(index){
return $contents.eq(index);
}});
});
},
initPage:function(){
jQuery('.js-dropdownify').dropdownify();
jQuery('.js-inputify').inputify();
jQuery.each(FE, function(key, value){
if(key.indexOf('init')===0&&key!=='initPage') value();
});
FE.loadXMLForm(jQuery('.js-xml-form-holder'));
FE.loadXMLTable(jQuery('.js-xml-tbl-holder'));
FE.loadXMLLocations(jQuery('.js-xml-locations-holder'));
if(FE.browser.ie) jQuery('[placeholder]').placeholderify();
},
initSectionSnap:function(){
if(!Modernizr.touch) return;
var hash=FE.getHash();
if(!hash||hash.indexOf('#/') > -1) return;
var $hash=jQuery(hash);
if(!$hash.length||!$hash.is('.section')) return;
setTimeout(function(){
FE.scrollTo($hash);
}, 25);
},
initSelfTogglers:function(){
jQuery('.self-toggler__toggler').togglerify({
singleActive: false,
slide: true,
content: function(){
return jQuery(this).next();
}});
},
initSectionContentToggler:function(){
var $sectionContentTogglers=jQuery('.section-content-toggler');
if(!$sectionContentTogglers.length) return;
var $sectionToggleableContents=jQuery('.section-toggleable-content'),
$sectionDropdown=jQuery('<select>'),
optionsStrArray=[];
$sectionContentTogglers
.togglerify({
selfToggleable: false,
singleActive:true,
content:function(index){
return $sectionToggleableContents.eq(index);
}})
.each(function(index){
var $dropdownOption=jQuery(['<option>', jQuery.trim(jQuery(this).find('.toggler__title').text()), '</option>'].join(''));
$dropdownOption.data('section-content-toggler', jQuery(this));
$dropdownOption.appendTo($sectionDropdown);
});
jQuery('<div class="column show-for-small-down" />')
.prepend($sectionDropdown)
.prependTo($sectionContentTogglers.eq(0).closest('.row'));
$sectionDropdown
.dropdownify({
markups:{
holder:'<div class="expand space-bottom" />'
}})
.on('change', function(){
var $thisToggler=jQuery(this).find('option:checked').data('section-content-toggler');
$thisToggler.togglerify('toggleOn');
});
FE.watchSize('small', function(isSmallScreen){
var method=(isSmallScreen) ? 'deactivate':'activate';
$sectionContentTogglers.togglerify(method);
});
},
initSmallNav:function(){
if(Modernizr.touch||jQuery('#mainSmallNav').data('initSmallNav')===true) return;
jQuery('#mainSmallNav').data('initSmallNav', true);
var prevScrollTop=jQuery(window).scrollTop(),
navHeight=jQuery('#mainSmallNav').height() + jQuery('#mainNav').height();
jQuery(window)
.on('resize.navHider', function(){
navHeight=jQuery('#mainSmallNav').height() + jQuery('#mainNav').height();
})
.trigger('resize.navHider')
.on('scroll.navHider', function(){
var currentScrollTop=jQuery(window).scrollTop(),
partialHiddenBool=currentScrollTop > 47,
hiddenBool=currentScrollTop >=prevScrollTop&&currentScrollTop > navHeight&&!FE.$els.body.hasClass('mobile-nav-is-shown');
jQuery('body').toggleClass('main-header-is-partially-hidden', partialHiddenBool);
jQuery('body').toggleClass('main-header-is-hidden', hiddenBool);
prevScrollTop=currentScrollTop;
})
.trigger('scroll.navHider');
},
initSyncHeightWrappers:function($scope){
var $syncHeightWrappers=jQuery('.js-sync-height-wrapper');
if(!$syncHeightWrappers.length) return;
$syncHeightWrappers.each(function(){
var selectors=jQuery(this).data('sync-height-selector');
if(!selectors) return;
var selectorsSplitArray=selectors.split(',');
for(var i=selectorsSplitArray.length-1; i > -1; i--){
selectorsSplitArray[i]=jQuery.trim(selectorsSplitArray[i]);
}
jQuery(this).heightSyncify({
items:selectorsSplitArray
});
});
},
initTooltips:function(){
var $els=jQuery('.icon--question[title], .js-tooltipify');
$els.tooltipify();
},
initQuickLinks:function(){
var $quicklinksToggler=jQuery('#mainNav__quicklinksToggler'),
$quicklinks=jQuery('#mainNav__quicklinks');
if(!$quicklinksToggler.length||!$quicklinks.length) return;
if($quicklinksToggler.data('initQuickLinks')===true) return;
$quicklinksToggler.data('initQuickLinks', true);
var mouseupEv='mouseup.mainNavQuicklinksFauxBlur',
resizeEv='resize.limitQuicklinksHeight';
$quicklinksToggler
.togglerify({
slide: true,
content: function(){
return $quicklinks;
}})
.togglerify('deactivate')
.on({
click:function(e){
e.preventDefault();
var $thisToggler=jQuery(this);
if($thisToggler.hasClass('is-toggled')){
$thisToggler.togglerify('toggleOff');
}else{
var heightLimit=jQuery(window).height() - jQuery('#mainNav').height(),
contentHeight;
$quicklinks.css('height', 'auto');
contentHeight=$quicklinks.height();
$quicklinks.css('height', '');
if(contentHeight >=heightLimit){
$thisToggler.togglerify('toggleOn', { contentHeight:heightLimit });
}else{
$thisToggler.togglerify('toggleOn');
}}
},
toggleOn:function(e, $thisToggler, $target){
jQuery(document).on(mouseupEv, function(e){
var container=$thisToggler.add($target);
if(!container.is(e.target)&&container.has(e.target).length===0){
jQuery(document).off(mouseupEv);
$target.data('togglerify').toggleOff();
}});
jQuery(window).on(resizeEv, function(){
if(!$thisToggler.hasClass('is-toggled')) return;
var heightLimit=jQuery(window).height() - jQuery('#mainNav').height();
$quicklinks.css('height', '');
if($quicklinks.height() >=heightLimit){
$quicklinks.height(heightLimit);
}});
},
toggleOff:function(){
jQuery(document).off(mouseupEv);
jQuery(window).off(resizeEv);
}});
},
loadXMLForm:function($holders){
$holders=jQuery($holders);
if(!$holders.length) return;
$holders.each(function(){
var $thisHolder=jQuery(this);
if(jQuery.data(this, 'loaded-xml-form')===true) return;
var xmlURL=$thisHolder.data('xml-form-url');
if(typeof xmlURL!=='string') return;
jQuery.ajax({
type: 'GET',
url: xmlURL,
dataType: 'xml',
success: function(data){
makeXMLForm(data, $thisHolder);
FE.initFancyPlaceholders($thisHolder);
FE.initInputFocus($thisHolder);
$thisHolder.find('.js-inputify').inputify();
$thisHolder.find('.js-dropdownify').dropdownify();
$thisHolder.data('loaded-xml-form', true);
},
error: function(d){
console.log(d);
}});
});
function makeXMLForm(data, $holder){
var $data=jQuery(data),
$inputs=$data.find('formInput'),
uniqueID=new Date().getTime() + '_' + Math.round(Math.random()*10000),
$xmlForm=jQuery([
'<form action="https://docs.google.com/forms/d/', getText($data.find('formID')), '/formResponse"',
'target="hiddenIframe_', uniqueID, '"',
'method="post" class="xml-form-asset xml-form-contents" />'
].join('')).prependTo($holder),
xmlFormStrArray=[];
xmlFormStrArray.push([
'<div class="row collapse   space-bottom medium-space-bottom-2x">',
makeTitle($data.find('formTitle')),
'</div>'
].join(''));
$inputs.each(function(index){
var $thisInput=jQuery(this),
uniqueInputID=new Date().getTime() + '_' + index,
name=getText($thisInput.find('name')),
label=getText($thisInput.find('label')),
type=getText($thisInput.find('type')).toLowerCase(),
required=getText($thisInput.find('required')).toLowerCase(),
pattern=getText($thisInput.find('pattern')),
tooltip=getText($thisInput.find('tooltip'));
switch(type){
case 'text':
case 'number':
case 'email':
case 'textarea':
var validifyStrArray=['response: #response_' + uniqueInputID],
floaterStrArray=[];
if(!pattern){
if(type==='number'){
validifyStrArray.unshift('pattern: numbers');
}else if(type==='email'){
validifyStrArray.unshift('pattern: email');
}}
if(required==='yes'){
validifyStrArray.unshift('required: true');
}
validifyStrArray.push('floater: #floater_roi_' + uniqueInputID);
floaterStrArray.push('<div class="validify-floater" id="floater_roi_', uniqueInputID, '">');
if(required==='yes'){
floaterStrArray.push([
'<span class="validify-floater__message validify-floater__message--failed-required">',
'This input is required.',
'</span>'
].join(''));
}
var errorMessage=getText($thisInput.find('errorMessage'));
if(type==='number'){
errorMessage='This input should consist of numbers only.'
}else if(type==='email'){
errorMessage='The address should be in this format: username@youremail.com'
}else if(!errorMessage){
errorMessage='Invalid input.'
}
floaterStrArray.push([
'<span class="validify-floater__message validify-floater__message--failed-pattern">',
errorMessage,
'</span>'
].join(''));
floaterStrArray.push('</div>');
var elementStr;
if(type==='textarea'){
elementStr=[
'<textarea'
];
}else{
elementStr=[
'<input',
' type="', (type==='email') ? 'email':'text', '"'
];
}
elementStr.push(' data-validify="', validifyStrArray.join(', '), '"',
(pattern)
? ' data-validify-pattern="' + pattern + '"'
: '',
' name="', name, '"',
' class="field expand"',
' id="roi_', uniqueInputID ,'"',
(type==='textarea')
? '></textarea>'
: ' />'
);
xmlFormStrArray.push([
'<div class="form-obj', (tooltip) ? ' form-obj--with-tooltip':'', '">',
'<div class="field-holder expand">',
elementStr.join(''),
'<label for="roi_', uniqueInputID, '" class="field-holder__label">',
label, (required==='yes') ? '<span class="text-red">*</span>':'',
'</label>',
'</div>',
'<span class="validify-responses  form-obj__icon" id="response_', uniqueInputID, '">',
'<span class="validify-response validify-response--success">',
'<i class="icon icon--success-tick"></i>',
'</span>',
'</span>',
(tooltip)
? '<i title="' + tooltip + '" class="icon icon--question round-circle   form-obj__icon"></i>'
: '',
floaterStrArray.join(''),
'</div>'
].join(''));
break;
case 'dropdown':
var validifyStrArray=['response: #response_' + uniqueInputID],
floaterStr='';
if(required==='yes'){
validifyStrArray.unshift('required: true');
validifyStrArray.push('floater: #floater_roi_' + uniqueInputID);
floaterStr=[
'<div class="validify-floater" id="floater_roi_', uniqueInputID, '">',
'<span class="validify-floater__message validify-floater__message--failed-required">',
'This input is required.',
'</span>',
'</div>'
].join('');
}
var optionsArray=getText($thisInput.find('options')).split('\n'),
options=[];
while(optionsArray.length){
options.push([
'<option value="', optionsArray[0], '">',
optionsArray[0],
'</option>'
].join(''));
optionsArray.shift();
}
xmlFormStrArray.push([
'<div class="form-obj', (tooltip) ? ' form-obj--with-tooltip':'', '">',
'<span class="expand js-dropdownify">',
'<select data-validify="', validifyStrArray.join(', '), '" name="', name, '">',
'<option value="">', label, (required==='yes') ? '*':'', '</option>',
options.join(''),
'</select>',
'</span>',
'<span class="validify-responses  form-obj__icon" id="response_', uniqueInputID, '">',
'<span class="validify-response validify-response--success">',
'<i class="icon icon--success-tick"></i>',
'</span>',
'</span>',
(tooltip)
? '<i title="' + tooltip + '" class="icon icon--question round-circle   form-obj__icon"></i>'
: '',
floaterStr,
'</div>'
].join(''));
break;
case 'radio':
case 'checkbox':
var validifyStrArray=['groupResponse: #response_' + uniqueInputID],
validifyRequiredStr='';
if(required==='yes'){
validifyStrArray.unshift('required: true');
validifyRequiredStr=[
'<span class="validify-response validify-response--failed-required">',
'<br />This input is required.',
'</span>'
].join('');
}
var optionsArray=getText($thisInput.find('options')).split('\n'),
optionsLabelsArray=getText($thisInput.find('optionsLabels')).split('\n'),
options=[],
currentOption;
for(var i=0, ii=optionsArray.length; i < ii; i++){
if(optionsArray[i]==='__other_option__'){
}else{
options.push([
'<label>',
'<input type="', type, '" name="', name, '" data-validify value="', optionsArray[i], '" class="js-inputify" /> ',
(typeof optionsLabelsArray[i]==='string'
&& optionsLabelsArray[i])
? optionsLabelsArray[i]
: optionsArray[i],
'</label>'
].join(''));
}}
xmlFormStrArray.push([
'<div class="form-obj" data-validify-group="', validifyStrArray.join(', '), '">',
'<p class="form-obj__label">',
label, (required==='yes') ? '<span class="text-red">*</span>':'',
(tooltip)
? ' <i title="' + tooltip + '" class="icon icon--question round-circle"></i>'
: '',
' <span class="validify-responses" id="response_', uniqueInputID, '">',
'<span class="validify-response validify-response--success">',
'<i class="icon icon--success-tick"></i>',
'</span>',
validifyRequiredStr,
'</span>',
'</p>',
options.join(''),
'</div>'
].join(''));
break;
}});
xmlFormStrArray.push([
'<div class="text-center space-top medium-space-top-2x">',
'<input type="submit" value="Submit" class="button padded xlarge" />',
'</div>'
].join(''));
$xmlForm.append(xmlFormStrArray.join(''));
$xmlForm.find('.icon--question[title]').tooltipify();
var $hiddenIframe=jQuery('<iframe data-submitted="false" name="hiddenIframe_' + uniqueID + '" style="display: none;" />').appendTo($xmlForm);
$hiddenIframe.on('load', function(){
if(jQuery(this).data('submitted')!==true) return;
$xmlForm.addClass('is-hidden');
$holder.find('.xml-form-thanks').addClass('is-shown');
FE.scrollTo($holder.find('.xml-form-thanks'));
});
$xmlForm.validify().on('submit', function(e){
var validifyData=jQuery.data(this, 'validify');
validifyData.set('strict', true).validate();
if(validifyData.valid!==true){
var $errorInput=jQuery(this).find('.is-failed').eq(0);
FE.scrollTo($errorInput, function(){
$errorInput.focus().select();
});
e.preventDefault();
}else{
$hiddenIframe.data('submitted', true);
$xmlForm.find('input[type="submit"]').addClass('is-loading').prop('disabled', true);
}});
}
function getText($node){
return ($node.length) ? jQuery.trim($node.text()):'';
}
function makeTitle($title){
var title=getText($title);
if(title){
return [
'<div class="large-6 column">',
'<h3>', title, '</h3>',
'</div>',
'<div class="large-6 column   medium-down-pad-vertical large-text-right align-to-h3 text-dark-grey">',
'<span class="text-red">*</span> Please fill in the mandatory fields.',
'</div>'
].join('');
}else{
return [
'<div class="column   medium-down-pad-vertical large-text-right text-dark-grey">',
'<span class="text-red">*</span> Please fill in the mandatory fields.',
'</div>'
].join('');
}}
},
loadXMLTable:function($holders){
$holders=jQuery($holders);
if(!$holders.length) return;
var worksheets={},
xmlSerializer=new XMLSerializer();
$holders.each(function(){
var $thisHolder=jQuery(this);
if($thisHolder.data('loaded-xml-table')===true) return;
var xmlURL=$thisHolder.data('xml-table-url');
if(typeof xmlURL!=='string') return;
jQuery.ajax({
type: 'GET',
url: xmlURL,
dataType: 'xml',
success: function(data){
var xmlStyles=getXMLStyles(data);
makeXMLTable(data, xmlStyles, $thisHolder);
attachRowHoverers();
$thisHolder.data('loaded-xml-table', true);
},
error: function(d){
console.log(d);
}});
});
function makeXMLTable(data, xmlStyles, $holder){
var $data=jQuery(data),
$worksheets=$data.find('Worksheet'),
dropdown={},
finalTableStrArr=[];
worksheets={};
$worksheets.each(function(){
var $thisWorksheet=jQuery(this),
thisWorksheetName=$thisWorksheet.attr('ss:Name').toLowerCase();
if(thisWorksheetName.indexOf('dropdown')===0){
$thisWorksheet.find('Data').each(function(){
var $Data=jQuery(this),
DataIndex=$Data.index(),
DataText=jQuery(this).text().toLowerCase();
switch(DataText){
case 'dropdown label':
dropdown.__label=jQuery(this).closest('Row').next('Row').find('Data').text();
break;
case 'option label':
jQuery(this).closest('Row').nextUntil().each(function(){
var optionLabelText=jQuery(this).find('Data').eq(DataIndex).text();
if(optionLabelText==='') return;
dropdown[jQuery(this).find('Data').eq(DataIndex).text()]=jQuery(this).find('Data').eq(DataIndex+1).text().toLowerCase();
});
break;
}});
}else{
worksheets[thisWorksheetName]=$thisWorksheet;
}});
if(jQuery.isEmptyObject(dropdown)){
var worksheetNames=[];
jQuery.each(worksheets, function(key, value){
worksheetNames.push(key);
});
finalTableStrArr.push(iterateWorksheetsArray(worksheetNames, xmlStyles));
}else{
var dropdownOptionsArray=[],
dropdownContentsArray=[];
jQuery.each(dropdown, function(key, value){
if(key==='__label') return;
dropdownOptionsArray.push(key);
var dropdownWorksheets={},
valueSplitArray=value.split('\n');
if(valueSplitArray.length===1){
valueSplitArray=valueSplitArray[0].split(',');
}
for(var i=valueSplitArray.length-1; i > -1; i--){
valueSplitArray[i]=jQuery.trim(valueSplitArray[i]);
}
dropdownContentsArray.push(iterateWorksheetsArray(valueSplitArray, xmlStyles));
});
var dropdownOptionsStrArray=[],
dropdownContentsStrArray=[];
while(dropdownOptionsArray.length){
dropdownOptionsStrArray.push([
'<option>', dropdownOptionsArray.shift(), '</option>'
].join(''));
}
while(dropdownContentsArray.length){
dropdownContentsStrArray.push([
'<div class="dropdown-content">',
dropdownContentsArray.shift(),
'</div>'
].join(''));
}
finalTableStrArr.push([
'<div class="dropdown-switcher-holder">',
'<div class="text-center text-large">',
dropdown.__label,
'<span class="js-dropdownify tbl-dropdown">',
'<select class="dropdown-switcher">',
dropdownOptionsStrArray.join(''),
'</select>',
'</span>',
'</div>',
'<div class="dropdown-contents-holder">',
dropdownContentsStrArray.join(''),
'</div>',
'</div>'
].join(''));
}
$holder.append(finalTableStrArr.join(''));
FE.initFootnotes($holder);
if(!$holder.find('.js-dropdownify').length) return;
$holder.find('.js-dropdownify').dropdownify();
FE.initDropdownSwitchers($holder);
}
function iterateWorksheetsArray(worksheetNames, xmlStyles){
var worksheetStrArr=[],
currentWorksheetName,
mediaClass;
while(worksheetNames.length){
currentWorksheetName=worksheetNames.shift();
if(typeof worksheets[currentWorksheetName]==='undefined'){
console.error("FE.loadXMLTable(): Can't find the worksheet '" + currentWorksheetName + "'");
continue;
}
if(currentWorksheetName.indexOf('desktop')===0){
mediaClass='show-for-large-up';
}else if(currentWorksheetName.indexOf('tabletup')===0){
mediaClass='show-for-medium-up';
}else if(currentWorksheetName.indexOf('tabletonly')===0){
mediaClass='show-for-medium-only';
}else if(currentWorksheetName.indexOf('tabletdown')===0){
mediaClass='show-for-medium-down';
}else if(currentWorksheetName.indexOf('mobile')===0){
mediaClass='show-for-small-down';
}
worksheetStrArr.push([
'<div class="tbl-holder', (typeof mediaClass==='string') ? ' ' + mediaClass:'', '">'
].join(''));
worksheetStrArr.push(makeTableString(worksheets[currentWorksheetName], xmlStyles));
worksheetStrArr.push('</div>');
}
return (worksheetStrArr.length) ? worksheetStrArr.join(''):false;
}
function getColumnCount($worksheet){
var $worksheetRows=$worksheet.find('Row'),
_columnCount=[];
$worksheetRows.each(function(){
var $cells=jQuery(this).find('Cell');
$cells.each(function(){
if(!jQuery(this).text()){
$cells=$cells.not(jQuery(this));
}});
_columnCount.push($cells.length);
});
return Math.max.apply(null, _columnCount);
}
function getXMLStyles(data){
var $styles=jQuery(data).find('Style'),
styleObj={};
$styles.each(function(){
var $thisStyle=jQuery(this),
$alignment=$thisStyle.find('Alignment'),
$interior=$thisStyle.find('Interior'),
$numberFormat=$thisStyle.find('NumberFormat'),
$font=$thisStyle.find('Font'),
thisStyleObj={};
if($alignment.length&&hasAttributes($alignment, ['ss:Horizontal', 'ss:Vertical'])){
var verticalAlignment, horizontalAlignment;
switch($alignment.attr('ss:Vertical')){
case 'Top':verticalAlignment='top'; break;
case 'Center':verticalAlignment='middle'; break;
case 'Bottom':verticalAlignment='bottom'; break;
}
switch($alignment.attr('ss:Horizontal')){
case 'Top':horizontalAlignment='top'; break;
case 'Center':horizontalAlignment='center'; break;
case 'Bottom':horizontalAlignment='bottom'; break;
}
thisStyleObj.alignment={
'vertical':verticalAlignment,
'horizontal':horizontalAlignment
};}
if($interior.length&&hasAttributes($interior, ['ss:Color'])){
thisStyleObj.bgColor=$interior.attr('ss:Color');
}
if($font.length&&hasAttributes($font, ['ss:Italic', 'ss:Bold', 'ss:Underline', 'ss:Color', 'ss:Size'])){
thisStyleObj.font={
'italic':$font.attr('ss:Italic'),
'bold':$font.attr('ss:Bold'),
'underline':$font.attr('ss:Underline'),
'color':$font.attr('ss:Color'),
'size':$font.attr('ss:Size')
};}
if($numberFormat.length&&hasAttributes($numberFormat, ['ss:Format'])){
thisStyleObj.numberFormat=$numberFormat.attr('ss:Format');
}
styleObj[$thisStyle.attr('ss:ID')]=thisStyleObj;
});
return styleObj;
}
function makeTableString($worksheet, xmlStyles){
var $rows=filterOutEmptyRows($worksheet.find('Row'));
if(!$rows.length) return '';
var totalColumns=parseInt(getColumnCount($worksheet), 10),
totalRows=$rows.length,
i, ii, j, jj,
tableLayout=[];
for(i=$rows.length-1; i >-1; i--){
tableLayout.push(new Array(totalColumns));
}
$rows.each(function(rowIndex){
var cellCount=0;
jQuery(this).find('Cell').each(function(cellIndex){
if(cellCount >=totalColumns) return;
var $thisCell=jQuery(this),
cellMergeDown=parseInt($thisCell.attr('ss:MergeDown'), 10)||0,
cellMergeAcross=parseInt($thisCell.attr('ss:MergeAcross'), 10)||0;
while(typeof tableLayout[rowIndex][cellCount]==='number'){
cellCount++;
}
tableLayout[rowIndex][cellCount]=$thisCell;
if(cellMergeAcross){
for(i=cellCount, ii=cellCount+cellMergeAcross; i < ii; i++){
tableLayout[rowIndex][i+1]=0;
}
cellCount +=cellMergeAcross;
}
if(cellMergeDown){
for(i=rowIndex+1, ii=rowIndex+cellMergeDown; i <=ii; i++){
tableLayout[i][cellCount]=0;
if(cellMergeAcross){
for(j=cellCount+1, jj=cellCount+cellMergeAcross; j <=jj; j++){
tableLayout[i][j]=0;
}}
}}
cellCount++;
});
});
var tableStrArr=[],
tableStyleID=$worksheet.find('Table').attr('ss:StyleID'),
defaultStyle=(xmlStyles[tableStyleID]) ? xmlStyles[tableStyleID]:{};
tableStrArr.push('<table class="default-tbl">');
var cellStrArr, cellArray, cell, k, kk;
while(tableLayout.length){
cellStrArr=[];
cellArray=tableLayout.shift();
for(k=0, kk=cellArray.length; k < kk; k++){
if(typeof cellArray[k]==='undefined'){
cellStrArr.push('<td></td>');
}else if(typeof cellArray[k]==='object'){
cellStrArr.push(makeCellString(cellArray[k], k));
}}
if(cellStrArr.length){
cellStrArr.unshift('<tr>');
cellStrArr.push('</tr>');
tableStrArr.push(cellStrArr.join(''));
}}
tableStrArr.push('</table>');
return tableStrArr.join('');
function makeCellString($cell, cellIndex, log){
var $thisCell=$cell,
cellContent=$thisCell.text();
if(cellContent===''){
if(cellIndex % 2===1){
return '<td class="alt"></td>';
}else{
return '<td></td>';
}}
var cellStyle=jQuery.extend({}, defaultStyle),
cellData=$thisCell.find('Data'),
cellDataType=cellData.attr('ss:Type');
if(cellDataType==='Number'){
var decimalSplit=cellContent.split('.');
if(decimalSplit.length > 1&&decimalSplit[1].length > 2){
cellContent=parseFloat(cellContent, 10).toFixed(2);
}}
if(xmlStyles[$thisCell.attr('ss:StyleID')]){
jQuery.extend(cellStyle, xmlStyles[$thisCell.attr('ss:StyleID')]);
}
var cellNumberFormat=cellStyle.numberFormat,
cellMergeDown=parseInt($thisCell.attr('ss:MergeDown'), 10)||0,
cellMergeAcross=parseInt($thisCell.attr('ss:MergeAcross'), 10)||0,
cellSSData=$thisCell.children('ss\\:Data'),
cellInlineTags={
'italic':0,
'bold':0,
'underline':0
},
cellTagName=(cellStyle.bgColor&&cellStyle.bgColor!=='#FFFFFF') ? 'th':'td',
cellClassNames=[],
cellClassName='',
cellRowspan='',
cellColspan='',
cellInlineStyles=[];
if(cellIndex % 2===1){
cellClassNames.push('alt');
}
if(cellSSData.length){
cellInlineTags={
'bold':cellSSData.find('B').length,
'italic':cellSSData.find('I').length,
'underline':cellSSData.find('U').length
};
cellContent=makeCellInlineFormats(cellSSData);
}
if(typeof cellStyle.bgColor==='string'){
cellInlineStyles.push('background-color: ' + cellStyle.bgColor);
}
if(typeof cellStyle.alignment==='object'){
if(typeof cellStyle.alignment.horizontal==='string'){
cellInlineStyles.push('text-align: ' + cellStyle.alignment.horizontal);
}
if(typeof cellStyle.alignment.vertical==='string'){
cellInlineStyles.push('vertical-align: ' + cellStyle.alignment.vertical);
}}
if(typeof cellStyle.font==='object'){
if(typeof cellStyle.font.italic!=='undefined'){
cellInlineStyles.push('font-style: italic');
}
if(typeof cellStyle.font.bold!=='undefined'){
cellInlineStyles.push('font-weight: bold');
}
if(typeof cellStyle.font.underline!=='undefined'){
cellInlineStyles.push('text-decoration: underline');
}
if(typeof cellStyle.font.color!=='undefined'){
cellInlineStyles.push('color: ' + cellStyle.font.color);
}}
if(cellClassNames.length){
cellClassName=[' class="', cellClassNames.join(' '), '"'].join('');
}
if(cellMergeDown){
cellRowspan=[' rowspan="', cellMergeDown+1, '"'].join('');
}
if(cellMergeAcross){
cellColspan=[' colspan="', cellMergeAcross+1, '"'].join('');
}
if(typeof cellNumberFormat!=='undefined'){
cellContent=makeCellCurrency(cellNumberFormat, cellContent);
}
if(cellInlineStyles.length){
cellInlineStyles=[' style="', cellInlineStyles.join('; '), '"'].join('');
}else{
cellInlineStyles='';
}
cellContent=cellContent.replace(/\n/g, '<br />');
if(typeof cellStyle.font==='object'
&& typeof cellStyle.font.size!=='undefined'
&& cellStyle.font.size!=='11'){
cellContent=[
'<span style="font-size: ', Math.round(parseFloat(cellStyle.font.size, 10) / 11 * 100, 10), '%;">',
cellContent,
'</span>'
].join('');
}
return [
'<', cellTagName, cellClassName, cellRowspan, cellColspan, cellInlineStyles, '>',
cellContent,
'</', cellTagName, '>'
].join('');
}}
function makeCellInlineFormats($ssData){
var ssDataChildNodes=jQuery.makeArray($ssData[0].childNodes),
contentsStr=[];
while(ssDataChildNodes.length){
contentsStr.push(xmlSerializer.serializeToString(ssDataChildNodes.shift()));
}
contentsStr=contentsStr.join('');
var cellContentStr=contentsStr,
fontMatchArray=cellContentStr.match(/<Font+(.*?)>/g);
var inlineStyles;
for(var i=0, ii=fontMatchArray.length; i < ii; i++){
inlineStyles=getInlineStyles(fontMatchArray[i]);
if(inlineStyles===''){
cellContentStr=cellContentStr
.replace(fontMatchArray[i], '')
.replace('</Font>', '');
}else{
cellContentStr=cellContentStr
.replace(fontMatchArray[i], '<span style="' + inlineStyles + '">')
.replace('</Font>', '</span>');
}}
var inlineTags=['b', 'i', 'u', 'sup'],
tagName;
while(inlineTags.length){
tagName=inlineTags.shift();
cellContentStr=cellContentStr
.replace(new RegExp('<' + tagName + '+(.*?)>', 'gi'), '<' + tagName + '>')
.replace(new RegExp('<\/' + tagName + '+(.*?)>', 'gi'), '</' + tagName + '>');
}
return cellContentStr;
function getInlineStyles(fontHTMLStr){
var splitArray=fontHTMLStr.substring(1, fontHTMLStr.length-1).split(' '),
attrStr,
splitAttrArray,
inlineStylesArray=[];
while(splitArray.length){
attrStr=splitArray.shift();
if(attrStr.indexOf('html:')===-1) continue;
splitAttrArray=attrStr.replace(/(html\:)|"/g, '').toLowerCase().split('=');
switch(splitAttrArray[0]){
case 'color':
if(splitAttrArray[1]==='#000000') continue;
inlineStylesArray.push(['color: ', splitAttrArray[1]].join(''));
break;
case 'size':
inlineStylesArray.push(['font-size: ', Math.round((parseFloat(splitAttrArray[1], 10) / 11 * 100), 10), '%'].join(''));
break;
}}
return inlineStylesArray.join('; ');
}}
function makeCellCurrency(cellNumberFormat, cellContent){
if(cellNumberFormat==='@'
|| cellNumberFormat==='0') return cellContent;
var splitCellContentArray;
if(cellNumberFormat==='Currency'){
splitCellContentArray=parseFloat(cellContent, 10).toFixed(2).split('.');
cellContent='RM' + contentWithcommas();
if(splitCellContentArray.length > 1){
cellContent +='.' + splitCellContentArray[1];
}}else if(cellNumberFormat==='Fixed'){
splitCellContentArray=parseFloat(cellContent, 10).toFixed(2).split('.');
cellContent=contentWithcommas();
if(splitCellContentArray.length > 1){
cellContent +='.' + splitCellContentArray[1];
}}else{
var currencyFormatArray=cellNumberFormat.split(';')[0].split(','),
currency=currencyFormatArray[0].replace(/\[|\]| |#|\\|"/g, '').replace(/\$/, '').split('-'),
decimals=currencyFormatArray[1].split('.');
if(currency.length > 1) currency=currency[0];
if(decimals.length===1){
decimals=0;
}else{
decimals=decimals[1].replace(/_\)/g, '').length;
}
splitCellContentArray=parseFloat(cellContent, 10).toFixed(decimals).split('.');
cellContent=currency + contentWithcommas();
if(splitCellContentArray.length > 1){
cellContent +='.' + splitCellContentArray[1];
}}
return cellContent;
function contentWithcommas(){
return splitCellContentArray[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}}
function attachRowHoverers(){
$holders.find('[rowspan]').each(function(){
var $thisCell=jQuery(this),
rowspan=$thisCell.attr('rowspan');
if(typeof rowspan!=='string') return;
rowspan=parseInt(rowspan, 10);
var $thisRow=$thisCell.closest('tr'),
$nextRows=$thisRow.nextAll('tr').slice(0, rowspan-1);
$nextRows.each(function(){
jQuery(this).on({
mouseenter:function(){
$thisCell.addClass('is-hovered');
},
mouseleave:function(){
$thisCell.removeClass('is-hovered');
}});
});
});
}
function filterOutEmptyRows($rows){
$rows.each(function(){
var empty=true;
jQuery(this).find('Cell').each(function(){
if(jQuery(this).text()!=='') empty=false;
return false;
});
if(empty) $rows=$rows.not(jQuery(this));
});
return $rows;
}
function hasAttributes($obj, attrArr){
while(attrArr.length){
if(typeof $obj.attr(attrArr.shift())!=='undefined'){
return true;
}}
return false;
}},
loadXMLLocations:function($holders){
$holders=jQuery($holders);
if(!$holders.length) return;
$holders.each(function(){
var $thisHolder=jQuery(this);
if($thisHolder.data('loaded-xml-locations')===true) return;
var xmlURL=$thisHolder.data('xml-locations-url');
if(typeof xmlURL!=='string') return;
jQuery.ajax({
type: 'GET',
url: xmlURL,
dataType: 'xml',
success: function(data){
makeLocationsList(data, $thisHolder);
$thisHolder.data('loaded-xml-locations', true);
},
error: function(d){
console.log(d);
}});
});
function makeLocationsList(data, $holder){
var $locations=jQuery(data).find('obj'),
regions=[];
$locations.each(function(){
var $region=jQuery(this).find('region'),
regionStr=jQuery.trim($region.text());
regionStr=(regionStr) ? regionStr:'Default';
if(regions.length){
for(var i=regions.length-1; i > -1; i--){
if(regions[i].name===regionStr){
regions[i].$els.push(jQuery(this));
return;
}}
}
regions.push({
'name':regionStr,
'$els':[jQuery(this)]
});
});
regions.sort(function(a,b){
var strA=a.name.toLowerCase(),
strB=b.name.toLowerCase();
if(strA < strB) return -1;
if(strA > strB) return 1;
return 0;
});
var output=[],
switcherStrArr=['<span class="location-dropdown"><select>', '', '</select></span>'],
rowMarkup=['<div class="row location-list', 1, '"><div class="row__flexi-width ', 3, '">'],
i, ii, totalLocationsInRegion;
for(i=0, ii=regions.length; i < ii; i++){
rowMarkup[1]=(i===0) ? ' current':'';
totalLocationsInRegion=regions[i].$els.length;
if(totalLocationsInRegion < 2){
rowMarkup[3]='has-1-item';
}else if(totalLocationsInRegion===2){
rowMarkup[3]='has-2-items';
}else if(totalLocationsInRegion===3){
rowMarkup[3]='has-3-items';
}else{
rowMarkup[3]='more-than-3-items';
}
output.push(rowMarkup.join(''));
while(regions[i].$els.length){
output.push([
'<div class="column">',
'<div class="location">',
'<div class="location__name">',
jQuery.trim(regions[i].$els[0].find('storeName').text()),
'</div>',
'<div class="location__address">',
jQuery.trim(regions[i].$els[0].find('storeAddress').text()),
'</div>',
'<div class="location__footer">',
'<a href="https://maps.google.com/maps?daddr=',
jQuery.trim(regions[i].$els[0].find('storeLat').text()), ',',
jQuery.trim(regions[i].$els[0].find('storeLng').text()), '" target="_blank">',
'Get Directions',
'</a>',
'</div>',
'</div>',
'</div>'
].join(''));
regions[i].$els.shift();
}
output.push('</div></div>');
}
$holder.html(output.join(''));
if(regions.length > 1){
for(i=0, ii=regions.length; i < ii; i++){
switcherStrArr[1] +=[
'<option value="', i, '">', regions[i].name, '</option>'
].join('');
}
var $switcher=jQuery(switcherStrArr.join(''));
jQuery('<div class="text-center" />')
.prependTo($holder)
.append($switcher);
$switcher.dropdownify();
var $locationLists=$holder.find('.location-list');
$holder.find('select').on('change', function(){
var targetIndex=parseInt(jQuery(this).val(), 10);
$locationLists.each(function(index){
if(index===targetIndex){
jQuery(this)
.addClass('current')
.heightSyncify('enable')
.heightSyncify('sync');
}else{
jQuery(this)
.removeClass('current')
.heightSyncify('disable');
}});
});
}
var syncHeightSelectors=['.location__name', '.location__address'];
$holder.find('.location-list').heightSyncify({
items:syncHeightSelectors
});
}},
scrollTo:function($obj, callback){
if(typeof $obj!=='object'
|| !$obj instanceof jQuery
|| !$obj.length){
return;
}
var targetScrollPos=$obj.offset().top - 50;
if(targetScrollPos < jQuery(window).scrollTop()){
targetScrollPos -=jQuery('#mainNav').outerHeight();
if(jQuery('#mainSmallNav').css('display')!=='none'
&& !jQuery('#mainHeader').hasClass('is-partially-hidden')){
targetScrollPos -=jQuery('#mainSmallNav').outerHeight();
}}
if(callback==='snap'){
jQuery(window).scrollTop(targetScrollPos);
}else{
jQuery('html, body').animate({
scrollTop:targetScrollPos
}, 400, callback);
}},
watchSize:function(){
homebrew.watchSize.apply(homebrew, arguments);
}
});
jQuery.extend(FE.FootnoteAnchor.prototype, {
init:function($el, $footnote){
if(!$el.length||!$footnote.length) return;
var instance=this;
instance.$el=$el;
instance.$footnote=$footnote;
$el.tooltipify({
contents:$footnote.html()
});
instance.$el.data('footnote-anchor', this);
instance.enable();
},
enable:function(){
if(Modernizr.touch) return this;
var instance=this;
instance.$el.on({
'click.footnotesTooltip':function(e){
e.preventDefault();
e.stopPropagation();
var $thisFootnote=instance.$footnote;
if(!jQuery('#notesToggler').hasClass('is-toggled')){
jQuery('#notesToggler').togglerify('toggleOn', { noSlide:true });
}
FE.scrollTo($thisFootnote);
$thisFootnote.addClass('is-active');
jQuery(document)
.off('mouseup.notesFauxBlur')
.on('mouseup.notesFauxBlur', function(e){
if(!$thisFootnote.is(e.target)&&$thisFootnote.has(e.target).length===0){
jQuery(document).off('mouseup.notesFauxBlur');
$thisFootnote.removeClass('is-active');
}});
}});
return this;
},
disable:function(){
var instance=this;
instance.$el.off('click.footnotesTooltip');
instance.$el.tooltipify('disable');
return instance;
}});
jQuery.extend(FE.Hasher.prototype, {
get:function(args){
var instance=this,
hash=window.location.hash;
if(hash===''
|| hash==='#/'
|| hash.substr(0,2)!=='#/'){
instance.data={};
return instance;
}
var splitHash=hash.substring(2).split('&'),
keyValuePairs,
dataObj={};
while(splitHash.length){
keyValuePairs=splitHash.shift().split('=');
dataObj[jQuery.trim(keyValuePairs[0])]=decodeURIComponent(jQuery.trim(keyValuePairs[1]));
}
instance.data=dataObj;
return instance;
},
setData:function(data){
if(!data||!jQuery.isPlainObject(data)) return this;
this.data=jQuery.extend({}, data);
return this;
},
extendData:function(data){
if(!data||!jQuery.isPlainObject(data)) return this;
if(this.data){
jQuery.extend(this.data, data);
}else{
this.data=data;
}
return this;
},
set:function(args){
args=args||{};
var instance=this,
options=jQuery.extend(instance.options, args);
if(options.ignoreDefault&&!instance.data) return instance;
instance.data=instance.data||{};
var hashKeys=[],
hash=[],
sequence=options.sequence;
if(sequence==='alphabetical'
|| typeof sequence==='function'){
jQuery.each(instance.data, function(key, value){
if(key===''||value==='') return;
hashKeys.push(key);
});
var sorter;
if(sequence==='alphabetical'){
sorter=function(a, b){
var _a=a.toLowerCase(),
_b=b.toLowerCase();
if(_a < _b) return -1;
if(_a > _b) return 1;
return 0;
};}else if(typeof sequence==='function'){
sorter=sequence;
}
hashKeys.sort(sorter);
var currentHashKey;
while(hashKeys.length){
currentHashKey=hashKeys.shift();
hash.push([currentHashKey, encodeURIComponent(instance.data[currentHashKey])].join('='));
}}else if(typeof sequence==='string'){
var splitSequence=sequence.split(','),
i, ii, currentSequenceKey;
for(i=0, ii=splitSequence.length; i < ii; i++){
currentSequenceKey=splitSequence[i];
if(instance.data[currentSequenceKey]){
hash.push([currentSequenceKey, encodeURIComponent(instance.data[currentSequenceKey])].join('='));
}}
jQuery.each(instance.data, function(key, value){
if(key===''||value==='') return;
for(i=splitSequence.length-1; i > -1; i--){
if(key===splitSequence[i]) return;
}
hash.push([key, encodeURIComponent(value)].join('='));
});
}else{
jQuery.each(instance.data, function(key, value){
if(key===''||value==='') return;
hash.push([key, encodeURIComponent(value)].join('='));
});
}
window.location.hash='#/' + hash.join('&');
},
isSameWith:function(data){
if(!data) return false;
var same=true,
count=0,
instance=this;
jQuery.each(data, function(key, value){
if(typeof instance.data[key]==='undefined'
|| instance.data[key]!==value){
same=false;
return false;
}else{
count++;
}});
if(same){
var refCount=0;
jQuery.each(instance.data, function(){
refCount++;
});
same=(count===refCount);
}
return same;
}});
jQuery.extend(FE.StickyColumn.prototype, {
callbacks:jQuery({}),
hasMousewheel:Boolean(jQuery.fn.mousewheel),
classes:{
stickyColumn:'sticky-column',
sticky:'is-sticky',
stickBottom:'is-stick-to-bottom'
},
load:function(args){
var instance=this,
proto=FE.StickyColumn.prototype;
if(!proto.hasMousewheel){
if(!proto.loadingMousewheel){
proto.loadingMousewheel=true;
jQuery.getScript(FE.baseURL + 'js/plugins/jquery.mousewheel.min.js', function(){
FE.StickyColumn.prototype.hasMousewheel=true;
proto.callbacks.dequeue('mousewheelLoaded');
});
}
proto.callbacks.queue('mousewheelLoaded', function(next){
instance.init(args);
if(typeof next==='function') next();
});
}},
init:function(args){
var $el=args.$el,
$comparee=args.$comparee;
if(!$el||!$comparee
|| !$el instanceof jQuery||!$comparee instanceof jQuery
|| !$el.length||!$comparee.length){
return;
}
var instance=this,
proto=FE.StickyColumn.prototype;
instance.$el=$el;
instance.$comparee=$comparee;
instance.uniqueID=homebrew.generateUniqueID();
$el.addClass(instance.classes.stickyColumn);
FE.watchSize('large', function(isLargeScreen){
if(isLargeScreen){
instance.watch();
}else{
instance.rest();
instance.unstick();
instance.updatePosition();
}});
return instance;
},
determineState:function(){
if(!homebrew.screenSize.large) return 'should-be-unstuck';
var instance=this,
$stickyCol=instance.$el,
$comparee=instance.$comparee,
windowTop=jQuery(window).scrollTop(),
stickyColMarginTop=parseInt($stickyCol.css('margin-top'), 10);
instance.offsetTop=(jQuery('#mainHeader').css('position')==='fixed') ?  0:0;
instance.offsetBottom=parseInt($comparee.find('.column').css('margin-bottom'), 10)*2;
if(!$comparee.is(':visible')||$stickyCol.height() >=$comparee.height()){
return 'should-be-unstuck';
}else if($stickyCol.hasClass(instance.classes.stickBottom)&&$stickyCol.offset().top >=windowTop + instance.offsetTop){
return 'should-be-stuck';
}else if((windowTop + $stickyCol.height() + stickyColMarginTop + instance.offsetTop) > ($comparee.offset().top + $comparee.height() - instance.offsetBottom)){
return 'should-be-stuck-to-bottom';
}else if($comparee.offset().top <=windowTop + instance.offsetTop){
return 'should-be-stuck';
}else{
return 'should-be-unstuck';
}},
updatePosition:function(){
var instance=this,
$el=instance.$el;
if($el.hasClass(instance.classes.stickBottom)||!$el.hasClass(instance.classes.sticky)){
$el.css('top', '');
}else{
$el.css('top', jQuery(window).scrollTop() - instance.$comparee.offset().top + instance.offsetTop + 'px');
}
return instance;
},
stick:function(){
var instance=this;
instance.$el
.addClass(instance.classes.sticky)
.removeClass(instance.classes.stickBottom);
return instance;
},
stickToBottom:function(){
var instance=this;
instance.$el
.addClass([
instance.classes.sticky,
instance.classes.stickBottom
].join(' '))
.css('margin-top', '');
return instance;
},
unstick:function(){
var instance=this;
instance.$el
.removeClass([
instance.classes.sticky,
instance.classes.stickBottom
].join(' '))
.css('margin-top', '');
return instance;
},
watch:function(){
var instance=this;
jQuery(window).on([
'scroll.', instance.uniqueID,
' resize.', instance.uniqueID
].join(''), function(){
var state=instance.determineState();
switch(state){
case 'should-be-stuck':instance.stick();         break;
case 'should-be-stuck-to-bottom':instance.stickToBottom(); break;
case 'should-be-unstuck':instance.unstick();       break;
}
instance.updatePosition();
}).trigger('scroll');
instance.$el.on('mousewheel', function(e){
if(instance.determineState()!=='should-be-stuck') return;
var vector;
if(e.deltaY < 0){
var bottomDiff=jQuery(window).scrollTop() + jQuery(window).height() - jQuery(this).offset().top - jQuery(this).height();
if(bottomDiff >=0){
return;
}else if(Math.abs(bottomDiff) < 100){
vector=bottomDiff;
}else{
vector=-100;
}}else if(e.deltaY > 0){
var topDiff=jQuery(window).scrollTop() + instance.offsetTop - jQuery(this).offset().top;
if(topDiff===0){
return;
}else if(topDiff < 100){
vector=topDiff;
}else{
vector=100;
}}
e.preventDefault();
instance.$el.css('margin-top', [parseInt(instance.$el.css('margin-top'), 10) + vector, 'px'].join(''));
});
return instance;
},
rest:function(){
jQuery(window).off('.' + this.uniqueID);
return this;
}});
FE.initPage();
if(typeof FE__callbacks==='object'
&& FE__callbacks instanceof Array
&& FE__callbacks.length){
while(FE__callbacks.length){
FE__callbacks.shift()();
}}
});