1/* 2 * Foundation Responsive Library 3 * http://foundation.zurb.com 4 * Copyright 2015, ZURB 5 * Free to use under the MIT license. 6 * http://www.opensource.org/licenses/mit-license.php 7*/ 8 9(function ($, window, document, undefined) { 10 'use strict'; 11 12 var header_helpers = function (class_array) { 13 var head = $('head'); 14 head.prepend($.map(class_array, function (class_name) { 15 if (head.has('.' + class_name).length === 0) { 16 return '<meta class="' + class_name + '" />'; 17 } 18 })); 19 }; 20 21 header_helpers([ 22 'foundation-mq-small', 23 'foundation-mq-small-only', 24 'foundation-mq-medium', 25 'foundation-mq-medium-only', 26 'foundation-mq-large', 27 'foundation-mq-large-only', 28 'foundation-mq-xlarge', 29 'foundation-mq-xlarge-only', 30 'foundation-mq-xxlarge', 31 'foundation-data-attribute-namespace']); 32 33 // Enable FastClick if present 34 35 $(function () { 36 if (typeof FastClick !== 'undefined') { 37 // Don't attach to body if undefined 38 if (typeof document.body !== 'undefined') { 39 FastClick.attach(document.body); 40 } 41 } 42 }); 43 44 // private Fast Selector wrapper, 45 // returns jQuery object. Only use where 46 // getElementById is not available. 47 var S = function (selector, context) { 48 if (typeof selector === 'string') { 49 if (context) { 50 var cont; 51 if (context.jquery) { 52 cont = context[0]; 53 if (!cont) { 54 return context; 55 } 56 } else { 57 cont = context; 58 } 59 return $(cont.querySelectorAll(selector)); 60 } 61 62 return $(document.querySelectorAll(selector)); 63 } 64 65 return $(selector, context); 66 }; 67 68 // Namespace functions. 69 70 var attr_name = function (init) { 71 var arr = []; 72 if (!init) { 73 arr.push('data'); 74 } 75 if (this.namespace.length > 0) { 76 arr.push(this.namespace); 77 } 78 arr.push(this.name); 79 80 return arr.join('-'); 81 }; 82 83 var add_namespace = function (str) { 84 var parts = str.split('-'), 85 i = parts.length, 86 arr = []; 87 88 while (i--) { 89 if (i !== 0) { 90 arr.push(parts[i]); 91 } else { 92 if (this.namespace.length > 0) { 93 arr.push(this.namespace, parts[i]); 94 } else { 95 arr.push(parts[i]); 96 } 97 } 98 } 99 100 return arr.reverse().join('-'); 101 }; 102 103 // Event binding and data-options updating. 104 105 var bindings = function (method, options) { 106 var self = this, 107 bind = function(){ 108 var $this = S(this), 109 should_bind_events = !$this.data(self.attr_name(true) + '-init'); 110 $this.data(self.attr_name(true) + '-init', $.extend({}, self.settings, (options || method), self.data_options($this))); 111 112 if (should_bind_events) { 113 self.events(this); 114 } 115 }; 116 117 if (S(this.scope).is('[' + this.attr_name() +']')) { 118 bind.call(this.scope); 119 } else { 120 S('[' + this.attr_name() +']', this.scope).each(bind); 121 } 122 // # Patch to fix #5043 to move this *after* the if/else clause in order for Backbone and similar frameworks to have improved control over event binding and data-options updating. 123 if (typeof method === 'string') { 124 return this[method].call(this, options); 125 } 126 127 }; 128 129 var single_image_loaded = function (image, callback) { 130 function loaded () { 131 callback(image[0]); 132 } 133 134 function bindLoad () { 135 this.one('load', loaded); 136 137 if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) { 138 var src = this.attr( 'src' ), 139 param = src.match( /\?/ ) ? '&' : '?'; 140 141 param += 'random=' + (new Date()).getTime(); 142 this.attr('src', src + param); 143 } 144 } 145 146 if (!image.attr('src')) { 147 loaded(); 148 return; 149 } 150 151 if (image[0].complete || image[0].readyState === 4) { 152 loaded(); 153 } else { 154 bindLoad.call(image); 155 } 156 }; 157 158 /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */ 159 160 window.matchMedia || (window.matchMedia = function() { 161 "use strict"; 162 163 // For browsers that support matchMedium api such as IE 9 and webkit 164 var styleMedia = (window.styleMedia || window.media); 165 166 // For those that don't support matchMedium 167 if (!styleMedia) { 168 var style = document.createElement('style'), 169 script = document.getElementsByTagName('script')[0], 170 info = null; 171 172 style.type = 'text/css'; 173 style.id = 'matchmediajs-test'; 174 175 script.parentNode.insertBefore(style, script); 176 177 // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers 178 info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle; 179 180 styleMedia = { 181 matchMedium: function(media) { 182 var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }'; 183 184 // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers 185 if (style.styleSheet) { 186 style.styleSheet.cssText = text; 187 } else { 188 style.textContent = text; 189 } 190 191 // Test if media query is true or false 192 return info.width === '1px'; 193 } 194 }; 195 } 196 197 return function(media) { 198 return { 199 matches: styleMedia.matchMedium(media || 'all'), 200 media: media || 'all' 201 }; 202 }; 203 }()); 204 205 /* 206 * jquery.requestAnimationFrame 207 * https://github.com/gnarf37/jquery-requestAnimationFrame 208 * Requires jQuery 1.8+ 209 * 210 * Copyright (c) 2012 Corey Frang 211 * Licensed under the MIT license. 212 */ 213 214 (function(jQuery) { 215 216 217 // requestAnimationFrame polyfill adapted from Erik Möller 218 // fixes from Paul Irish and Tino Zijdel 219 // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ 220 // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating 221 222 var animating, 223 lastTime = 0, 224 vendors = ['webkit', 'moz'], 225 requestAnimationFrame = window.requestAnimationFrame, 226 cancelAnimationFrame = window.cancelAnimationFrame, 227 jqueryFxAvailable = 'undefined' !== typeof jQuery.fx; 228 229 for (;
229 lastTime < vendors.length && !requestAnimationFrame; lastTime++) { 230 requestAnimationFrame = window[ vendors[lastTime] + 'RequestAnimationFrame' ]; 231 cancelAnimationFrame = cancelAnimationFrame || 232 window[ vendors[lastTime] + 'CancelAnimationFrame' ] || 233 window[ vendors[lastTime] + 'CancelRequestAnimationFrame' ]; 234 } 235 236 function raf() { 237 if (animating) { 238 requestAnimationFrame(raf); 239 240 if (jqueryFxAvailable) { 241 jQuery.fx.tick(); 242 } 243 } 244 } 245 246 if (requestAnimationFrame) { 247 // use rAF 248 window.requestAnimationFrame = requestAnimationFrame; 249 window.cancelAnimationFrame = cancelAnimationFrame; 250 251 if (jqueryFxAvailable) { 252 jQuery.fx.timer = function (timer) { 253 if (timer() && jQuery.timers.push(timer) && !animating) { 254 animating = true; 255 raf(); 256 } 257 }; 258 259 jQuery.fx.stop = function () { 260 animating = false; 261 }; 262 } 263 } else { 264 // polyfill 265 window.requestAnimationFrame = function (callback) { 266 var currTime = new Date().getTime(), 267 timeToCall = Math.max(0, 16 - (currTime - lastTime)), 268 id = window.setTimeout(function () { 269 callback(currTime + timeToCall); 270 }, timeToCall); 271 lastTime = currTime + timeToCall; 272 return id; 273 }; 274 275 window.cancelAnimationFrame = function (id) { 276 clearTimeout(id); 277 }; 278 279 } 280 281 }( $ )); 282 283 function removeQuotes (string) { 284 if (typeof string === 'string' || string instanceof String) { 285 string = string.replace(/^['\\/"]+|(;\s?})+|['\\/"]+$/g, ''); 286 } 287 288 return string; 289 } 290 291 function MediaQuery(selector) { 292 this.selector = selector; 293 this.query = ''; 294 } 295 296 MediaQuery.prototype.toString = function () { 297 return this.query || (this.query = S(this.selector).css('font-family').replace(/^[\/\\'"]+|(;\s?})+|[\/\\'"]+$/g, '')); 298 }; 299 300 window.Foundation = { 301 name : 'Foundation', 302 303 version : '5.5.3', 304 305 media_queries : { 306 'small' : new MediaQuery('.foundation-mq-small'), 307 'small-only' : new MediaQuery('.foundation-mq-small-only'), 308 'medium' : new MediaQuery('.foundation-mq-medium'), 309 'medium-only' : new MediaQuery('.foundation-mq-medium-only'), 310 'large' : new MediaQuery('.foundation-mq-large'), 311 'large-only' : new MediaQuery('.foundation-mq-large-only'), 312 'xlarge' : new MediaQuery('.foundation-mq-xlarge'), 313 'xlarge-only' : new MediaQuery('.foundation-mq-xlarge-only'), 314 'xxlarge' : new MediaQuery('.foundation-mq-xxlarge') 315 }, 316 317 stylesheet : $('<style></style>').appendTo('head')[0].sheet, 318 319 global : { 320 namespace : undefined 321 }, 322 323 init : function (scope, libraries, method, options, response) { 324 var args = [scope, method, options, response], 325 responses = []; 326 327 // check RTL 328 this.rtl = /rtl/i.test(S('html').attr('dir')); 329 330 // set foundation global scope 331 this.scope = scope || this.scope; 332 333 this.set_namespace(); 334 335 if (libraries && typeof libraries === 'string' && !/reflow/i.test(libraries)) { 336 if (this.libs.hasOwnProperty(libraries)) { 337 responses.push(this.init_lib(libraries, args)); 338 } 339 } else { 340 for (var lib in this.libs) { 341 responses.push(this.init_lib(lib, libraries)); 342 } 343 } 344 345 S(window).load(function () { 346 S(window) 347 .trigger('resize.fndtn.clearing') 348 .trigger('resize.fndtn.dropdown') 349 .trigger('resize.fndtn.equalizer') 350 .trigger('resize.fndtn.interchange') 351 .trigger('resize.fndtn.joyride') 352 .trigger('resize.fndtn.magellan') 353 .trigger('resize.fndtn.topbar') 354 .trigger('resize.fndtn.slider'); 355 }); 356 357 return scope; 358 }, 359 360 init_lib : function (lib, args) { 361 if (this.libs.hasOwnProperty(lib)) { 362 this.patch(this.libs[lib]); 363 364 if (args && args.hasOwnProperty(lib)) { 365 if (typeof this.libs[lib].settings !== 'undefined') { 366 $.extend(true, this.libs[lib].settings, args[lib]); 367 } else if (typeof this.libs[lib].defaults !== 'undefined') { 368 $.extend(true, this.libs[lib].defaults, args[lib]); 369 } 370 return this.libs[lib].init.apply(this.libs[lib], [this.scope, args[lib]]); 371 } 372 373 args = args instanceof Array ? args : new Array(args); 374 return this.libs[lib].init.apply(this.libs[lib], args); 375 } 376 377 return function () {}; 378 }, 379 380 patch : function (lib) { 381 lib.scope = this.scope; 382 lib.namespace = this.global.namespace; 383 lib.rtl = this.rtl; 384 lib['data_options'] = this.utils.data_options; 385 lib['attr_name'] = attr_name; 386 lib['add_namespace'] = add_namespace; 387 lib['bindings'] = bindings; 388 lib['S'] = this.utils.S; 389 }, 390 391 inherit : function (scope, methods) { 392 var methods_arr = methods.split(' '), 393 i = methods_arr.length; 394 395 while (i--) { 396 if (this.utils.hasOwnProperty(methods_arr[i])) { 397 scope[methods_arr[i]] = this.utils[methods_arr[i]]; 398 } 399 } 400 }, 401 402 set_namespace : function () { 403 404 // Description: 405 // Don't bother reading the namespace out of the meta tag 406 // if the namespace has been set globally in javascript 407 // 408 // Example: 409 // Foundation.global.namespace = 'my-namespace'; 410 // or make it an empty string: 411 // Foundation.global.namespace = ''; 412 // 413 // 414 415 // If the namespace has not been set (is undefined), try to read it out of the meta element. 416 // Otherwise use the globally defined namespace, even if it's empty ('') 417 var namespace = ( this.global.namespace === undefined ) ? $('.foundation-data-attribute-namespace').css('font-family') : this.global.namespace; 418 419 // Finally, if the namsepace is either undefined or false, set it to an empty string. 420 // Otherwise use the namespace value. 421 this.global.namespace = ( namespace === undefined || /false/i.test(namespace) ) ? '' : namespace; 422 }, 423 424 libs : {}, 425 426 // methods that can be inherited in libraries 427 utils : { 428 429 // Description: 430 // Fast Selector wrapper returns jQuery object. Only use where getElementById 431 // is not available. 432 // 433 // Arguments:
434 // Selector (String): CSS selector describing the element(s) to be 435 // returned as a jQuery object. 436 // 437 // Scope (String): CSS selector describing the area to be searched. Default 438 // is document. 439 // 440 // Returns: 441 // Element (jQuery Object): jQuery object containing elements matching the 442 // selector within the scope. 443 S : S, 444 445 // Description: 446 // Executes a function a max of once every n milliseconds 447 // 448 // Arguments: 449 // Func (Function): Function to be throttled. 450 // 451 // Delay (Integer): Function execution threshold in milliseconds. 452 // 453 // Returns: 454 // Lazy_function (Function): Function with throttling applied. 455 throttle : function (func, delay) { 456 var timer = null; 457 458 return function () { 459 var context = this, args = arguments; 460 461 if (timer == null) { 462 timer = setTimeout(function () { 463 func.apply(context, args); 464 timer = null; 465 }, delay); 466 } 467 }; 468 }, 469 470 // Description: 471 // Executes a function when it stops being invoked for n seconds 472 // Modified version of _.debounce() http://underscorejs.org 473 // 474 // Arguments: 475 // Func (Function): Function to be debounced. 476 // 477 // Delay (Integer): Function execution threshold in milliseconds. 478 // 479 // Immediate (Bool): Whether the function should be called at the beginning 480 // of the delay instead of the end. Default is false. 481 // 482 // Returns: 483 // Lazy_function (Function): Function with debouncing applied. 484 debounce : function (func, delay, immediate) { 485 var timeout, result; 486 return function () { 487 var context = this, args = arguments; 488 var later = function () { 489 timeout = null; 490 if (!immediate) { 491 result = func.apply(context, args); 492 } 493 }; 494 var callNow = immediate && !timeout; 495 clearTimeout(timeout); 496 timeout = setTimeout(later, delay); 497 if (callNow) { 498 result = func.apply(context, args); 499 } 500 return result; 501 }; 502 }, 503 504 // Description: 505 // Parses data-options attribute 506 // 507 // Arguments: 508 // El (jQuery Object): Element to be parsed. 509 // 510 // Returns: 511 // Options (Javascript Object): Contents of the element's data-options 512 // attribute. 513 data_options : function (el, data_attr_name) { 514 data_attr_name = data_attr_name || 'options'; 515 var opts = {}, ii, p, opts_arr, 516 data_options = function (el) { 517 var namespace = Foundation.global.namespace; 518 519 if (namespace.length > 0) { 520 return el.data(namespace + '-' + data_attr_name); 521 } 522 523 return el.data(data_attr_name); 524 }; 525 526 var cached_options = data_options(el); 527 528 if (typeof cached_options === 'object') { 529 return cached_options; 530 } 531 532 opts_arr = (cached_options || ':').split(';'); 533 ii = opts_arr.length; 534 535 function isNumber (o) { 536 return !isNaN (o - 0) && o !== null && o !== '' && o !== false && o !== true; 537 } 538 539 function trim (str) { 540 if (typeof str === 'string') { 541 return $.trim(str); 542 } 543 return str; 544 } 545 546 while (ii--) { 547 p = opts_arr[ii].split(':'); 548 p = [p[0], p.slice(1).join(':')]; 549 550 if (/true/i.test(p[1])) { 551 p[1] = true; 552 } 553 if (/false/i.test(p[1])) { 554 p[1] = false; 555 } 556 if (isNumber(p[1])) { 557 if (p[1].indexOf('.') === -1) { 558 p[1] = parseInt(p[1], 10); 559 } else { 560 p[1] = parseFloat(p[1]); 561 } 562 } 563 564 if (p.length === 2 && p[0].length > 0) { 565 opts[trim(p[0])] = trim(p[1]); 566 } 567 } 568 569 return opts; 570 }, 571 572 // Description: 573 // Adds JS-recognizable media queries 574 // 575 // Arguments: 576 // Media (String): Key string for the media query to be stored as in 577 // Foundation.media_queries 578 //
579 // Class (String): Class name for the generated <meta> tag 580 register_media : function (media, media_class) { 581 if (Foundation.media_queries[media] === undefined) { 582 $('head').append('<meta class="' + media_class + '"/>'); 583 Foundation.media_queries[media] = removeQuotes($('.' + media_class).css('font-family')); 584 } 585 }, 586 587 // Description: 588 // Add custom CSS within a JS-defined media query 589 // 590 // Arguments: 591 // Rule (String): CSS rule to be appended to the document. 592 // 593 // Media (String): Optional media query string for the CSS rule to be 594 // nested under. 595 add_custom_rule : function (rule, media) { 596 if (media === undefined && Foundation.stylesheet) { 597 Foundation.stylesheet.insertRule(rule, Foundation.stylesheet.cssRules.length); 598 } else { 599 var query = Foundation.media_queries[media]; 600 601 if (query !== undefined) { 602 Foundation.stylesheet.insertRule('@media ' + 603 Foundation.media_queries[media] + '{ ' + rule + ' }', Foundation.stylesheet.cssRules.length); 604 } 605 } 606 }, 607 608 // Description: 609 // Performs a callback function when an image is fully loaded 610 // 611 // Arguments: 612 // Image (jQuery Object): Image(s) to check if loaded. 613 // 614 // Callback (Function): Function to execute when image is fully loaded. 615 image_loaded : function (images, callback) { 616 var self = this, 617 unloaded = images.length; 618 619 function pictures_has_height(images) { 620 var pictures_number = images.length; 621 622 for (var i = pictures_number - 1; i >= 0; i--) { 623 if(images.attr('height') === undefined) { 624 return false; 625 }; 626 }; 627 628 return true; 629 } 630 631 if (unloaded === 0 || pictures_has_height(images)) { 632 callback(images); 633 } 634 635 images.each(function () { 636 single_image_loaded(self.S(this), function () { 637 unloaded -= 1; 638 if (unloaded === 0) { 639 callback(images); 640 } 641 }); 642 }); 643 }, 644 645 // Description: 646 // Returns a random, alphanumeric string 647 // 648 // Arguments: 649 // Length (Integer): Length of string to be generated. Defaults to random 650 // integer. 651 // 652 // Returns: 653 // Rand (String): Pseudo-random, alphanumeric string. 654 random_str : function () { 655 if (!this.fidx) { 656 this.fidx = 0; 657 } 658 this.prefix = this.prefix || [(this.name || 'F'), (+new Date).toString(36)].join('-'); 659 660 return this.prefix + (this.fidx++).toString(36); 661 }, 662 663 // Description: 664 // Helper for window.matchMedia 665 // 666 // Arguments: 667 // mq (String): Media query 668 // 669 // Returns: 670 // (Boolean): Whether the media query passes or not 671 match : function (mq) { 672 return window.matchMedia(mq).matches; 673 }, 674 675 // Description: 676 // Helpers for checking Foundation default media queries with JS 677 // 678 // Returns: 679 // (Boolean): Whether the media query passes or not 680 681 is_small_up : function () { 682 return this.match(Foundation.media_queries.small); 683 }, 684 685 is_medium_up : function () { 686 return this.match(Foundation.media_queries.medium); 687 }, 688 689 is_large_up : function () { 690 return this.match(Foundation.media_queries.large); 691 }, 692 693 is_xlarge_up : function () { 694 return this.match(Foundation.media_queries.xlarge); 695 }, 696 697 is_xxlarge_up : function () { 698 return this.match(Foundation.media_queries.xxlarge); 699 }, 700 701 is_small_only : function () { 702 return !this.is_medium_up() && !this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up(); 703 }, 704 705 is_medium_only : function () { 706 return this.is_medium_up() && !this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up(); 707 }, 708 709 is_large_only : function () { 710 return this.is_medium_up() && this.is_large_up() && !this.is_xlarge_up() && !this.is_xxlarge_up(); 711 }, 712 713 is_xlarge_only : function () { 714 return this.is_medium_up() && this.is_large_up() && this.is_xlarge_up() && !this.is_xxlarge_up(); 715 }, 716 717 is_xxlarge_only : function () { 718 return this.is_medium_up() && this.is_large_up() && this.is_xlarge_up() && this.is_xxlarge_up(); 719 } 720 } 721 }; 722 723 $.fn.foundation = function () { 724 var args = Array.prototype.slice.call(arguments, 0); 725 726 return this.each(function () {
727 Foundation.init.apply(Foundation, [this].concat(args)); 728 return this; 729 }); 730 }; 731 732}(jQuery, window, window.document)); 733 734;(function ($, window, document, undefined) { 735 'use strict'; 736 737 Foundation.libs.abide = { 738 name : 'abide', 739 740 version : '5.5.3', 741 742 settings : { 743 live_validate : true, // validate the form as you go 744 validate_on_blur : true, // validate whenever you focus/blur on an input field 745 // validate_on: 'tab', // tab (when user tabs between fields), change (input changes), manual (call custom events) 746 747 focus_on_invalid : true, // automatically bring the focus to an invalid input field 748 error_labels : true, // labels with a for="inputId" will receive an `error` class 749 error_class : 'error', // labels with a for="inputId" will receive an `error` class 750 // the amount of time Abide will take before it validates the form (in ms). 751 // smaller time will result in faster validation 752 timeout : 1000, 753 patterns : { 754 alpha : /^[a-zA-Z]+$/, 755 alpha_numeric : /^[a-zA-Z0-9]+$/, 756 integer : /^[-+]?\d+$/, 757 number : /^[-+]?\d*(?:[\.\,]\d+)?$/, 758 759 // amex, visa, diners 760 card : /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/, 761 cvv : /^([0-9]){3,4}$/, 762 763 // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address 764 email : /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/,
765 766 // http://blogs.lse.ac.uk/lti/2008/04/23/a-regular-expression-to-match-any-url/ 767 url: /^(https?|ftp|file|ssh):\/\/([-;:&=\+\$,\w]+@{1})?([-A-Za-z0-9\.]+)+:?(\d+)?((\/[-\+~%\/\.\w]+)?\??([-\+=&;%@\.\w]+)?#?([\w]+)?)?/, 768 // abc.de 769 domain : /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,8}$/, 770 771 datetime : /^([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9])T([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(Z|([\-\+]([0-1][0-9])\:00))$/, 772 // YYYY-MM-DD 773 date : /(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))$/, 774 // HH:MM:SS 775 time : /^(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}$/, 776 dateISO : /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/, 777 // MM/DD/YYYY 778 month_day_year : /^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.]\d{4}$/, 779 // DD/MM/YYYY 780 day_month_year : /^(0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.]\d{4}$/, 781 782 // #FFF or #FFFFFF 783 color : /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/ 784 }, 785 validators : { 786 equalTo : function (el, required, parent) { 787 var from = document.getElementById(el.getAttribute(this.add_namespace('data-equalto'))).value, 788 to = el.value, 789 valid = (from === to); 790 791 return valid; 792 } 793 } 794 }, 795 796 timer : null, 797 798 init : function (scope, method, options) { 799 this.bindings(method, options); 800 }, 801 802 events : function (scope) { 803 var self = this, 804 form = self.S(scope).attr('novalidate', 'novalidate'), 805 settings = form.data(this.attr_name(true) + '-init') || {}; 806 807 this.invalid_attr = this.add_namespace('data-invalid'); 808 809 function validate(originalSelf, e) { 810 clearTimeout(self.timer); 811 self.timer = setTimeout(function () { 812 self.validate([originalSelf], e); 813 }.bind(originalSelf), settings.timeout); 814 } 815 816 form 817 .off('.abide') 818 .on('submit.fndtn.abide', function (e) { 819 var is_ajax = /ajax/i.test(self.S(this).attr(self.attr_name())); 820 return self.validate(self.S(this).find('input, textarea, select').not(":hidden, [data-abide-ignore]").get(), e, is_ajax); 821 }) 822 .on('validate.fndtn.abide', function (e) { 823 if (settings.validate_on === 'manual') { 824 self.validate([e.target], e); 825 } 826 }) 827 .on('reset', function (e) { 828 return self.reset($(this), e); 829 }) 830 .find('input, textarea, select').not(":hidden, [data-abide-ignore]") 831 .off('.abide') 832 .on('blur.fndtn.abide change.fndtn.abide', function (e) { 833 var id = this.getAttribute('id'), 834 eqTo = form.find('[data-equalto="'+ id +'"]'); 835 // old settings fallback 836 // will be deprecated with F6 release 837 if (settings.validate_on_blur && settings.validate_on_blur === true) { 838 validate(this, e); 839 } 840 // checks if there is an equalTo equivalent related by id 841 if(typeof eqTo.get(0) !== "undefined" && eqTo.val().length){ 842 validate(eqTo.get(0),e); 843 } 844 // new settings combining validate options into one setting 845 if (settings.validate_on === 'change') { 846 validate(this, e); 847 } 848 }) 849 .on('keydown.fndtn.abide', function (e) { 850 var id = this.getAttribute('id'), 851 eqTo = form.find('[data-equalto="'+ id +'"]'); 852 // old settings fallback 853 // will be deprecated with F6 release 854 if (settings.live_validate && settings.live_validate === true && e.which != 9) { 855 validate(this, e); 856 } 857 // checks if there is an equalTo equivalent related by id 858 if(typeof eqTo.get(0) !== "undefined" && eqTo.val().length){ 859 validate(eqTo.get(0),e); 860 } 861 // new settings combining validate options into one setting
862 if (settings.validate_on === 'tab' && e.which === 9) { 863 validate(this, e); 864 } 865 else if (settings.validate_on === 'change') { 866 validate(this, e); 867 } 868 }) 869 .on('focus', function (e) { 870 if (navigator.userAgent.match(/iPad|iPhone|Android|BlackBerry|Windows Phone|webOS/i)) { 871 $('html, body').animate({ 872 scrollTop: $(e.target).offset().top 873 }, 100); 874 } 875 }); 876 }, 877 878 reset : function (form, e) { 879 var self = this; 880 form.removeAttr(self.invalid_attr); 881 882 $('[' + self.invalid_attr + ']', form).removeAttr(self.invalid_attr); 883 $('.' + self.settings.error_class, form).not('small').removeClass(self.settings.error_class); 884 $(':input', form).not(':button, :submit, :reset, :hidden, [data-abide-ignore]').val('').removeAttr(self.invalid_attr); 885 }, 886 887 validate : function (els, e, is_ajax) { 888 var validations = this.parse_patterns(els), 889 validation_count = validations.length, 890 form = this.S(els[0]).closest('form'), 891 submit_event = /submit/.test(e.type); 892 893 // Has to count up to make sure the focus gets applied to the top error 894 for (var i = 0; i < validation_count; i++) { 895 if (!validations[i] && (submit_event || is_ajax)) { 896 if (this.settings.focus_on_invalid) { 897 els[i].focus(); 898 } 899 form.trigger('invalid.fndtn.abide'); 900 this.S(els[i]).closest('form').attr(this.invalid_attr, ''); 901 return false; 902 } 903 } 904 905 if (submit_event || is_ajax) { 906 form.trigger('valid.fndtn.abide'); 907 } 908 909 form.removeAttr(this.invalid_attr); 910 911 if (is_ajax) { 912 return false; 913 } 914 915 return true; 916 }, 917 918 parse_patterns : function (els) { 919 var i = els.length, 920 el_patterns = []; 921 922 while (i--) { 923 el_patterns.push(this.pattern(els[i])); 924 } 925 926 return this.check_validation_and_apply_styles(el_patterns); 927 }, 928 929 pattern : function (el) { 930 var type = el.getAttribute('type'), 931 required = typeof el.getAttribute('required') === 'string'; 932 933 var pattern = el.getAttribute('pattern') || ''; 934 935 if (this.settings.patterns.hasOwnProperty(pattern) && pattern.length > 0) { 936 return [el, this.settings.patterns[pattern], required]; 937 } else if (pattern.length > 0) { 938 return [el, new RegExp(pattern), required]; 939 } 940 941 if (this.settings.patterns.hasOwnProperty(type)) { 942 return [el, this.settings.patterns[type], required]; 943 } 944 945 pattern = /.*/; 946 947 return [el, pattern, required]; 948 }, 949 950 // TODO: Break this up into smaller methods, getting hard to read. 951 check_validation_and_apply_styles : function (el_patterns) { 952 var i = el_patterns.length, 953 validations = []; 954 if (i == 0) { 955 return validations; 956 } 957 var form = this.S(el_patterns[0][0]).closest('[data-' + this.attr_name(true) + ']'), 958 settings = form.data(this.attr_name(true) + '-init') || {}; 959 while (i--) { 960 var el = el_patterns[i][0], 961 required = el_patterns[i][2], 962 value = el.value.trim(), 963 direct_parent = this.S(el).parent(), 964 validator = el.getAttribute(this.add_namespace('data-abide-validator')), 965 is_radio = el.type === 'radio', 966 is_checkbox = el.type === 'checkbox', 967 label = this.S('label[for="' + el.getAttribute('id') + '"]'), 968 valid_length = (required) ? (el.value.length > 0) : true, 969 el_validations = []; 970 971 var parent, valid; 972 973 // support old way to do equalTo validations 974 if (el.getAttribute(this.add_namespace('data-equalto'))) { validator = 'equalTo' } 975 976 if (!direct_parent.is('label')) { 977 parent = direct_parent; 978 } else { 979 parent = direct_parent.parent(); 980 } 981 982 if (is_radio && required) { 983 el_validations.push(this.valid_radio(el, required)); 984 } else if (is_checkbox && required) { 985 el_validations.push(this.valid_checkbox(el, required)); 986 987 } else if (validator) { 988 // Validate using each of the specified (space-delimited) validators.
989 var validators = validator.split(' '); 990 var last_valid = true, all_valid = true; 991 for (var iv = 0; iv < validators.length; iv++) { 992 valid = this.settings.validators[validators[iv]].apply(this, [el, required, parent]) 993 el_validations.push(valid); 994 all_valid = valid && last_valid; 995 last_valid = valid; 996 } 997 if (all_valid) { 998 this.S(el).removeAttr(this.invalid_attr); 999 parent.removeClass('error'); 1000 if (label.length > 0 && this.settings.error_labels) { 1001 label.removeClass(this.settings.error_class).removeAttr('role'); 1002 } 1003 $(el).triggerHandler('valid'); 1004 } else { 1005 this.S(el).attr(this.invalid_attr, ''); 1006 parent.addClass('error'); 1007 if (label.length > 0 && this.settings.error_labels) { 1008 label.addClass(this.settings.error_class).attr('role', 'alert'); 1009 } 1010 $(el).triggerHandler('invalid'); 1011 } 1012 } else { 1013 1014 if (el_patterns[i][1].test(value) && valid_length || 1015 !required && el.value.length < 1 || $(el).attr('disabled')) { 1016 el_validations.push(true); 1017 } else { 1018 el_validations.push(false); 1019 } 1020 1021 el_validations = [el_validations.every(function (valid) {return valid;})]; 1022 if (el_validations[0]) { 1023 this.S(el).removeAttr(this.invalid_attr); 1024 el.setAttribute('aria-invalid', 'false'); 1025 el.removeAttribute('aria-describedby'); 1026 parent.removeClass(this.settings.error_class); 1027 if (label.length > 0 && this.settings.error_labels) { 1028 label.removeClass(this.settings.error_class).removeAttr('role'); 1029 } 1030 $(el).triggerHandler('valid'); 1031 } else { 1032 this.S(el).attr(this.invalid_attr, ''); 1033 el.setAttribute('aria-invalid', 'true'); 1034 1035 // Try to find the error associated with the input 1036 var errorElem = parent.find('small.' + this.settings.error_class, 'span.' + this.settings.error_class); 1037 var errorID = errorElem.length > 0 ? errorElem[0].id : ''; 1038 if (errorID.length > 0) { 1039 el.setAttribute('aria-describedby', errorID); 1040 } 1041 1042 // el.setAttribute('aria-describedby', $(el).find('.error')[0].id); 1043 parent.addClass(this.settings.error_class); 1044 if (label.length > 0 && this.settings.error_labels) { 1045 label.addClass(this.settings.error_class).attr('role', 'alert'); 1046 } 1047 $(el).triggerHandler('invalid'); 1048 } 1049 } 1050 validations = validations.concat(el_validations); 1051 } 1052 1053 return validations; 1054 }, 1055 1056 valid_checkbox : function (el, required) { 1057 var el = this.S(el), 1058 valid = (el.is(':checked') || !required || el.get(0).getAttribute('disabled')); 1059 1060 if (valid) { 1061 el.removeAttr(this.invalid_attr).parent().removeClass(this.settings.error_class); 1062 $(el).triggerHandler('valid'); 1063 } else { 1064 el.attr(this.invalid_attr, '').parent().addClass(this.settings.error_class); 1065 $(el).triggerHandler('invalid'); 1066 } 1067 1068 return valid; 1069 }, 1070 1071 valid_radio : function (el, required) { 1072 var name = el.getAttribute('name'), 1073 group = this.S(el).closest('[data-' + this.attr_name(true) + ']').find("[name='" + name + "']"), 1074 count = group.length, 1075 valid = false, 1076 disabled = false; 1077 1078 // Has to count up to make sure the focus gets applied to the top error 1079 for (var i=0; i < count; i++) { 1080 if( group[i].getAttribute('disabled') ){ 1081 disabled=true; 1082 valid=true; 1083 } else { 1084 if (group[i].checked){ 1085 valid = true; 1086 } else { 1087 if( disabled ){ 1088 valid = false; 1089 } 1090 } 1091 } 1092 } 1093 1094 // Has to count up to make sure the focus gets applied to the top error 1095 for (var i = 0; i < count; i++) { 1096 if (valid) { 1097 this.S(group[i]).removeAttr(this.invalid_attr).parent().removeClass(this.settings.error_class); 1098 $(group[i]).triggerHandler('valid'); 1099 } else { 1100 this.S(group[i]).attr(this.invalid_attr, '').parent().addClass(this.settings.error_class); 1101 $(group[i]).triggerHandler('invalid'); 1102 } 1103 } 1104 1105 return valid; 1106 }, 1107 1108 valid_equal : function (el, required, parent) { 1109 var from = document.getElementById(el.getAttribute(this.add_namespace('data-equalto'))).value, 1110 to = el.value, 1111 valid = (from === to); 1112 1113 if (valid) { 1114 this.S(el).removeAttr(this.invalid_attr); 1115 parent.removeClass(this.settings.error_class); 1116 if (label.length > 0 && settings.error_labels) { 1117 label.removeClass(this.settings.error_class); 1118 } 1119 } else { 1120 this.S(el).attr(this.invalid_attr, ''); 1121 parent.addClass(this.settings.error_class); 1122 if (label.length > 0 && settings.error_labels) { 1123 label.addClass(this.settings.error_class); 1124 } 1125 } 1126 1127 return valid; 1128 }, 1129 1130 valid_oneof : function (el, required, parent, doNotValidateOthers) { 1131 var el = this.S(el), 1132 others = this.S('[' + this.add_namespace('data-oneof') + ']'), 1133 valid = others.filter(':checked').length > 0; 1134 1135 if (valid) { 1136 el.removeAttr(this.invalid_attr).parent().removeClass(this.settings.error_class); 1137 } else { 1138 el.attr(this.invalid_attr, '').parent().addClass(this.settings.error_class); 1139 } 1140 1141 if (!doNotValidateOthers) { 1142 var _this = this; 1143 others.each(function () { 1144 _this.valid_oneof.call(_this, this, null, null, true); 1145 }); 1146 } 1147 1148 return valid; 1149 }, 1150 1151 reflow : function(scope, options) { 1152 var self = this, 1153 form = self.S('[' + this.attr_name() + ']').attr('novalidate', 'novalidate'); 1154 self.S(form).each(function (idx, el) { 1155 self.events(el); 1156 }); 1157 } 1158 }; 1159}(jQuery, window, window.document)); 1160 1161;(function ($, window, document, undefined) { 1162 'use strict'; 1163 1164 Foundation.libs.accordion = { 1165 name : 'accordion', 1166 1167 version : '5.5.3', 1168 1169 settings : { 1170 content_class : 'content', 1171 active_class : 'active', 1172 multi_expand : false, 1173 toggleable : true, 1174 callback : function () {} 1175 }, 1176 1177 init : function (scope, method, options) { 1178 this.bindings(method, options); 1179 }, 1180 1181 events : function (instance) { 1182 var self = this; 1183 var S = this.S; 1184 self.create(this.S(instance)); 1185 1186 S(this.scope) 1187 .off('.fndtn.accordion') 1188 .on('click.fndtn.accordion', '[' + this.attr_name() + '] > dd > a, [' + this.attr_name() + '] > li > a', function (e) { 1189 var accordion = S(this).closest('[' + self.attr_name() + ']'), 1190 groupSelector = self.attr_name() + '=' + accordion.attr(self.attr_name()), 1191 settings = accordion.data(self.attr_name(true) + '-init') || self.settings, 1192 target = S('#' + this.href.split('#')[1]), 1193 aunts = $('> dd, > li', accordion), 1194 siblings = aunts.children('.' + settings.content_class), 1195 active_content = siblings.filter('.' + settings.active_class); 1196 1197 e.preventDefault(); 1198 1199 if (accordion.attr(self.attr_name())) { 1200 siblings = siblings.add('[' + groupSelector + '] dd > ' + '.' + settings.content_class + ', [' + groupSelector + '] li > ' + '.' + settings.content_class); 1201 aunts = aunts.add('[' + groupSelector + '] dd, [' + groupSelector + '] li'); 1202 } 1203 1204 if (settings.toggleable && target.is(active_content)) { 1205 target.parent('dd, li').toggleClass(settings.active_class, false); 1206 target.toggleClass(settings.active_class, false); 1207 S(this).attr('aria-expanded', function(i, attr){ 1208 return attr === 'true' ? 'false' : 'true'; 1209 }); 1210 settings.callback(target); 1211 target.triggerHandler('toggled', [accordion]); 1212 accordion.triggerHandler('toggled', [target]); 1213 return; 1214 } 1215 1216 if (!settings.multi_expand) { 1217 siblings.removeClass(settings.active_class); 1218 aunts.removeClass(settings.active_class); 1219 aunts.children('a').attr('aria-expanded','false'); 1220 } 1221 1222 target.addClass(settings.active_class).parent().addClass(settings.active_class); 1223 settings.callback(target); 1224 target.triggerHandler('toggled', [accordion]); 1225 accordion.triggerHandler('toggled', [target]); 1226 S(this).attr('aria-expanded','true'); 1227 }); 1228 }, 1229 1230 create: function($instance) { 1231 var self = this, 1232 accordion = $instance, 1233 aunts = $('> .accordion-navigation', accordion), 1234 settings = accordion.data(self.attr_name(true) + '-init') || self.settings; 1235 1236 aunts.children('a').attr('aria-expanded','false'); 1237 aunts.has('.' + settings.content_class + '.' + settings.active_class).addClass(settings.active_class).children('a').attr('aria-expanded','true'); 1238 1239 if (settings.multi_expand) { 1240 $instance.attr('aria-multiselectable','true'); 1241 } 1242 }, 1243 1244 toggle : function(options) { 1245 var options = typeof options !== 'undefined' ? options : {}; 1246 var selector = typeof options.selector !== 'undefined' ? options.selector : ''; 1247 var toggle_state = typeof options.toggle_state !== 'undefined' ? options.toggle_state : ''; 1248 var $accordion = typeof options.$accordion !== 'undefined' ? options.$accordion : this.S(this.scope).closest('[' + this.attr_name() + ']'); 1249 1250 var $items = $accordion.find('> dd' + selector + ', > li' + selector); 1251 if ( $items.length < 1 ) { 1252 if ( window.console ) { 1253 console.error('Selection not found.', selector); 1254 } 1255 return false;
1256 } 1257 1258 var S = this.S; 1259 var active_class = this.settings.active_class; 1260 $items.each(function() { 1261 var $item = S(this); 1262 var is_active = $item.hasClass(active_class); 1263 if ( ( is_active && toggle_state === 'close' ) || ( !is_active && toggle_state === 'open' ) || toggle_state === '' ) { 1264 $item.find('> a').trigger('click.fndtn.accordion'); 1265 } 1266 }); 1267 }, 1268 1269 open : function(options) { 1270 var options = typeof options !== 'undefined' ? options : {}; 1271 options.toggle_state = 'open'; 1272 this.toggle(options); 1273 }, 1274 1275 close : function(options) { 1276 var options = typeof options !== 'undefined' ? options : {}; 1277 options.toggle_state = 'close'; 1278 this.toggle(options); 1279 }, 1280 1281 off : function () {}, 1282 1283 reflow : function () {} 1284 }; 1285}(jQuery, window, window.document)); 1286 1287;(function ($, window, document, undefined) { 1288 'use strict'; 1289 1290 Foundation.libs.alert = { 1291 name : 'alert', 1292 1293 version : '5.5.3', 1294 1295 settings : { 1296 callback : function () {} 1297 }, 1298 1299 init : function (scope, method, options) { 1300 this.bindings(method, options); 1301 }, 1302 1303 events : function () { 1304 var self = this, 1305 S = this.S; 1306 1307 $(this.scope).off('.alert').on('click.fndtn.alert', '[' + this.attr_name() + '] .close', function (e) { 1308 var alertBox = S(this).closest('[' + self.attr_name() + ']'), 1309 settings = alertBox.data(self.attr_name(true) + '-init') || self.settings; 1310 1311 e.preventDefault(); 1312 if (Modernizr.csstransitions) { 1313 alertBox.addClass('alert-close'); 1314 alertBox.on('transitionend webkitTransitionEnd oTransitionEnd', function (e) { 1315 S(this).trigger('close.fndtn.alert').remove(); 1316 settings.callback(); 1317 }); 1318 } else { 1319 alertBox.fadeOut(300, function () { 1320 S(this).trigger('close.fndtn.alert').remove(); 1321 settings.callback(); 1322 }); 1323 } 1324 }); 1325 }, 1326 1327 reflow : function () {} 1328 }; 1329}(jQuery, window, window.document)); 1330 1331;(function ($, window, document, undefined) { 1332 'use strict'; 1333 1334 Foundation.libs.clearing = { 1335 name : 'clearing', 1336 1337 version : '5.5.3', 1338 1339 settings : { 1340 templates : { 1341 viewing : '<a href="#" class="clearing-close">×</a>' + 1342 '<div class="visible-img" style="display: none"><div class="clearing-touch-label"></div><img src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" alt="" />' + 1343 '<p class="clearing-caption"></p><a href="#" class="clearing-main-prev"><span></span></a>' + 1344 '<a href="#" class="clearing-main-next"><span></span></a></div>' + 1345 '<img class="clearing-preload-next" style="display: none" src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" alt="" />' + 1346 '<img class="clearing-preload-prev" style="display: none" src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" alt="" />' 1347 }, 1348 1349 // comma delimited list of selectors that, on click, will close clearing, 1350 // add 'div.clearing-blackout, div.visible-img' to close on background click 1351 close_selectors : '.clearing-close, div.clearing-blackout', 1352 1353 // Default to the entire li element. 1354 open_selectors : '', 1355 1356 // Image will be skipped in carousel. 1357 skip_selector : '', 1358 1359 touch_label : '', 1360 1361 // event initializer and locks 1362 init : false, 1363 locked : false 1364 }, 1365 1366 init : function (scope, method, options) { 1367 var self = this; 1368 Foundation.inherit(this, 'throttle image_loaded'); 1369 1370 this.bindings(method, options); 1371 1372 if (self.S(this.scope).is('[' + this.attr_name() + ']')) { 1373 this.assemble(self.S('li', this.scope)); 1374 } else { 1375 self.S('[' + this.attr_name() + ']', this.scope).each(function () { 1376 self.assemble(self.S('li', this)); 1377 }); 1378 } 1379 }, 1380 1381 events : function (scope) { 1382 var self = this, 1383 S = self.S, 1384 $scroll_container = $('.scroll-container'); 1385 1386 if ($scroll_container.length > 0) { 1387 this.scope = $scroll_container; 1388 } 1389 1390 S(this.scope) 1391 .off('.clearing') 1392 .on('click.fndtn.clearing', 'ul[' + this.attr_name() + '] li ' + this.settings.open_selectors, 1393 function (e, current, target) { 1394 var current = current || S(this), 1395 target = target || current, 1396 next = current.next('li'), 1397 settings = current.closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init'), 1398 image = S(e.target); 1399 1400 e.preventDefault(); 1401 1402 if (!settings) { 1403 self.init(); 1404 settings = current.closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init'); 1405 } 1406 1407 // if clearing is open and the current image is 1408 // clicked, go to the next image in sequence 1409 if (target.hasClass('visible') && 1410 current[0] === target[0] && 1411 next.length > 0 && self.is_open(current)) { 1412 target = next; 1413 image = S('img', target); 1414 } 1415 1416 // set current and target to the clicked li if not otherwise defined. 1417 self.open(image, current, target); 1418 self.update_paddles(target); 1419 }) 1420 1421 .on('click.fndtn.clearing', '.clearing-main-next', 1422 function (e) { self.nav(e, 'next') }) 1423 .on('click.fndtn.clearing', '.clearing-main-prev', 1424 function (e) { self.nav(e, 'prev') }) 1425 .on('click.fndtn.clearing', this.settings.close_selectors, 1426 function (e) { Foundation.libs.clearing.close(e, this) }); 1427 1428 $(document).on('keydown.fndtn.clearing', 1429 function (e) { self.keydown(e) }); 1430 1431 S(window).off('.clearing').on('resize.fndtn.clearing', 1432 function () { self.resize() }); 1433 1434 this.swipe_events(scope); 1435 }, 1436 1437 swipe_events : function (scope) { 1438 var self = this, 1439 S = self.S; 1440 1441 S(this.scope) 1442 .on('touchstart.fndtn.clearing', '.visible-img', function (e) { 1443 if (!e.touches) { e = e.originalEvent; } 1444 var data = { 1445 start_page_x : e.touches[0].pageX, 1446 start_page_y : e.touches[0].pageY, 1447 start_time : (new Date()).getTime(), 1448 delta_x : 0, 1449 is_scrolling : undefined 1450 }; 1451 1452 S(this).data('swipe-transition', data); 1453 e.stopPropagation(); 1454 }) 1455 .on('touchmove.fndtn.clearing', '.visible-img', function (e) { 1456 if (!e.touches) { 1457 e = e.originalEvent; 1458 } 1459 // Ignore pinch/zoom events 1460 if (e.touches.length > 1 || e.scale && e.scale !== 1) { 1461 return; 1462 } 1463 1464 var data = S(this).data('swipe-transition'); 1465 1466 if (typeof data === 'undefined') { 1467 data = {}; 1468 } 1469 1470 data.delta_x = e.touches[0].pageX - data.start_page_x; 1471 1472 if (Foundation.rtl) { 1473 data.delta_x = -data.delta_x; 1474 } 1475 1476 if (typeof data.is_scrolling === 'undefined') { 1477 data.is_scrolling = !!( data.is_scrolling || Math.abs(data.delta_x) < Math.abs(e.touches[0].pageY - data.start_page_y) ); 1478 } 1479 1480 if (!data.is_scrolling && !data.active) { 1481 e.preventDefault(); 1482 var direction = (data.delta_x < 0) ? 'next' : 'prev'; 1483 data.active = true; 1484 self.nav(e, direction); 1485 } 1486 }) 1487 .on('touchend.fndtn.clearing', '.visible-img', function (e) { 1488 S(this).data('swipe-transition', {}); 1489 e.stopPropagation(); 1490 }); 1491 }, 1492 1493 assemble : function ($li) { 1494 var $el = $li.parent(); 1495 1496 if ($el.parent().hasClass('carousel')) { 1497 return; 1498 } 1499 1500 $el.after('<div id="foundationClearingHolder"></div>'); 1501 1502 var grid = $el.detach(), 1503 grid_outerHTML = ''; 1504 1505 if (grid[0] == null) { 1506 return; 1507 } else {
1508 grid_outerHTML = grid[0].outerHTML; 1509 } 1510 1511 var holder = this.S('#foundationClearingHolder'), 1512 settings = $el.data(this.attr_name(true) + '-init'), 1513 data = { 1514 grid : '<div class="carousel">' + grid_outerHTML + '</div>', 1515 viewing : settings.templates.viewing 1516 }, 1517 wrapper = '<div class="clearing-assembled"><div>' + data.viewing + 1518 data.grid + '</div></div>', 1519 touch_label = this.settings.touch_label; 1520 1521 if (Modernizr.touch) { 1522 wrapper = $(wrapper).find('.clearing-touch-label').html(touch_label).end(); 1523 } 1524 1525 holder.after(wrapper).remove(); 1526 }, 1527 1528 open : function ($image, current, target) { 1529 var self = this, 1530 body = $(document.body), 1531 root = target.closest('.clearing-assembled'), 1532 container = self.S('div', root).first(), 1533 visible_image = self.S('.visible-img', container), 1534 image = self.S('img', visible_image).not($image), 1535 label = self.S('.clearing-touch-label', container), 1536 error = false, 1537 loaded = {}; 1538 1539 // Event to disable scrolling on touch devices when Clearing is activated 1540 $('body').on('touchmove', function (e) { 1541 e.preventDefault(); 1542 }); 1543 1544 image.error(function () { 1545 error = true; 1546 }); 1547 1548 function startLoad() { 1549 setTimeout(function () { 1550 this.image_loaded(image, function () { 1551 if (image.outerWidth() === 1 && !error) { 1552 startLoad.call(this); 1553 } else { 1554 cb.call(this, image); 1555 } 1556 }.bind(this)); 1557 }.bind(this), 100); 1558 } 1559 1560 function cb (image) { 1561 var $image = $(image); 1562 $image.css('visibility', 'visible'); 1563 $image.trigger('imageVisible'); 1564 // toggle the gallery 1565 body.css('overflow', 'hidden'); 1566 root.addClass('clearing-blackout'); 1567 container.addClass('clearing-container'); 1568 visible_image.show(); 1569 this.fix_height(target) 1570 .caption(self.S('.clearing-caption', visible_image), self.S('img', target)) 1571 .center_and_label(image, label) 1572 .shift(current, target, function () { 1573 target.closest('li').siblings().removeClass('visible'); 1574 target.closest('li').addClass('visible'); 1575 }); 1576 visible_image.trigger('opened.fndtn.clearing') 1577 } 1578 1579 if (!this.locked()) { 1580 visible_image.trigger('open.fndtn.clearing'); 1581 // set the image to the selected thumbnail 1582 loaded = this.load($image); 1583 if (loaded.interchange) { 1584 image 1585 .attr('data-interchange', loaded.interchange) 1586 .foundation('interchange', 'reflow'); 1587 } else { 1588 image 1589 .attr('src', loaded.src) 1590 .attr('data-interchange', ''); 1591 } 1592 image.css('visibility', 'hidden'); 1593 1594 startLoad.call(this); 1595 } 1596 }, 1597 1598 close : function (e, el) { 1599 e.preventDefault(); 1600 1601 var root = (function (target) { 1602 if (/blackout/.test(target.selector)) { 1603 return target; 1604 } else { 1605 return target.closest('.clearing-blackout'); 1606 } 1607 }($(el))), 1608 body = $(document.body), container, visible_image; 1609 1610 if (el === e.target && root) { 1611 body.css('overflow', ''); 1612 container = $('div', root).first(); 1613 visible_image = $('.visible-img', container); 1614 visible_image.trigger('close.fndtn.clearing'); 1615 this.settings.prev_index = 0; 1616 $('ul[' + this.attr_name() + ']', root) 1617 .attr('style', '').closest('.clearing-blackout') 1618 .removeClass('clearing-blackout'); 1619 container.removeClass('clearing-container'); 1620 visible_image.hide(); 1621 visible_image.trigger('closed.fndtn.clearing'); 1622 } 1623 1624 // Event to re-enable scrolling on touch devices 1625 $('body').off('touchmove'); 1626 1627 return false; 1628 }, 1629 1630 is_open : function (current) { 1631 return current.parent().prop('style').length > 0; 1632 }, 1633 1634 keydown : function (e) { 1635 var clearing = $('.clearing-blackout ul[' + this.attr_name() + ']'), 1636 NEXT_KEY = this.rtl ? 37 : 39, 1637 PREV_KEY = this.rtl ? 39 : 37, 1638 ESC_KEY = 27; 1639 1640 if (e.which === NEXT_KEY) { 1641 this.go(clearing, 'next'); 1642 } 1643 if (e.which === PREV_KEY) { 1644 this.go(clearing, 'prev'); 1645 } 1646 if (e.which === ESC_KEY) { 1647 this.S('a.clearing-close').trigger('click.fndtn.clearing'); 1648 } 1649 }, 1650 1651 nav : function (e, direction) { 1652 var clearing = $('ul[' + this.attr_name() + ']', '.clearing-blackout'); 1653 1654 e.preventDefault(); 1655 this.go(clearing, direction); 1656 }, 1657 1658 resize : function () { 1659 var image = $('img', '.clearing-blackout .visible-img'), 1660 label = $('.clearing-touch-label', '.clearing-blackout'); 1661 1662 if (image.length) { 1663 this.center_and_label(image, label); 1664 image.trigger('resized.fndtn.clearing') 1665 } 1666 }, 1667 1668 // visual adjustments 1669 fix_height : function (target) { 1670 var lis = target.parent().children(), 1671 self = this; 1672 1673 lis.each(function () { 1674 var li = self.S(this), 1675 image = li.find('img'); 1676 1677 if (li.height() > image.outerHeight()) { 1678 li.addClass('fix-height'); 1679 } 1680 }) 1681 .closest('ul') 1682 .width(lis.length * 100 + '%'); 1683 1684 return this; 1685 }, 1686 1687 update_paddles : function (target) { 1688 target = target.closest('li'); 1689 var visible_image = target 1690 .closest('.carousel') 1691 .siblings('.visible-img'); 1692 1693 if (target.next().length > 0) { 1694 this.S('.clearing-main-next', visible_image).removeClass('disabled'); 1695 } else { 1696 this.S('.clearing-main-next', visible_image).addClass('disabled'); 1697 } 1698 1699 if (target.prev().length > 0) { 1700 this.S('.clearing-main-prev', visible_image).removeClass('disabled'); 1701 } else { 1702 this.S('.clearing-main-prev', visible_image).addClass('disabled'); 1703 } 1704 }, 1705 1706 center_and_label : function (target, label) { 1707 if (!this.rtl && label.length > 0) { 1708 label.css({ 1709 marginLeft : -(label.outerWidth() / 2), 1710 marginTop : -(target.outerHeight() / 2)-label.outerHeight()-10 1711 }); 1712 } else { 1713 label.css({ 1714 marginRight : -(label.outerWidth() / 2), 1715 marginTop : -(target.outerHeight() / 2)-label.outerHeight()-10, 1716 left: 'auto', 1717 right: '50%' 1718 }); 1719 } 1720 return this; 1721 }, 1722 1723 // image loading and preloading 1724 1725 load : function ($image) { 1726 var href, 1727 interchange, 1728 closest_a; 1729 1730 if ($image[0].nodeName === 'A') { 1731 href = $image.attr('href'); 1732 interchange = $image.data('clearing-interchange'); 1733 } else { 1734 closest_a = $image.closest('a'); 1735 href = closest_a.attr('href'); 1736 interchange = closest_a.data('clearing-interchange'); 1737 } 1738 1739 this.preload($image); 1740 1741 return { 1742 'src': href ? href : $image.attr('src'), 1743 'interchange': href ? interchange : $image.data('clearing-interchange') 1744 } 1745 }, 1746 1747 preload : function ($image) { 1748 this 1749 .img($image.closest('li').next(), 'next') 1750 .img($image.closest('li').prev(), 'prev'); 1751 }, 1752 1753 img : function (img, sibling_type) { 1754 if (img.length) { 1755 var preload_img = $('.clearing-preload-' + sibling_type), 1756 new_a = this.S('a', img), 1757 src, 1758 interchange, 1759 image; 1760 1761 if (new_a.length) { 1762 src = new_a.attr('href'); 1763 interchange = new_a.data('clearing-interchange'); 1764 } else { 1765 image = this.S('img', img); 1766 src = image.attr('src'); 1767 interchange = image.data('clearing-interchange'); 1768 } 1769 1770 if (interchange) { 1771 preload_img.attr('data-interchange', interchange); 1772 } else { 1773 preload_img.attr('src', src); 1774 preload_img.attr('data-interchange', ''); 1775 } 1776 } 1777 return this; 1778 }, 1779 1780 // image caption 1781 1782 caption : function (container, $image) { 1783 var caption = $image.attr('data-caption'); 1784 1785 if (caption) {
1786 var containerPlain = container.get(0); 1787 containerPlain.innerHTML = caption; 1788 container.show(); 1789 } else { 1790 container 1791 .text('') 1792 .hide(); 1793 } 1794 return this; 1795 }, 1796 1797 // directional methods 1798 1799 go : function ($ul, direction) { 1800 var current = this.S('.visible', $ul), 1801 target = current[direction](); 1802 1803 // Check for skip selector. 1804 if (this.settings.skip_selector && target.find(this.settings.skip_selector).length != 0) { 1805 target = target[direction](); 1806 } 1807 1808 if (target.length) { 1809 this.S('img', target) 1810 .trigger('click.fndtn.clearing', [current, target]) 1811 .trigger('change.fndtn.clearing'); 1812 } 1813 }, 1814 1815 shift : function (current, target, callback) { 1816 var clearing = target.parent(), 1817 old_index = this.settings.prev_index || target.index(), 1818 direction = this.direction(clearing, current, target), 1819 dir = this.rtl ? 'right' : 'left', 1820 left = parseInt(clearing.css('left'), 10), 1821 width = target.outerWidth(), 1822 skip_shift; 1823 1824 var dir_obj = {}; 1825 1826 // we use jQuery animate instead of CSS transitions because we 1827 // need a callback to unlock the next animation 1828 // needs support for RTL ** 1829 if (target.index() !== old_index && !/skip/.test(direction)) { 1830 if (/left/.test(direction)) { 1831 this.lock(); 1832 dir_obj[dir] = left + width; 1833 clearing.animate(dir_obj, 300, this.unlock()); 1834 } else if (/right/.test(direction)) { 1835 this.lock(); 1836 dir_obj[dir] = left - width; 1837 clearing.animate(dir_obj, 300, this.unlock()); 1838 } 1839 } else if (/skip/.test(direction)) { 1840 // the target image is not adjacent to the current image, so 1841 // do we scroll right or not 1842 skip_shift = target.index() - this.settings.up_count; 1843 this.lock(); 1844 1845 if (skip_shift > 0) { 1846 dir_obj[dir] = -(skip_shift * width); 1847 clearing.animate(dir_obj, 300, this.unlock()); 1848 } else { 1849 dir_obj[dir] = 0; 1850 clearing.animate(dir_obj, 300, this.unlock()); 1851 } 1852 } 1853 1854 callback(); 1855 }, 1856 1857 direction : function ($el, current, target) { 1858 var lis = this.S('li', $el), 1859 li_width = lis.outerWidth() + (lis.outerWidth() / 4), 1860 up_count = Math.floor(this.S('.clearing-container').outerWidth() / li_width) - 1, 1861 target_index = lis.index(target), 1862 response; 1863 1864 this.settings.up_count = up_count; 1865 1866 if (this.adjacent(this.settings.prev_index, target_index)) { 1867 if ((target_index > up_count) && target_index > this.settings.prev_index) { 1868 response = 'right'; 1869 } else if ((target_index > up_count - 1) && target_index <= this.settings.prev_index) { 1870 response = 'left'; 1871 } else { 1872 response = false; 1873 } 1874 } else { 1875 response = 'skip'; 1876 } 1877 1878 this.settings.prev_index = target_index; 1879 1880 return response; 1881 }, 1882 1883 adjacent : function (current_index, target_index) { 1884 for (var i = target_index + 1; i >= target_index - 1; i--) { 1885 if (i === current_index) { 1886 return true; 1887 } 1888 } 1889 return false; 1890 }, 1891 1892 // lock management 1893 1894 lock : function () { 1895 this.settings.locked = true; 1896 }, 1897 1898 unlock : function () { 1899 this.settings.locked = false; 1900 }, 1901 1902 locked : function () { 1903 return this.settings.locked; 1904 }, 1905 1906 off : function () { 1907 this.S(this.scope).off('.fndtn.clearing'); 1908 this.S(window).off('.fndtn.clearing'); 1909 }, 1910 1911 reflow : function () { 1912 this.init(); 1913 } 1914 }; 1915 1916}(jQuery, window, window.document)); 1917 1918;(function ($, window, document, undefined) { 1919 'use strict'; 1920 1921 Foundation.libs.dropdown = { 1922 name : 'dropdown', 1923 1924 version : '5.5.3', 1925 1926 settings : { 1927 active_class : 'open', 1928 disabled_class : 'disabled', 1929 mega_class : 'mega', 1930 align : 'bottom', 1931 is_hover : false, 1932 hover_timeout : 150, 1933 opened : function () {}, 1934 closed : function () {} 1935 }, 1936 1937 init : function (scope, method, options) { 1938 Foundation.inherit(this, 'throttle'); 1939 1940 $.extend(true, this.settings, method, options); 1941 this.bindings(method, options); 1942 }, 1943 1944 events : function (scope) { 1945 var self = this, 1946 S = self.S; 1947 1948 S(this.scope) 1949 .off('.dropdown') 1950 .on('click.fndtn.dropdown', '[' + this.attr_name() + ']', function (e) { 1951 var settings = S(this).data(self.attr_name(true) + '-init') || self.settings; 1952 if (!settings.is_hover || Modernizr.touch) { 1953 e.preventDefault(); 1954 if (S(this).parent('[data-reveal-id]').length) { 1955 e.stopPropagation(); 1956 } 1957 self.toggle($(this)); 1958 } 1959 }) 1960 .on('mouseenter.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) { 1961 var $this = S(this), 1962 dropdown, 1963 target; 1964 1965 clearTimeout(self.timeout); 1966 1967 if ($this.data(self.data_attr())) { 1968 dropdown = S('#' + $this.data(self.data_attr())); 1969 target = $this; 1970 } else { 1971 dropdown = $this; 1972 target = S('[' + self.attr_name() + '="' + dropdown.attr('id') + '"]'); 1973 } 1974 1975 var settings = target.data(self.attr_name(true) + '-init') || self.settings; 1976 1977 if (S(e.currentTarget).data(self.data_attr()) && settings.is_hover) { 1978 self.closeall.call(self); 1979 } 1980 1981 if (settings.is_hover) { 1982 self.open.apply(self, [dropdown, target]); 1983 } 1984 }) 1985 .on('mouseleave.fndtn.dropdown', '[' + this.attr_name() + '], [' + this.attr_name() + '-content]', function (e) { 1986 var $this = S(this); 1987 var settings; 1988 1989 if ($this.data(self.data_attr())) { 1990 settings = $this.data(self.data_attr(true) + '-init') || self.settings; 1991 } else { 1992 var target = S('[' + self.attr_name() + '="' + S(this).attr('id') + '"]'), 1993 settings = target.data(self.attr_name(true) + '-init') || self.settings; 1994 } 1995 1996 self.timeout = setTimeout(function () { 1997 if ($this.data(self.data_attr())) { 1998 if (settings.is_hover) { 1999 self.close.call(self, S('#' + $this.data(self.data_attr()))); 2000 } 2001 } else { 2002 if (settings.is_hover) { 2003 self.close.call(self, $this); 2004 } 2005 } 2006 }.bind(this), settings.hover_timeout); 2007 }) 2008 .on('click.fndtn.dropdown', function (e) { 2009 var parent = S(e.target).closest('[' + self.attr_name() + '-content]'); 2010 var links = parent.find('a'); 2011 2012 if (links.length > 0 && parent.attr('aria-autoclose') !== 'false') { 2013 self.close.call(self, S('[' + self.attr_name() + '-content]')); 2014 } 2015 2016 if (e.target !== document && !$.contains(document.documentElement, e.target)) { 2017 return; 2018 } 2019 2020 if (S(e.target).closest('[' + self.attr_name() + ']').length > 0) { 2021 return; 2022 } 2023 2024 if (!(S(e.target).data('revealId')) && 2025 (parent.length > 0 && (S(e.target).is('[' + self.attr_name() + '-content]') || 2026 $.contains(parent.first()[0], e.target)))) { 2027 e.stopPropagation(); 2028 return; 2029 } 2030 2031 self.close.call(self, S('[' + self.attr_name() + '-content]')); 2032 }) 2033 .on('opened.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () {
2034 self.settings.opened.call(this); 2035 }) 2036 .on('closed.fndtn.dropdown', '[' + self.attr_name() + '-content]', function () { 2037 self.settings.closed.call(this); 2038 }); 2039 2040 S(window) 2041 .off('.dropdown') 2042 .on('resize.fndtn.dropdown', self.throttle(function () { 2043 self.resize.call(self); 2044 }, 50)); 2045 2046 this.resize(); 2047 }, 2048 2049 close : function (dropdown) { 2050 var self = this; 2051 dropdown.each(function (idx) { 2052 var original_target = $('[' + self.attr_name() + '=' + dropdown[idx].id + ']') || $('aria-controls=' + dropdown[idx].id + ']'); 2053 original_target.attr('aria-expanded', 'false'); 2054 if (self.S(this).hasClass(self.settings.active_class)) { 2055 self.S(this) 2056 .css(Foundation.rtl ? 'right' : 'left', '-99999px') 2057 .attr('aria-hidden', 'true') 2058 .removeClass(self.settings.active_class) 2059 .prev('[' + self.attr_name() + ']') 2060 .removeClass(self.settings.active_class) 2061 .removeData('target'); 2062 2063 self.S(this).trigger('closed.fndtn.dropdown', [dropdown]); 2064 } 2065 }); 2066 dropdown.removeClass('f-open-' + this.attr_name(true)); 2067 }, 2068 2069 closeall : function () { 2070 var self = this; 2071 $.each(self.S('.f-open-' + this.attr_name(true)), function () { 2072 self.close.call(self, self.S(this)); 2073 }); 2074 }, 2075 2076 open : function (dropdown, target) { 2077 this 2078 .css(dropdown 2079 .addClass(this.settings.active_class), target); 2080 dropdown.prev('[' + this.attr_name() + ']').addClass(this.settings.active_class); 2081 dropdown.data('target', target.get(0)).trigger('opened.fndtn.dropdown', [dropdown, target]); 2082 dropdown.attr('aria-hidden', 'false'); 2083 target.attr('aria-expanded', 'true'); 2084 dropdown.focus(); 2085 dropdown.addClass('f-open-' + this.attr_name(true)); 2086 }, 2087 2088 data_attr : function () { 2089 if (this.namespace.length > 0) { 2090 return this.namespace + '-' + this.name; 2091 } 2092 2093 return this.name; 2094 }, 2095 2096 toggle : function (target) { 2097 if (target.hasClass(this.settings.disabled_class)) { 2098 return; 2099 } 2100 var dropdown = this.S('#' + target.data(this.data_attr())); 2101 if (dropdown.length === 0) { 2102 // No dropdown found, not continuing 2103 return; 2104 } 2105 2106 this.close.call(this, this.S('[' + this.attr_name() + '-content]').not(dropdown)); 2107 2108 if (dropdown.hasClass(this.settings.active_class)) { 2109 this.close.call(this, dropdown); 2110 if (dropdown.data('target') !== target.get(0)) { 2111 this.open.call(this, dropdown, target); 2112 } 2113 } else { 2114 this.open.call(this, dropdown, target); 2115 } 2116 }, 2117 2118 resize : function () { 2119 var dropdown = this.S('[' + this.attr_name() + '-content].open'); 2120 var target = $(dropdown.data("target")); 2121 2122 if (dropdown.length && target.length) { 2123 this.css(dropdown, target); 2124 } 2125 }, 2126 2127 css : function (dropdown, target) { 2128 var left_offset = Math.max((target.width() - dropdown.width()) / 2, 8), 2129 settings = target.data(this.attr_name(true) + '-init') || this.settings, 2130 parentOverflow = dropdown.parent().css('overflow-y') || dropdown.parent().css('overflow'); 2131 2132 this.clear_idx(); 2133 2134 2135 2136 if (this.small()) { 2137 var p = this.dirs.bottom.call(dropdown, target, settings); 2138 2139 dropdown.attr('style', '').removeClass('drop-left drop-right drop-top').css({ 2140 position : 'absolute', 2141 width : '95%', 2142 'max-width' : 'none', 2143 top : p.top 2144 }); 2145 2146 dropdown.css(Foundation.rtl ? 'right' : 'left', left_offset); 2147 } 2148 // detect if dropdown is in an overflow container 2149 else if (parentOverflow !== 'visible') { 2150 var offset = target[0].offsetTop + target[0].offsetHeight; 2151 2152 dropdown.attr('style', '').css({ 2153 position : 'absolute', 2154 top : offset 2155 }); 2156 2157 dropdown.css(Foundation.rtl ? 'right' : 'left', left_offset); 2158 } 2159 else { 2160 2161 this.style(dropdown, target, settings); 2162 } 2163 2164 return dropdown; 2165 }, 2166 2167 style : function (dropdown, target, settings) { 2168 var css = $.extend({position : 'absolute'}, 2169 this.dirs[settings.align].call(dropdown, target, settings)); 2170 2171 dropdown.attr('style', '').css(css); 2172 }, 2173 2174 // return CSS property object 2175 // `this` is the dropdown 2176 dirs : { 2177 // Calculate target offset 2178 _base : function (t, s) { 2179 var o_p = this.offsetParent(), 2180 o = o_p.offset(), 2181 p = t.offset(); 2182 2183 p.top -= o.top; 2184 p.left -= o.left; 2185 2186 //set some flags on the p object to pass along 2187 p.missRight = false;
2188 p.missTop = false; 2189 p.missLeft = false; 2190 p.leftRightFlag = false; 2191 2192 //lets see if the panel will be off the screen 2193 //get the actual width of the page and store it 2194 var actualBodyWidth; 2195 var windowWidth = window.innerWidth; 2196 2197 if (document.getElementsByClassName('row')[0]) { 2198 actualBodyWidth = document.getElementsByClassName('row')[0].clientWidth; 2199 } else { 2200 actualBodyWidth = windowWidth; 2201 } 2202 2203 var actualMarginWidth = (windowWidth - actualBodyWidth) / 2; 2204 var actualBoundary = actualBodyWidth; 2205 2206 if (!this.hasClass('mega') && !s.ignore_repositioning) { 2207 var outerWidth = this.outerWidth(); 2208 var o_left = t.offset().left; 2209 2210 //miss top 2211 if (t.offset().top <= this.outerHeight()) { 2212 p.missTop = true; 2213 actualBoundary = windowWidth - actualMarginWidth; 2214 p.leftRightFlag = true; 2215 } 2216 2217 //miss right 2218 if (o_left + outerWidth > o_left + actualMarginWidth && o_left - actualMarginWidth > outerWidth) { 2219 p.missRight = true; 2220 p.missLeft = false; 2221 } 2222 2223 //miss left 2224 if (o_left - outerWidth <= 0) { 2225 p.missLeft = true; 2226 p.missRight = false; 2227 } 2228 } 2229 2230 return p; 2231 }, 2232 2233 top : function (t, s) { 2234 var self = Foundation.libs.dropdown, 2235 p = self.dirs._base.call(this, t, s); 2236 2237 this.addClass('drop-top'); 2238 2239 if (p.missTop == true) { 2240 p.top = p.top + t.outerHeight() + this.outerHeight(); 2241 this.removeClass('drop-top'); 2242 } 2243 2244 if (p.missRight == true) { 2245 p.left = p.left - this.outerWidth() + t.outerWidth(); 2246 } 2247 2248 if (t.outerWidth() < this.outerWidth() || self.small() || this.hasClass(s.mega_menu)) { 2249 self.adjust_pip(this, t, s, p); 2250 } 2251 2252 if (Foundation.rtl) { 2253 return {left : p.left - this.outerWidth() + t.outerWidth(), 2254 top : p.top - this.outerHeight()}; 2255 } 2256 2257 return {left : p.left, top : p.top - this.outerHeight()}; 2258 }, 2259 2260 bottom : function (t, s) { 2261 var self = Foundation.libs.dropdown, 2262 p = self.dirs._base.call(this, t, s); 2263 2264 if (p.missRight == true) { 2265 p.left = p.left - this.outerWidth() + t.outerWidth(); 2266 } 2267 2268 if (t.outerWidth() < this.outerWidth() || self.small() || this.hasClass(s.mega_menu)) { 2269 self.adjust_pip(this, t, s, p); 2270 } 2271 2272 if (self.rtl) { 2273 return {left : p.left - this.outerWidth() + t.outerWidth(), top : p.top + t.outerHeight()}; 2274 } 2275 2276 return {left : p.left, top : p.top + t.outerHeight()}; 2277 }, 2278 2279 left : function (t, s) { 2280 var p = Foundation.libs.dropdown.dirs._base.call(this, t, s); 2281 2282 this.addClass('drop-left'); 2283 2284 if (p.missLeft == true) { 2285 p.left = p.left + this.outerWidth(); 2286 p.top = p.top + t.outerHeight(); 2287 this.removeClass('drop-left'); 2288 } 2289 2290 return {left : p.left - this.outerWidth(), top : p.top}; 2291 }, 2292 2293 right : function (t, s) { 2294 var p = Foundation.libs.dropdown.dirs._base.call(this, t, s); 2295 2296 this.addClass('drop-right'); 2297 2298 if (p.missRight == true) { 2299 p.left = p.left - this.outerWidth(); 2300 p.top = p.top + t.outerHeight(); 2301 this.removeClass('drop-right'); 2302 } else { 2303 p.triggeredRight = true; 2304 } 2305 2306 var self = Foundation.libs.dropdown; 2307 2308 if (t.outerWidth() < this.outerWidth() || self.small() || this.hasClass(s.mega_menu)) { 2309 self.adjust_pip(this, t, s, p); 2310 } 2311 2312 return {left : p.left + t.outerWidth(), top : p.top}; 2313 } 2314 }, 2315 2316 // Insert rule to style psuedo elements 2317 adjust_pip : function (dropdown, target, settings, position) { 2318 var sheet = Foundation.stylesheet, 2319 pip_offset_base = 8; 2320 2321 if (dropdown.hasClass(settings.mega_class)) { 2322 pip_offset_base = position.left + (target.outerWidth() / 2) - 8; 2323 }
2323 else if (this.small()) { 2324 pip_offset_base += position.left - 8; 2325 } 2326 2327 this.rule_idx = sheet.cssRules.length; 2328 2329 //default 2330 var sel_before = '.f-dropdown.open:before', 2331 sel_after = '.f-dropdown.open:after', 2332 css_before = 'left: ' + pip_offset_base + 'px;', 2333 css_after = 'left: ' + (pip_offset_base - 1) + 'px;'; 2334 2335 if (position.missRight == true) { 2336 pip_offset_base = dropdown.outerWidth() - 23; 2337 sel_before = '.f-dropdown.open:before', 2338 sel_after = '.f-dropdown.open:after', 2339 css_before = 'left: ' + pip_offset_base + 'px;', 2340 css_after = 'left: ' + (pip_offset_base - 1) + 'px;'; 2341 } 2342 2343 //just a case where right is fired, but its not missing right 2344 if (position.triggeredRight == true) { 2345 sel_before = '.f-dropdown.open:before', 2346 sel_after = '.f-dropdown.open:after', 2347 css_before = 'left:-12px;', 2348 css_after = 'left:-14px;'; 2349 } 2350 2351 if (sheet.insertRule) { 2352 sheet.insertRule([sel_before, '{', css_before, '}'].join(' '), this.rule_idx); 2353 sheet.insertRule([sel_after, '{', css_after, '}'].join(' '), this.rule_idx + 1); 2354 } else { 2355 sheet.addRule(sel_before, css_before, this.rule_idx); 2356 sheet.addRule(sel_after, css_after, this.rule_idx + 1); 2357 } 2358 }, 2359 2360 // Remove old dropdown rule index 2361 clear_idx : function () { 2362 var sheet = Foundation.stylesheet; 2363 2364 if (typeof this.rule_idx !== 'undefined') { 2365 sheet.deleteRule(this.rule_idx); 2366 sheet.deleteRule(this.rule_idx); 2367 delete this.rule_idx; 2368 } 2369 }, 2370 2371 small : function () { 2372 return matchMedia(Foundation.media_queries.small).matches && 2373 !matchMedia(Foundation.media_queries.medium).matches; 2374 }, 2375 2376 off : function () { 2377 this.S(this.scope).off('.fndtn.dropdown'); 2378 this.S('html, body').off('.fndtn.dropdown'); 2379 this.S(window).off('.fndtn.dropdown'); 2380 this.S('[data-dropdown-content]').off('.fndtn.dropdown'); 2381 }, 2382 2383 reflow : function () {} 2384 }; 2385}(jQuery, window, window.document)); 2386 2387;(function ($, window, document, undefined) { 2388 'use strict'; 2389 2390 Foundation.libs.equalizer = { 2391 name : 'equalizer', 2392 2393 version : '5.5.3', 2394 2395 settings : { 2396 use_tallest : true, 2397 before_height_change : $.noop, 2398 after_height_change : $.noop, 2399 equalize_on_stack : false, 2400 act_on_hidden_el: false 2401 }, 2402 2403 init : function (scope, method, options) { 2404 Foundation.inherit(this, 'image_loaded'); 2405 this.bindings(method, options); 2406 this.reflow(); 2407 }, 2408 2409 events : function () { 2410 this.S(window).off('.equalizer').on('resize.fndtn.equalizer', function (e) { 2411 this.reflow(); 2412 }.bind(this)); 2413 }, 2414 2415 equalize : function (equalizer) { 2416 var isStacked = false, 2417 group = equalizer.data('equalizer'), 2418 settings = equalizer.data(this.attr_name(true)+'-init') || this.settings, 2419 vals, 2420 firstTopOffset; 2421 2422 if (settings.act_on_hidden_el) { 2423 vals = group ? equalizer.find('['+this.attr_name()+'-watch="'+group+'"]') : equalizer.find('['+this.attr_name()+'-watch]'); 2424 } 2425 else { 2426 vals = group ? equalizer.find('['+this.attr_name()+'-watch="'+group+'"]:visible') : equalizer.find('['+this.attr_name()+'-watch]:visible'); 2427 } 2428 2429 if (vals.length === 0) { 2430 return; 2431 } 2432 2433 settings.before_height_change(); 2434 equalizer.trigger('before-height-change.fndth.equalizer'); 2435 vals.height('inherit'); 2436 2437 if (settings.equalize_on_stack === false) { 2438 firstTopOffset = vals.first().offset().top; 2439 vals.each(function () { 2440 if ($(this).offset().top !== firstTopOffset) { 2441 isStacked = true; 2442 return false; 2443 } 2444 }); 2445 if (isStacked) { 2446 return; 2447 } 2448 } 2449 2450 var heights = vals.map(function () { return $(this).outerHeight(false) }).get(); 2451 2452 if (settings.use_tallest) { 2453 var max = Math.max.apply(null, heights); 2454 vals.css('height', max); 2455 } else { 2456 var min = Math.min.apply(null, heights); 2457 vals.css('height', min); 2458 } 2459 2460 settings.after_height_change(); 2461 equalizer.trigger('after-height-change.fndtn.equalizer'); 2462 }, 2463 2464 reflow : function () { 2465 var self = this; 2466 2467 this.S('[' + this.attr_name() + ']', this.scope).each(function () { 2468 var $eq_target = $(this), 2469 media_query = $eq_target.data('equalizer-mq'), 2470 ignore_media_query = true; 2471 2472 if (media_query) { 2473 media_query = 'is_' + media_query.replace(/-/g, '_'); 2474 if (Foundation.utils.hasOwnProperty(media_query)) { 2475 ignore_media_query = false;
2476 } 2477 } 2478 2479 self.image_loaded(self.S('img', this), function () { 2480 if (ignore_media_query || Foundation.utils[media_query]()) { 2481 self.equalize($eq_target) 2482 } else { 2483 var vals = $eq_target.find('[' + self.attr_name() + '-watch]:visible'); 2484 vals.css('height', 'auto'); 2485 } 2486 }); 2487 }); 2488 } 2489 }; 2490})(jQuery, window, window.document); 2491 2492;(function ($, window, document, undefined) { 2493 'use strict'; 2494 2495 Foundation.libs.interchange = { 2496 name : 'interchange', 2497 2498 version : '5.5.3', 2499 2500 cache : {}, 2501 2502 images_loaded : false, 2503 nodes_loaded : false, 2504 2505 settings : { 2506 load_attr : 'interchange', 2507 2508 named_queries : { 2509 'default' : 'only screen', 2510 'small' : Foundation.media_queries['small'], 2511 'small-only' : Foundation.media_queries['small-only'], 2512 'medium' : Foundation.media_queries['medium'], 2513 'medium-only' : Foundation.media_queries['medium-only'], 2514 'large' : Foundation.media_queries['large'], 2515 'large-only' : Foundation.media_queries['large-only'], 2516 'xlarge' : Foundation.media_queries['xlarge'], 2517 'xlarge-only' : Foundation.media_queries['xlarge-only'], 2518 'xxlarge' : Foundation.media_queries['xxlarge'], 2519 'landscape' : 'only screen and (orientation: landscape)', 2520 'portrait' : 'only screen and (orientation: portrait)', 2521 'retina' : 'only screen and (-webkit-min-device-pixel-ratio: 2),' + 2522 'only screen and (min--moz-device-pixel-ratio: 2),' + 2523 'only screen and (-o-min-device-pixel-ratio: 2/1),' + 2524 'only screen and (min-device-pixel-ratio: 2),' + 2525 'only screen and (min-resolution: 192dpi),' + 2526 'only screen and (min-resolution: 2dppx)' 2527 }, 2528 2529 directives : { 2530 replace : function (el, path, trigger) { 2531 // The trigger argument, if called within the directive, fires 2532 // an event named after the directive on the element, passing 2533 // any parameters along to the event that you pass to trigger. 2534 // 2535 // ex. trigger(), trigger([a, b, c]), or trigger(a, b, c) 2536 // 2537 // This allows you to bind a callback like so: 2538 // $('#interchangeContainer').on('replace', function (e, a, b, c) { 2539 // console.log($(this).html(), a, b, c); 2540 // }); 2541 2542 if (el !== null && /IMG/.test(el[0].nodeName)) { 2543 var orig_path = $.each(el, function(){this.src = path;}); 2544 // var orig_path = el[0].src; 2545 2546 if (new RegExp(path, 'i').test(orig_path)) { 2547 return; 2548 } 2549 2550 el.attr("src", path); 2551 2552 return trigger(el[0].src); 2553 } 2554 var last_path = el.data(this.data_attr + '-last-path'), 2555 self = this; 2556 2557 if (last_path == path) { 2558 return; 2559 } 2560 2561 if (/\.(gif|jpg|jpeg|tiff|png)([?#].*)?/i.test(path)) { 2562 $(el).css('background-image', 'url(' + path + ')'); 2563 el.data('interchange-last-path', path); 2564 return trigger(path); 2565 } 2566 2567 return $.get(path, function (response) { 2568 el.html(response); 2569 el.data(self.data_attr + '-last-path', path); 2570 trigger(); 2571 }); 2572 2573 } 2574 } 2575 }, 2576 2577 init : function (scope, method, options) { 2578 Foundation.inherit(this, 'throttle random_str'); 2579 2580 this.data_attr = this.set_data_attr(); 2581 $.extend(true, this.settings, method, options); 2582 this.bindings(method, options); 2583 this.reflow(); 2584 }, 2585 2586 get_media_hash : function () { 2587 var mediaHash = ''; 2588 for (var queryName in this.settings.named_queries ) { 2589 mediaHash += matchMedia(this.settings.named_queries[queryName]).matches.toString(); 2590 } 2591 return mediaHash; 2592 }, 2593 2594 events : function () { 2595 var self = this, prevMediaHash; 2596 2597 $(window) 2598 .off('.interchange') 2599 .on('resize.fndtn.interchange', self.throttle(function () { 2600 var currMediaHash = self.get_media_hash(); 2601 if (currMediaHash !== prevMediaHash) { 2602 self.resize(); 2603 } 2604 prevMediaHash = currMediaHash; 2605 }, 50)); 2606 2607 return this; 2608 }, 2609 2610 resize : function () { 2611 var cache = this.cache; 2612 2613 if (!this.images_loaded || !this.nodes_loaded) { 2614 setTimeout($.proxy(this.resize, this), 50); 2615 return; 2616 } 2617 2618 for (var uuid in cache) { 2619 if (cache.hasOwnProperty(uuid)) { 2620 var passed = this.results(uuid, cache[uuid]); 2621 if (passed) { 2622 this.settings.directives[passed 2623 .scenario[1]].call(this, passed.el, passed.scenario[0], (function (passed) { 2624 if (arguments[0] instanceof Array) { 2625 var args = arguments[0]; 2626 } else { 2627 var args = Array.prototype.slice.call(arguments, 0); 2628 } 2629 2630 return function() { 2631 passed.el.trigger(passed.scenario[1], args); 2632 } 2633 }(passed))); 2634 } 2635 } 2636 } 2637 2638 }, 2639 2640 results : function (uuid, scenarios) { 2641 var count = scenarios.length; 2642 2643 if (count > 0) { 2644 var el = this.S('[' + this.add_namespace('data-uuid') + '="' + uuid + '"]'); 2645 2646 while (count--) { 2647 var mq, rule = scenarios[count][2]; 2648 if (this.settings.named_queries.hasOwnProperty(rule)) { 2649 mq = matchMedia(this.settings.named_queries[rule]); 2650 } else { 2651 mq = matchMedia(rule); 2652 } 2653 if (mq.matches) { 2654 return {el : el, scenario : scenarios[count]}; 2655 } 2656 } 2657 } 2658 2659 return false;
2660 }, 2661 2662 load : function (type, force_update) { 2663 if (typeof this['cached_' + type] === 'undefined' || force_update) { 2664 this['update_' + type](); 2665 } 2666 2667 return this['cached_' + type]; 2668 }, 2669 2670 update_images : function () { 2671 var images = this.S('img[' + this.data_attr + ']'), 2672 count = images.length, 2673 i = count, 2674 loaded_count = 0, 2675 data_attr = this.data_attr; 2676 2677 this.cache = {}; 2678 this.cached_images = []; 2679 this.images_loaded = (count === 0); 2680 2681 while (i--) { 2682 loaded_count++; 2683 if (images[i]) { 2684 var str = images[i].getAttribute(data_attr) || ''; 2685 2686 if (str.length > 0) { 2687 this.cached_images.push(images[i]); 2688 } 2689 } 2690 2691 if (loaded_count === count) { 2692 this.images_loaded = true; 2693 this.enhance('images'); 2694 } 2695 } 2696 2697 return this; 2698 }, 2699 2700 update_nodes : function () { 2701 var nodes = this.S('[' + this.data_attr + ']').not('img'), 2702 count = nodes.length, 2703 i = count, 2704 loaded_count = 0, 2705 data_attr = this.data_attr; 2706 2707 this.cached_nodes = []; 2708 this.nodes_loaded = (count === 0); 2709 2710 while (i--) { 2711 loaded_count++; 2712 var str = nodes[i].getAttribute(data_attr) || ''; 2713 2714 if (str.length > 0) { 2715 this.cached_nodes.push(nodes[i]); 2716 } 2717 2718 if (loaded_count === count) { 2719 this.nodes_loaded = true; 2720 this.enhance('nodes'); 2721 } 2722 } 2723 2724 return this; 2725 }, 2726 2727 enhance : function (type) { 2728 var i = this['cached_' + type].length; 2729 2730 while (i--) { 2731 this.object($(this['cached_' + type][i])); 2732 } 2733 2734 return $(window).trigger('resize.fndtn.interchange'); 2735 }, 2736 2737 convert_directive : function (directive) { 2738 2739 var trimmed = this.trim(directive); 2740 2741 if (trimmed.length > 0) { 2742 return trimmed; 2743 } 2744 2745 return 'replace'; 2746 }, 2747 2748 parse_scenario : function (scenario) { 2749 // This logic had to be made more complex since some users were using commas in the url path 2750 // So we cannot simply just split on a comma 2751 2752 var directive_match = scenario[0].match(/(.+),\s*(\w+)\s*$/), 2753 // getting the mq has gotten a bit complicated since we started accounting for several use cases 2754 // of URLs. For now we'll continue to match these scenarios, but we may consider having these scenarios 2755 // as nested objects or arrays in F6. 2756 // regex: match everything before close parenthesis for mq 2757 media_query = scenario[1].match(/(.*)\)/); 2758 2759 if (directive_match) { 2760 var path = directive_match[1], 2761 directive = directive_match[2]; 2762 2763 } else { 2764 var cached_split = scenario[0].split(/,\s*$/), 2765 path = cached_split[0], 2766 directive = ''; 2767 } 2768 2769 return [this.trim(path), this.convert_directive(directive), this.trim(media_query[1])]; 2770 }, 2771 2772 object : function (el) { 2773 var raw_arr = this.parse_data_attr(el), 2774 scenarios = [], 2775 i = raw_arr.length; 2776 2777 if (i > 0) { 2778 while (i--) { 2779 // split array between comma delimited content and mq 2780 // regex: comma, optional space, open parenthesis 2781 var scenario = raw_arr[i].split(/,\s?\(/); 2782 2783 if (scenario.length > 1) { 2784 var params = this.parse_scenario(scenario); 2785 scenarios.push(params); 2786 } 2787 } 2788 } 2789 2790 return this.store(el, scenarios); 2791 }, 2792 2793 store : function (el, scenarios) { 2794 var uuid = this.random_str(), 2795 current_uuid = el.data(this.add_namespace('uuid', true)); 2796 2797 if (this.cache[current_uuid]) { 2798 return this.cache[current_uuid]; 2799 } 2800 2801 el.attr(this.add_namespace('data-uuid'), uuid); 2802 return this.cache[uuid] = scenarios; 2803 }, 2804 2805 trim : function (str) { 2806 2807 if (typeof str === 'string') { 2808 return $.trim(str); 2809 } 2810 2811 return str; 2812 }, 2813 2814 set_data_attr : function (init) { 2815 if (init) { 2816 if (this.namespace.length > 0) { 2817 return this.namespace + '-' + this.settings.load_attr; 2818 } 2819 2820 return this.settings.load_attr; 2821 } 2822 2823 if (this.namespace.length > 0) { 2824 return 'data-' + this.namespace + '-' + this.settings.load_attr; 2825 } 2826 2827 return 'data-' + this.settings.load_attr; 2828 }, 2829 2830 parse_data_attr : function (el) { 2831 var raw = el.attr(this.attr_name()).split(/\[(.*?)\]/), 2832 i = raw.length, 2833 output = []; 2834 2835 while (i--) { 2836 if (raw[i].replace(/[\W\d]+/, '').length > 4) { 2837 output.push(raw[i]); 2838 } 2839 } 2840 2841 return output; 2842 }, 2843 2844 reflow : function () { 2845 this.load('images', true); 2846 this.load('nodes', true); 2847 } 2848 2849 }; 2850 2851}(jQuery, window, window.document)); 2852 2853;(function ($, window, document, undefined) { 2854 'use strict'; 2855 2856 var Modernizr = Modernizr || false; 2857 2858 Foundation.libs.joyride = { 2859 name : 'joyride', 2860 2861 version : '5.5.3', 2862 2863 defaults : { 2864 expose : false, // turn on or off the expose feature 2865 modal : true, // Whether to cover page with modal during the tour 2866 keyboard : true, // enable left, right and esc keystrokes 2867 tip_location : 'bottom', // 'top', 'bottom', 'left' or 'right' in relation to parent 2868 nub_position : 'auto', // override on a per tooltip bases 2869 scroll_speed : 1500, // Page scrolling speed in milliseconds, 0 = no scroll animation 2870 scroll_animation : 'linear', // supports 'swing' and 'linear', extend with jQuery UI. 2871 timer : 0, // 0 = no timer , all other numbers = timer in milliseconds 2872 start_timer_on_click : true, // true or false - true requires clicking the first button start the timer 2873 start_offset : 0, // the index of the tooltip you want to start on (index of the li) 2874 next_button : true, // true or false to control whether a next button is used 2875 prev_button : true, // true or false to control whether a prev button is used 2876 tip_animation : 'fade', // 'pop' or 'fade' in each tip 2877 pause_after : [], // array of indexes where to pause the tour after 2878 exposed : [], // array of expose elements 2879 tip_animation_fade_speed : 300, // when tipAnimation = 'fade' this is speed in milliseconds for the transition 2880 cookie_monster : false, // true or false to control whether cookies are used 2881 cookie_name : 'joyride', // Name the cookie you'll use
2882 cookie_domain : false, // Will this cookie be attached to a domain, ie. '.notableapp.com' 2883 cookie_expires : 365, // set when you would like the cookie to expire. 2884 tip_container : 'body', // Where will the tip be attached 2885 abort_on_close : true, // When true, the close event will not fire any callback 2886 tip_location_patterns : { 2887 top : ['bottom'], 2888 bottom : [], // bottom should not need to be repositioned 2889 left : ['right', 'top', 'bottom'], 2890 right : ['left', 'top', 'bottom'] 2891 }, 2892 post_ride_callback : function () {}, // A method to call once the tour closes (canceled or complete) 2893 post_step_callback : function () {}, // A method to call after each step 2894 pre_step_callback : function () {}, // A method to call before each step 2895 pre_ride_callback : function () {}, // A method to call before the tour starts (passed index, tip, and cloned exposed element) 2896 post_expose_callback : function () {}, // A method to call after an element has been exposed 2897 template : { // HTML segments for tip layout 2898 link : '<a href="#close" class="joyride-close-tip">×</a>', 2899 timer : '<div class="joyride-timer-indicator-wrap"><span class="joyride-timer-indicator"></span></div>', 2900 tip : '<div class="joyride-tip-guide"><span class="joyride-nub"></span></div>', 2901 wrapper : '<div class="joyride-content-wrapper"></div>', 2902 button : '<a href="#" class="small button joyride-next-tip"></a>', 2903 prev_button : '<a href="#" class="small button joyride-prev-tip"></a>', 2904 modal : '<div class="joyride-modal-bg"></div>', 2905 expose : '<div class="joyride-expose-wrapper"></div>', 2906 expose_cover : '<div class="joyride-expose-cover"></div>' 2907 }, 2908 expose_add_class : '' // One or more space-separated class names to be added to exposed element 2909 }, 2910 2911 init : function (scope, method, options) { 2912 Foundation.inherit(this, 'throttle random_str'); 2913 2914 this.settings = this.settings || $.extend({}, this.defaults, (options || method)); 2915 2916 this.bindings(method, options) 2917 }, 2918 2919 go_next : function () { 2920 if (this.settings.$li.next().length < 1) { 2921 this.end(); 2922 } else if (this.settings.timer > 0) { 2923 clearTimeout(this.settings.automate); 2924 this.hide(); 2925 this.show(); 2926 this.startTimer(); 2927 } else { 2928 this.hide(); 2929 this.show(); 2930 } 2931 }, 2932 2933 go_prev : function () { 2934 if (this.settings.$li.prev().length < 1) { 2935 // Do nothing if there are no prev element 2936 } else if (this.settings.timer > 0) { 2937 clearTimeout(this.settings.automate); 2938 this.hide(); 2939 this.show(null, true); 2940 this.startTimer(); 2941 } else { 2942 this.hide(); 2943 this.show(null, true); 2944 } 2945 }, 2946 2947 events : function () { 2948 var self = this; 2949 2950 $(this.scope) 2951 .off('.joyride') 2952 .on('click.fndtn.joyride', '.joyride-next-tip, .joyride-modal-bg', function (e) { 2953 e.preventDefault(); 2954 this.go_next() 2955 }.bind(this)) 2956 .on('click.fndtn.joyride', '.joyride-prev-tip', function (e) { 2957 e.preventDefault(); 2958 this.go_prev(); 2959 }.bind(this)) 2960 2961 .on('click.fndtn.joyride', '.joyride-close-tip', function (e) { 2962 e.preventDefault(); 2963 this.end(this.settings.abort_on_close); 2964 }.bind(this)) 2965 2966 .on('keyup.fndtn.joyride', function (e) { 2967 // Don't do anything if keystrokes are disabled 2968 // or if the joyride is not being shown 2969 if (!this.settings.keyboard || !this.settings.riding) { 2970 return; 2971 } 2972 2973 switch (e.which) { 2974 case 39: // right arrow 2975 e.preventDefault(); 2976 this.go_next(); 2977 break; 2978 case 37: // left arrow 2979 e.preventDefault(); 2980 this.go_prev(); 2981 break; 2982 case 27: // escape 2983 e.preventDefault(); 2984 this.end(this.settings.abort_on_close); 2985 } 2986 }.bind(this)); 2987 2988 $(window) 2989 .off('.joyride') 2990 .on('resize.fndtn.joyride', self.throttle(function () { 2991 if ($('[' + self.attr_name() + ']').length >
2991 0 && self.settings.$next_tip && self.settings.riding) { 2992 if (self.settings.exposed.length > 0) { 2993 var $els = $(self.settings.exposed); 2994 2995 $els.each(function () { 2996 var $this = $(this); 2997 self.un_expose($this); 2998 self.expose($this); 2999 }); 3000 } 3001 3002 if (self.is_phone()) { 3003 self.pos_phone(); 3004 } else { 3005 self.pos_default(false); 3006 } 3007 } 3008 }, 100)); 3009 }, 3010 3011 start : function () { 3012 var self = this, 3013 $this = $('[' + this.attr_name() + ']', this.scope), 3014 integer_settings = ['timer', 'scrollSpeed', 'startOffset', 'tipAnimationFadeSpeed', 'cookieExpires'], 3015 int_settings_count = integer_settings.length; 3016 3017 if (!$this.length > 0) { 3018 return; 3019 } 3020 3021 if (!this.settings.init) { 3022 this.events(); 3023 } 3024 3025 this.settings = $this.data(this.attr_name(true) + '-init'); 3026 3027 // non configureable settings 3028 this.settings.$content_el = $this; 3029 this.settings.$body = $(this.settings.tip_container); 3030 this.settings.body_offset = $(this.settings.tip_container).position(); 3031 this.settings.$tip_content = this.settings.$content_el.find('> li'); 3032 this.settings.paused = false; 3033 this.settings.attempts = 0; 3034 this.settings.riding = true; 3035 3036 // can we create cookies? 3037 if (typeof $.cookie !== 'function') { 3038 this.settings.cookie_monster = false; 3039 } 3040 3041 // generate the tips and insert into dom. 3042 if (!this.settings.cookie_monster || this.settings.cookie_monster && !$.cookie(this.settings.cookie_name)) { 3043 this.settings.$tip_content.each(function (index) { 3044 var $this = $(this); 3045 this.settings = $.extend({}, self.defaults, self.data_options($this)); 3046 3047 // Make sure that settings parsed from data_options are integers where necessary 3048 var i = int_settings_count; 3049 while (i--) { 3050 self.settings[integer_settings[i]] = parseInt(self.settings[integer_settings[i]], 10); 3051 } 3052 self.create({$li : $this, index : index}); 3053 }); 3054 3055 // show first tip 3056 if (!this.settings.start_timer_on_click && this.settings.timer > 0) { 3057 this.show('init'); 3058 this.startTimer(); 3059 } else { 3060 this.show('init'); 3061 } 3062 3063 } 3064 }, 3065 3066 resume : function () { 3067 this.set_li(); 3068 this.show(); 3069 }, 3070 3071 tip_template : function (opts) { 3072 var $blank, content; 3073 3074 opts.tip_class = opts.tip_class || ''; 3075 3076 $blank = $(this.settings.template.tip).addClass(opts.tip_class); 3077 content = $.trim($(opts.li).html()) + 3078 this.prev_button_text(opts.prev_button_text, opts.index) + 3079 this.button_text(opts.button_text) + 3080 this.settings.template.link + 3081 this.timer_instance(opts.index); 3082 3083 $blank.append($(this.settings.template.wrapper)); 3084 $blank.first().attr(this.add_namespace('data-index'), opts.index); 3085 $('.joyride-content-wrapper', $blank).append(content); 3086 3087 return $blank[0]; 3088 }, 3089 3090 timer_instance : function (index) { 3091 var txt; 3092 3093 if ((index === 0 && this.settings.start_timer_on_click && this.settings.timer > 0) || this.settings.timer === 0) { 3094 txt = ''; 3095 } else { 3096 txt = $(this.settings.template.timer)[0].outerHTML; 3097 } 3098 return txt; 3099 }, 3100 3101 button_text : function (txt) { 3102 if (this.settings.tip_settings.next_button) { 3103 txt = $.trim(txt) || 'Next'; 3104 txt = $(this.settings.template.button).append(txt)[0].outerHTML; 3105 } else { 3106 txt = ''; 3107 } 3108 return txt; 3109 }, 3110 3111 prev_button_text : function (txt, idx) { 3112 if (this.settings.tip_settings.prev_button) { 3113 txt = $.trim(txt) || 'Previous'; 3114 3115 // Add the disabled class to the button if it's the first element 3116 if (idx == 0) { 3117 txt = $(this.settings.template.prev_button).append(txt).addClass('disabled')[0].outerHTML; 3118 } else { 3119 txt = $(this.settings.template.prev_button).append(txt)[0].outerHTML; 3120 } 3121 } else { 3122 txt = ''; 3123 } 3124 return txt; 3125 }, 3126 3127 create : function (opts) { 3128 this.settings.tip_settings = $.extend({}, this.settings, this.data_options(opts.$li)); 3129 var buttonText = opts.$li.attr(this.add_namespace('data-button')) || opts.$li.attr(this.add_namespace('data-text')), 3130 prevButtonText = opts.$li.attr(this.add_namespace('data-button-prev')) || opts.$li.attr(this.add_namespace('data-prev-text')), 3131 tipClass = opts.$li.attr('class'), 3132 $tip_content = $(this.tip_template({ 3133 tip_class : tipClass, 3134 index : opts.index, 3135 button_text : buttonText, 3136 prev_button_text : prevButtonText, 3137 li : opts.$li 3138 })); 3139 3140 $(this.settings.tip_container).append($tip_content); 3141 }, 3142 3143 show : function (init, is_prev) { 3144 var $timer = null; 3145 3146 // are we paused? 3147 if (this.settings.$li === undefined || ($.inArray(this.settings.$li.index(), this.settings.pause_after) === -1)) { 3148 3149 // don't go to the next li if the tour was paused 3150 if (this.settings.paused) { 3151 this.settings.paused = false;
3152 } else { 3153 this.set_li(init, is_prev); 3154 } 3155 3156 this.settings.attempts = 0; 3157 3158 if (this.settings.$li.length && this.settings.$target.length > 0) { 3159 if (init) { //run when we first start 3160 this.settings.pre_ride_callback(this.settings.$li.index(), this.settings.$next_tip); 3161 if (this.settings.modal) { 3162 this.show_modal(); 3163 } 3164 } 3165 3166 this.settings.pre_step_callback(this.settings.$li.index(), this.settings.$next_tip); 3167 3168 if (this.settings.modal && this.settings.expose) { 3169 this.expose(); 3170 } 3171 3172 this.settings.tip_settings = $.extend({}, this.settings, this.data_options(this.settings.$li)); 3173 3174 this.settings.timer = parseInt(this.settings.timer, 10); 3175 3176 this.settings.tip_settings.tip_location_pattern = this.settings.tip_location_patterns[this.settings.tip_settings.tip_location]; 3177 3178 // scroll and hide bg if not modal and not expose 3179 if (!/body/i.test(this.settings.$target.selector) && !this.settings.expose) { 3180 var joyridemodalbg = $('.joyride-modal-bg'); 3181 if (/pop/i.test(this.settings.tipAnimation)) { 3182 joyridemodalbg.hide(); 3183 } else { 3184 joyridemodalbg.fadeOut(this.settings.tipAnimationFadeSpeed); 3185 } 3186 this.scroll_to(); 3187 } 3188 3189 if (this.is_phone()) { 3190 this.pos_phone(true); 3191 } else { 3192 this.pos_default(true); 3193 } 3194 3195 $timer = this.settings.$next_tip.find('.joyride-timer-indicator'); 3196 3197 if (/pop/i.test(this.settings.tip_animation)) { 3198 3199 $timer.width(0); 3200 3201 if (this.settings.timer > 0) { 3202 3203 this.settings.$next_tip.show(); 3204 3205 setTimeout(function () { 3206 $timer.animate({ 3207 width : $timer.parent().width() 3208 }, this.settings.timer, 'linear'); 3209 }.bind(this), this.settings.tip_animation_fade_speed); 3210 3211 } else { 3212 this.settings.$next_tip.show(); 3213 3214 } 3215 3216 } else if (/fade/i.test(this.settings.tip_animation)) { 3217 3218 $timer.width(0); 3219 3220 if (this.settings.timer > 0) { 3221 3222 this.settings.$next_tip 3223 .fadeIn(this.settings.tip_animation_fade_speed) 3224 .show(); 3225 3226 setTimeout(function () { 3227 $timer.animate({ 3228 width : $timer.parent().width() 3229 }, this.settings.timer, 'linear'); 3230 }.bind(this), this.settings.tip_animation_fade_speed); 3231 3232 } else { 3233 this.settings.$next_tip.fadeIn(this.settings.tip_animation_fade_speed); 3234 } 3235 } 3236 3237 this.settings.$current_tip = this.settings.$next_tip; 3238 3239 // skip non-existant targets 3240 } else if (this.settings.$li && this.settings.$target.length < 1) { 3241 3242 this.show(init, is_prev); 3243 3244 } else { 3245 3246 this.end(); 3247 3248 } 3249 } else { 3250 3251 this.settings.paused = true; 3252 3253 } 3254 3255 }, 3256 3257 is_phone : function () { 3258 return matchMedia(Foundation.media_queries.small).matches && 3259 !matchMedia(Foundation.media_queries.medium).matches; 3260 }, 3261 3262 hide : function () { 3263 if (this.settings.modal && this.settings.expose) { 3264 this.un_expose(); 3265 } 3266 3267 if (!this.settings.modal) { 3268 $('.joyride-modal-bg').hide(); 3269 } 3270 3271 // Prevent scroll bouncing...wait to remove from layout 3272 this.settings.$current_tip.css('visibility', 'hidden'); 3273 setTimeout($.proxy(function () { 3274 this.hide(); 3275 this.css('visibility', 'visible'); 3276 }, this.settings.$current_tip), 0); 3277 this.settings.post_step_callback(this.settings.$li.index(), 3278 this.settings.$current_tip); 3279 }, 3280 3281 set_li : function (init, is_prev) { 3282 if (init) { 3283 this.settings.$li = this.settings.$tip_content.eq(this.settings.start_offset); 3284 this.set_next_tip(); 3285 this.settings.$current_tip = this.settings.$next_tip; 3286 } else { 3287 if (is_prev) { 3288 this.settings.$li = this.settings.$li.prev(); 3289 } else { 3290 this.settings.$li = this.settings.$li.next(); 3291 } 3292 this.set_next_tip(); 3293 } 3294 3295 this.set_target(); 3296 }, 3297 3298 set_next_tip : function () { 3299 this.settings.$next_tip = $('.joyride-tip-guide').eq(this.settings.$li.index()); 3300 this.settings.$next_tip.data('closed', ''); 3301 }, 3302 3303 set_target : function () { 3304 var cl = this.settings.$li.attr(this.add_namespace('data-class')), 3305 id = this.settings.$li.attr(this.add_namespace('data-id')), 3306 $sel = function () { 3307 if (id) { 3308 return $(document.getElementById(id)); 3309 } else if (cl) { 3310 return $('.' + cl).first(); 3311 } else { 3312 return $('body'); 3313 } 3314 }; 3315 3316 this.settings.$target = $sel(); 3317 }, 3318 3319 scroll_to : function () { 3320 var window_half, tipOffset; 3321 3322 window_half = $(window).height() / 2;
3323 tipOffset = Math.ceil(this.settings.$target.offset().top - window_half + this.settings.$next_tip.outerHeight()); 3324 3325 if (tipOffset != 0) { 3326 $('html, body').stop().animate({ 3327 scrollTop : tipOffset 3328 }, this.settings.scroll_speed, 'swing'); 3329 } 3330 }, 3331 3332 paused : function () { 3333 return ($.inArray((this.settings.$li.index() + 1), this.settings.pause_after) === -1); 3334 }, 3335 3336 restart : function () { 3337 this.hide(); 3338 this.settings.$li = undefined; 3339 this.show('init'); 3340 }, 3341 3342 pos_default : function (init) { 3343 var $nub = this.settings.$next_tip.find('.joyride-nub'), 3344 nub_width = Math.ceil($nub.outerWidth() / 2), 3345 nub_height = Math.ceil($nub.outerHeight() / 2), 3346 toggle = init || false; 3347 3348 // tip must not be "display: none" to calculate position 3349 if (toggle) { 3350 this.settings.$next_tip.css('visibility', 'hidden'); 3351 this.settings.$next_tip.show(); 3352 } 3353 3354 if (!/body/i.test(this.settings.$target.selector)) { 3355 var topAdjustment = this.settings.tip_settings.tipAdjustmentY ? parseInt(this.settings.tip_settings.tipAdjustmentY) : 0, 3356 leftAdjustment = this.settings.tip_settings.tipAdjustmentX ? parseInt(this.settings.tip_settings.tipAdjustmentX) : 0; 3357 3358 if (this.bottom()) { 3359 if (this.rtl) { 3360 this.settings.$next_tip.css({ 3361 top : (this.settings.$target.offset().top + nub_height + this.settings.$target.outerHeight() + topAdjustment), 3362 left : this.settings.$target.offset().left + this.settings.$target.outerWidth() - this.settings.$next_tip.outerWidth() + leftAdjustment}); 3363 } else { 3364 this.settings.$next_tip.css({ 3365 top : (this.settings.$target.offset().top + nub_height + this.settings.$target.outerHeight() + topAdjustment), 3366 left : this.settings.$target.offset().left + leftAdjustment}); 3367 } 3368 3369 this.nub_position($nub, this.settings.tip_settings.nub_position, 'top'); 3370 3371 } else if (this.top()) { 3372 if (this.rtl) { 3373 this.settings.$next_tip.css({ 3374 top : (this.settings.$target.offset().top - this.settings.$next_tip.outerHeight() - nub_height + topAdjustment), 3375 left : this.settings.$target.offset().left + this.settings.$target.outerWidth() - this.settings.$next_tip.outerWidth()}); 3376 } else { 3377 this.settings.$next_tip.css({ 3378 top : (this.settings.$target.offset().top - this.settings.$next_tip.outerHeight() - nub_height + topAdjustment), 3379 left : this.settings.$target.offset().left + leftAdjustment}); 3380 } 3381 3382 this.nub_position($nub, this.settings.tip_settings.nub_position, 'bottom'); 3383 3384 } else if (this.right()) { 3385 3386 this.settings.$next_tip.css({ 3387 top : this.settings.$target.offset().top + topAdjustment, 3388 left : (this.settings.$target.outerWidth() + this.settings.$target.offset().left + nub_width + leftAdjustment)}); 3389 3390 this.nub_position($nub, this.settings.tip_settings.nub_position, 'left'); 3391 3392 } else if (this.left()) { 3393 3394 this.settings.$next_tip.css({ 3395 top : this.settings.$target.offset().top + topAdjustment, 3396 left : (this.settings.$target.offset().left - this.settings.$next_tip.outerWidth() - nub_width + leftAdjustment)}); 3397 3398 this.nub_position($nub, this.settings.tip_settings.nub_position, 'right'); 3399 3400 } 3401 3402 if (!this.visible(this.corners(this.settings.$next_tip)) && this.settings.attempts < this.settings.tip_settings.tip_location_pattern.length) { 3403 3404 $nub.removeClass('bottom') 3405 .removeClass('top') 3406 .removeClass('right') 3407 .removeClass('left'); 3408 3409 this.settings.tip_settings.tip_location = this.settings.tip_settings.tip_location_pattern[this.settings.attempts]; 3410 3411 this.settings.attempts++; 3412 3413 this.pos_default(); 3414 3415 } 3416 3417 } else if (this.settings.$li.length) { 3418 3419 this.pos_modal($nub); 3420 3421 } 3422 3423 if (toggle) { 3424 this.settings.$next_tip.hide(); 3425 this.settings.$next_tip.css('visibility', 'visible'); 3426 } 3427 3428 }, 3429 3430 pos_phone : function (init) { 3431 var tip_height = this.settings.$next_tip.outerHeight(), 3432 tip_offset = this.settings.$next_tip.offset(), 3433 target_height = this.settings.$target.outerHeight(), 3434 $nub = $('.joyride-nub', this.settings.$next_tip),
3435 nub_height = Math.ceil($nub.outerHeight() / 2), 3436 toggle = init || false; 3437 3438 $nub.removeClass('bottom') 3439 .removeClass('top') 3440 .removeClass('right') 3441 .removeClass('left'); 3442 3443 if (toggle) { 3444 this.settings.$next_tip.css('visibility', 'hidden'); 3445 this.settings.$next_tip.show(); 3446 } 3447 3448 if (!/body/i.test(this.settings.$target.selector)) { 3449 3450 if (this.top()) { 3451 3452 this.settings.$next_tip.offset({top : this.settings.$target.offset().top - tip_height - nub_height}); 3453 $nub.addClass('bottom'); 3454 3455 } else { 3456 3457 this.settings.$next_tip.offset({top : this.settings.$target.offset().top + target_height + nub_height}); 3458 $nub.addClass('top'); 3459 3460 } 3461 3462 } else if (this.settings.$li.length) { 3463 this.pos_modal($nub); 3464 } 3465 3466 if (toggle) { 3467 this.settings.$next_tip.hide(); 3468 this.settings.$next_tip.css('visibility', 'visible'); 3469 } 3470 }, 3471 3472 pos_modal : function ($nub) { 3473 this.center(); 3474 $nub.hide(); 3475 3476 this.show_modal(); 3477 }, 3478 3479 show_modal : function () { 3480 if (!this.settings.$next_tip.data('closed')) { 3481 var joyridemodalbg = $('.joyride-modal-bg'); 3482 if (joyridemodalbg.length < 1) { 3483 var joyridemodalbg = $(this.settings.template.modal); 3484 joyridemodalbg.appendTo('body'); 3485 } 3486 3487 if (/pop/i.test(this.settings.tip_animation)) { 3488 joyridemodalbg.show(); 3489 } else { 3490 joyridemodalbg.fadeIn(this.settings.tip_animation_fade_speed); 3491 } 3492 } 3493 }, 3494 3495 expose : function () { 3496 var expose, 3497 exposeCover, 3498 el, 3499 origCSS, 3500 origClasses, 3501 randId = 'expose-' + this.random_str(6); 3502 3503 if (arguments.length > 0 && arguments[0] instanceof $) { 3504 el = arguments[0]; 3505 } else if (this.settings.$target && !/body/i.test(this.settings.$target.selector)) { 3506 el = this.settings.$target; 3507 } else { 3508 return false; 3509 } 3510 3511 if (el.length < 1) { 3512 if (window.console) { 3513 console.error('element not valid', el); 3514 } 3515 return false; 3516 } 3517 3518 expose = $(this.settings.template.expose); 3519 this.settings.$body.append(expose); 3520 expose.css({ 3521 top : el.offset().top, 3522 left : el.offset().left, 3523 width : el.outerWidth(true), 3524 height : el.outerHeight(true) 3525 }); 3526 3527 exposeCover = $(this.settings.template.expose_cover); 3528 3529 origCSS = { 3530 zIndex : el.css('z-index'), 3531 position : el.css('position') 3532 }; 3533 3534 origClasses = el.attr('class') == null ? '' : el.attr('class'); 3535 3536 el.css('z-index', parseInt(expose.css('z-index')) + 1); 3537 3538 if (origCSS.position == 'static') { 3539 el.css('position', 'relative'); 3540 } 3541 3542 el.data('expose-css', origCSS); 3543 el.data('orig-class', origClasses); 3544 el.attr('class', origClasses + ' ' + this.settings.expose_add_class); 3545 3546 exposeCover.css({ 3547 top : el.offset().top, 3548 left : el.offset().left, 3549 width : el.outerWidth(true), 3550 height : el.outerHeight(true) 3551 }); 3552 3553 if (this.settings.modal) { 3554 this.show_modal(); 3555 } 3556 3557 this.settings.$body.append(exposeCover); 3558 expose.addClass(randId); 3559 exposeCover.addClass(randId); 3560 el.data('expose', randId); 3561 this.settings.post_expose_callback(this.settings.$li.index(), this.settings.$next_tip, el); 3562 this.add_exposed(el); 3563 }, 3564 3565 un_expose : function () { 3566 var exposeId, 3567 el, 3568 expose, 3569 origCSS, 3570 origClasses, 3571 clearAll = false; 3572 3573 if (arguments.length > 0 && arguments[0] instanceof $) { 3574 el = arguments[0]; 3575 } else if (this.settings.$target && !/body/i.test(this.settings.$target.selector)) { 3576 el = this.settings.$target; 3577 } else { 3578 return false; 3579 } 3580 3581 if (el.length < 1) { 3582 if (window.console) { 3583 console.error('element not valid', el); 3584 } 3585 return false; 3586 } 3587 3588 exposeId = el.data('expose'); 3589 expose = $('.' + exposeId); 3590 3591 if (arguments.length > 1) { 3592 clearAll = arguments[1]; 3593 } 3594 3595 if (clearAll === true) { 3596 $('.joyride-expose-wrapper,.joyride-expose-cover').remove(); 3597 } else { 3598 expose.remove(); 3599 } 3600 3601 origCSS = el.data('expose-css'); 3602 3603 if (origCSS.zIndex == 'auto') { 3604 el.css('z-index', ''); 3605 } else { 3606 el.css('z-index', origCSS.zIndex); 3607 } 3608 3609 if (origCSS.position != el.css('position')) { 3610 if (origCSS.position == 'static') {// this is default, no need to set it. 3611 el.css('position', ''); 3612 } else { 3613 el.css('position', origCSS.position); 3614 } 3615 } 3616 3617 origClasses = el.data('orig-class'); 3618 el.attr('class', origClasses); 3619 el.removeData('orig-classes'); 3620 3621 el.removeData('expose'); 3622 el.removeData('expose-z-index'); 3623 this.remove_exposed(el); 3624 }, 3625
3626 add_exposed : function (el) { 3627 this.settings.exposed = this.settings.exposed || []; 3628 if (el instanceof $ || typeof el === 'object') { 3629 this.settings.exposed.push(el[0]); 3630 } else if (typeof el == 'string') { 3631 this.settings.exposed.push(el); 3632 } 3633 }, 3634 3635 remove_exposed : function (el) { 3636 var search, i; 3637 if (el instanceof $) { 3638 search = el[0] 3639 } else if (typeof el == 'string') { 3640 search = el; 3641 } 3642 3643 this.settings.exposed = this.settings.exposed || []; 3644 i = this.settings.exposed.length; 3645 3646 while (i--) { 3647 if (this.settings.exposed[i] == search) { 3648 this.settings.exposed.splice(i, 1); 3649 return; 3650 } 3651 } 3652 }, 3653 3654 center : function () { 3655 var $w = $(window); 3656 3657 this.settings.$next_tip.css({ 3658 top : ((($w.height() - this.settings.$next_tip.outerHeight()) / 2) + $w.scrollTop()), 3659 left : ((($w.width() - this.settings.$next_tip.outerWidth()) / 2) + $w.scrollLeft()) 3660 }); 3661 3662 return true; 3663 }, 3664 3665 bottom : function () { 3666 return /bottom/i.test(this.settings.tip_settings.tip_location); 3667 }, 3668 3669 top : function () { 3670 return /top/i.test(this.settings.tip_settings.tip_location); 3671 }, 3672 3673 right : function () { 3674 return /right/i.test(this.settings.tip_settings.tip_location); 3675 }, 3676 3677 left : function () { 3678 return /left/i.test(this.settings.tip_settings.tip_location); 3679 }, 3680 3681 corners : function (el) { 3682 if (el.length === 0) { 3683 return [false, false, false, false]; 3684 } 3685 3686 var w = $(window), 3687 window_half = w.height() / 2, 3688 //using this to calculate since scroll may not have finished yet. 3689 tipOffset = Math.ceil(this.settings.$target.offset().top - window_half + this.settings.$next_tip.outerHeight()), 3690 right = w.width() + w.scrollLeft(), 3691 offsetBottom = w.height() + tipOffset, 3692 bottom = w.height() + w.scrollTop(), 3693 top = w.scrollTop(); 3694 3695 if (tipOffset < top) { 3696 if (tipOffset < 0) { 3697 top = 0; 3698 } else { 3699 top = tipOffset; 3700 } 3701 } 3702 3703 if (offsetBottom > bottom) { 3704 bottom = offsetBottom; 3705 } 3706 3707 return [ 3708 el.offset().top < top, 3709 right < el.offset().left + el.outerWidth(), 3710 bottom < el.offset().top + el.outerHeight(), 3711 w.scrollLeft() > el.offset().left 3712 ]; 3713 }, 3714 3715 visible : function (hidden_corners) { 3716 var i = hidden_corners.length; 3717 3718 while (i--) { 3719 if (hidden_corners[i]) { 3720 return false; 3721 } 3722 } 3723 3724 return true; 3725 }, 3726 3727 nub_position : function (nub, pos, def) { 3728 if (pos === 'auto') { 3729 nub.addClass(def); 3730 } else { 3731 nub.addClass(pos); 3732 } 3733 }, 3734 3735 startTimer : function () { 3736 if (this.settings.$li.length) { 3737 this.settings.automate = setTimeout(function () { 3738 this.hide(); 3739 this.show(); 3740 this.startTimer(); 3741 }.bind(this), this.settings.timer); 3742 } else { 3743 clearTimeout(this.settings.automate); 3744 } 3745 }, 3746 3747 end : function (abort) { 3748 if (this.settings.cookie_monster) { 3749 $.cookie(this.settings.cookie_name, 'ridden', {expires : this.settings.cookie_expires, domain : this.settings.cookie_domain}); 3750 } 3751 3752 if (this.settings.timer > 0) { 3753 clearTimeout(this.settings.automate); 3754 } 3755 3756 if (this.settings.modal && this.settings.expose) { 3757 this.un_expose(); 3758 } 3759 3760 // Unplug keystrokes listener 3761 $(this.scope).off('keyup.joyride') 3762 3763 this.settings.$next_tip.data('closed', true); 3764 this.settings.riding = false; 3765 3766 $('.joyride-modal-bg').hide(); 3767 this.settings.$current_tip.hide(); 3768 3769 if (typeof abort === 'undefined' || abort === false) { 3770 this.settings.post_step_callback(this.settings.$li.index(), this.settings.$current_tip); 3771 this.settings.post_ride_callback(this.settings.$li.index(), this.settings.$current_tip); 3772 } 3773 3774 $('.joyride-tip-guide').remove(); 3775 }, 3776 3777 off : function () { 3778 $(this.scope).off('.joyride'); 3779 $(window).off('.joyride'); 3780 $('.joyride-close-tip, .joyride-next-tip, .joyride-modal-bg').off('.joyride'); 3781 $('.joyride-tip-guide, .joyride-modal-bg').remove(); 3782 clearTimeout(this.settings.automate); 3783 }, 3784 3785 reflow : function () {} 3786 }; 3787}(jQuery, window, window.document)); 3788 3789;(function ($, window, document, undefined) { 3790 'use strict'; 3791 3792 Foundation.libs['magellan-expedition'] = { 3793 name : 'magellan-expedition', 3794 3795 version : '5.5.3', 3796 3797 settings : { 3798 active_class : 'active', 3799 threshold : 0, // pixels from the top of the expedition for it to become fixes 3800 destination_threshold : 20, // pixels from the top of destination for it to be considered active 3801 throttle_delay : 30, // calculation throttling to increase framerate 3802 fixed_top : 0, // top distance in pixels assigend to the fixed element on scroll 3803 offset_by_height : true, // whether to offset the destination by the expedition height. Usually you want this to be true, unless your expedition is on the side. 3804 duration : 700, // animation duration time 3805 easing : 'swing' // animation easing 3806 }, 3807 3808 init : function (scope, method, options) { 3809 Foundation.inherit(this, 'throttle'); 3810 this.bindings(method, options); 3811 }, 3812 3813 events : function () { 3814 var self = this, 3815 S = self.S, 3816 settings = self.settings; 3817 3818 // initialize expedition offset 3819 self.set_expedition_position(); 3820 3821 S(self.scope) 3822 .off('.magellan') 3823 .on('click.fndtn.magellan', '[' + self.add_namespace('data-magellan-arrival') + '] a[href*=#]', function (e) { 3824 var sameHost = ((this.hostname === location.hostname) || !this.hostname), 3825 samePath = self.filterPathname(location.pathname) === self.filterPathname(this.pathname), 3826 testHash = this.hash.replace(/(:|\.|\/)/g, '\\$1'), 3827 anchor = this; 3828 3829 if (sameHost && samePath && testHash) { 3830 e.preventDefault(); 3831 var expedition = $(this).closest('[' + self.attr_name() + ']'), 3832 settings = expedition.data('magellan-expedition-init'), 3833 hash = this.hash.split('#').join(''), 3834 target = $('a[name="' + hash + '"]'); 3835 3836 if (target.length === 0) { 3837 target = $('#' + hash); 3838 3839 } 3840 3841 // Account for expedition height if fixed position 3842 var scroll_top = target.offset().top - settings.destination_threshold + 1; 3843 if (settings.offset_by_height) { 3844 scroll_top = scroll_top - expedition.outerHeight(); 3845 } 3846 $('html, body').stop().animate({ 3847 'scrollTop' : scroll_top 3848 }, settings.duration, settings.easing, function () { 3849 if (history.pushState) { 3850 history.pushState(null, null, anchor.pathname + anchor.search + '#' + hash); 3851 } else { 3852 location.hash = anchor.pathname + anchor.search + '#' + hash; 3853 } 3854 }); 3855 } 3856 }) 3857 .on('scroll.fndtn.magellan', self.throttle(this.check_for_arrivals.bind(this), settings.throttle_delay)); 3858 }, 3859 3860 check_for_arrivals : function () { 3861 var self = this; 3862 self.update_arrivals(); 3863 self.update_expedition_positions(); 3864 }, 3865 3866 set_expedition_position : function () { 3867 var self = this; 3868 $('[' + this.attr_name() + '=fixed]', self.scope).each(function (idx, el) { 3869 var expedition = $(this), 3870 settings = expedition.data('magellan-expedition-init'), 3871 styles = expedition.attr('styles'), // save styles 3872 top_offset, fixed_top; 3873 3874 expedition.attr('style', ''); 3875 top_offset = expedition.offset().top + settings.threshold; 3876 3877 //set fixed-top by attribute 3878 fixed_top = parseInt(expedition.data('magellan-fixed-top')); 3879 if (!isNaN(fixed_top)) { 3880 self.settings.fixed_top = fixed_top; 3881 } 3882 3883 expedition.data(self.data_attr('magellan-top-offset'), top_offset); 3884 expedition.attr('style', styles); 3885 }); 3886 }, 3887 3888 update_expedition_positions : function () { 3889 var self = this, 3890 window_top_offset = $(window).scrollTop(); 3891 3892 $('[' + this.attr_name() + '=fixed]', self.scope).each(function () { 3893 var expedition = $(this), 3894 settings = expedition.data('magellan-expedition-init'), 3895 styles = expedition.attr('style'), // save styles 3896 top_offset = expedition.data('magellan-top-offset'); 3897 3898 //scroll to the top distance 3899 if (window_top_offset + self.settings.fixed_top >= top_offset) { 3900 // Placeholder allows height calculations to be consistent even when 3901 // appearing to switch between fixed/non-fixed placement 3902 var placeholder = expedition.prev('[' + self.add_namespace('data-magellan-expedition-clone') + ']'); 3903 if (placeholder.length === 0) { 3904 placeholder = expedition.clone(); 3905 placeholder.removeAttr(self.attr_name()); 3906 placeholder.attr(self.add_namespace('data-magellan-expedition-clone'), ''); 3907 expedition.before(placeholder); 3908 } 3909 expedition.css({position :'fixed', top : settings.fixed_top}).addClass('fixed'); 3910 } else { 3911 expedition.prev('[' + self.add_namespace('data-magellan-expedition-clone') + ']').remove(); 3912 expedition.attr('style', styles).css('position', '').css('top', '').removeClass('fixed'); 3913 } 3914 }); 3915 }, 3916 3917 update_arrivals : function () { 3918 var self = this, 3919 window_top_offset = $(window).scrollTop(); 3920 3921 $('[' + this.attr_name() + ']', self.scope).each(function () { 3922 var expedition = $(this), 3923 settings = expedition.data(self.attr_name(true) + '-init'), 3924 offsets = self.offsets(expedition, window_top_offset), 3925 arrivals = expedition.find('[' + self.add_namespace('data-magellan-arrival') + ']'), 3926 active_item = false;
3927 offsets.each(function (idx, item) { 3928 if (item.viewport_offset >= item.top_offset) { 3929 var arrivals = expedition.find('[' + self.add_namespace('data-magellan-arrival') + ']'); 3930 arrivals.not(item.arrival).removeClass(settings.active_class); 3931 item.arrival.addClass(settings.active_class); 3932 active_item = true; 3933 return true; 3934 } 3935 }); 3936 3937 if (!active_item) { 3938 arrivals.removeClass(settings.active_class); 3939 } 3940 }); 3941 }, 3942 3943 offsets : function (expedition, window_offset) { 3944 var self = this, 3945 settings = expedition.data(self.attr_name(true) + '-init'), 3946 viewport_offset = window_offset; 3947 3948 return expedition.find('[' + self.add_namespace('data-magellan-arrival') + ']').map(function (idx, el) { 3949 var name = $(this).data(self.data_attr('magellan-arrival')), 3950 dest = $('[' + self.add_namespace('data-magellan-destination') + '=' + name + ']'); 3951 if (dest.length > 0) { 3952 var top_offset = dest.offset().top - settings.destination_threshold; 3953 if (settings.offset_by_height) { 3954 top_offset = top_offset - expedition.outerHeight(); 3955 } 3956 top_offset = Math.floor(top_offset); 3957 return { 3958 destination : dest, 3959 arrival : $(this), 3960 top_offset : top_offset, 3961 viewport_offset : viewport_offset 3962 } 3963 } 3964 }).sort(function (a, b) { 3965 if (a.top_offset < b.top_offset) { 3966 return -1; 3967 } 3968 if (a.top_offset > b.top_offset) { 3969 return 1; 3970 } 3971 return 0; 3972 }); 3973 }, 3974 3975 data_attr : function (str) { 3976 if (this.namespace.length > 0) { 3977 return this.namespace + '-' + str; 3978 } 3979 3980 return str; 3981 }, 3982 3983 off : function () { 3984 this.S(this.scope).off('.magellan'); 3985 this.S(window).off('.magellan'); 3986 }, 3987 3988 filterPathname : function (pathname) { 3989 pathname = pathname || ''; 3990 return pathname 3991 .replace(/^\//,'') 3992 .replace(/(?:index|default).[a-zA-Z]{3,4}$/,'') 3993 .replace(/\/$/,''); 3994 }, 3995 3996 reflow : function () { 3997 var self = this; 3998 // remove placeholder expeditions used for height calculation purposes 3999 $('[' + self.add_namespace('data-magellan-expedition-clone') + ']', self.scope).remove(); 4000 } 4001 }; 4002}(jQuery, window, window.document)); 4003 4004;(function ($, window, document, undefined) { 4005 'use strict'; 4006 4007 Foundation.libs.offcanvas = { 4008 name : 'offcanvas', 4009 4010 version : '5.5.3', 4011 4012 settings : { 4013 open_method : 'move', 4014 close_on_click : false 4015 }, 4016 4017 init : function (scope, method, options) { 4018 this.bindings(method, options); 4019 }, 4020 4021 events : function () { 4022 var self = this, 4023 S = self.S, 4024 move_class = '', 4025 right_postfix = '', 4026 left_postfix = '', 4027 top_postfix = '', 4028 bottom_postfix = ''; 4029 4030 if (this.settings.open_method === 'move') { 4031 move_class = 'move-'; 4032 right_postfix = 'right'; 4033 left_postfix = 'left'; 4034 top_postfix = 'top'; 4035 bottom_postfix = 'bottom'; 4036 } else if (this.settings.open_method === 'overlap_single') { 4037 move_class = 'offcanvas-overlap-'; 4038 right_postfix = 'right'; 4039 left_postfix = 'left'; 4040 top_postfix = 'top'; 4041 bottom_postfix = 'bottom'; 4042 } else if (this.settings.open_method === 'overlap') { 4043 move_class = 'offcanvas-overlap'; 4044 } 4045 4046 S(this.scope).off('.offcanvas') 4047 .on('click.fndtn.offcanvas', '.left-off-canvas-toggle', function (e) { 4048 self.click_toggle_class(e, move_class + right_postfix); 4049 if (self.settings.open_method !== 'overlap') { 4050 S('.left-submenu').removeClass(move_class + right_postfix); 4051 } 4052 $('.left-off-canvas-toggle').attr('aria-expanded', 'true'); 4053 }) 4054 .on('click.fndtn.offcanvas', '.left-off-canvas-menu a', function (e) { 4055 var settings = self.get_settings(e); 4056 var parent = S(this).parent(); 4057 4058 if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) { 4059 self.hide.call(self, move_class + right_postfix, self.get_wrapper(e)); 4060 parent.parent().removeClass(move_class + right_postfix); 4061 } else if (S(this).parent().hasClass('has-submenu')) { 4062 e.preventDefault(); 4063 S(this).siblings('.left-submenu').toggleClass(move_class + right_postfix); 4064 } else if (parent.hasClass('back')) { 4065 e.preventDefault(); 4066 parent.parent().removeClass(move_class + right_postfix); 4067 } 4068 $('.left-off-canvas-toggle').attr('aria-expanded', 'true'); 4069 }) 4070 //end of left canvas 4071 .on('click.fndtn.offcanvas', '.right-off-canvas-toggle', function (e) { 4072 self.click_toggle_class(e, move_class + left_postfix); 4073 if (self.settings.open_method !== 'overlap') { 4074 S('.right-submenu').removeClass(move_class + left_postfix); 4075 } 4076 $('.right-off-canvas-toggle').attr('aria-expanded', 'true'); 4077 }) 4078 .on('click.fndtn.offcanvas', '.right-off-canvas-menu a', function (e) { 4079 var settings = self.get_settings(e); 4080 var parent = S(this).parent(); 4081 4082 if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) { 4083 self.hide.call(self, move_class + left_postfix, self.get_wrapper(e)); 4084 parent.parent().removeClass(move_class + left_postfix); 4085 } else if (S(this).parent().hasClass('has-submenu')) { 4086 e.preventDefault(); 4087 S(this).siblings('.right-submenu').toggleClass(move_class + left_postfix); 4088 } else if (parent.hasClass('back')) { 4089 e.preventDefault(); 4090 parent.parent().removeClass(move_class + left_postfix); 4091 } 4092 $('.right-off-canvas-toggle').attr('aria-expanded', 'true'); 4093 }) 4094 //end of right canvas 4095 .on('click.fndtn.offcanvas', '.top-off-canvas-toggle', function (e) { 4096 self.click_toggle_class(e, move_class + bottom_postfix); 4097 if (self.settings.open_method !== 'overlap') { 4098 S('.top-submenu').removeClass(move_class + bottom_postfix); 4099 } 4100 $('.top-off-canvas-toggle').attr('aria-expanded', 'true'); 4101 }) 4102 .on('click.fndtn.offcanvas', '.top-off-canvas-menu a', function (e) { 4103 var settings = self.get_settings(e); 4104 var parent = S(this).parent(); 4105 4106 if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) { 4107 self.hide.call(self, move_class + bottom_postfix, self.get_wrapper(e)); 4108 parent.parent().removeClass(move_class + bottom_postfix); 4109 } else if (S(this).parent().hasClass('has-submenu')) { 4110 e.preventDefault(); 4111 S(this).siblings('.top-submenu').toggleClass(move_class + bottom_postfix); 4112 } else if (parent.hasClass('back')) { 4113 e.preventDefault(); 4114 parent.parent().removeClass(move_class + bottom_postfix); 4115 } 4116 $('.top-off-canvas-toggle').attr('aria-expanded', 'true'); 4117 }) 4118 //end of top canvas 4119 .on('click.fndtn.offcanvas', '.bottom-off-canvas-toggle', function (e) { 4120 self.click_toggle_class(e, move_class + top_postfix); 4121 if (self.settings.open_method !== 'overlap') { 4122 S('.bottom-submenu').removeClass(move_class + top_postfix); 4123 } 4124 $('.bottom-off-canvas-toggle').attr('aria-expanded', 'true'); 4125 }) 4126 .on('click.fndtn.offcanvas', '.bottom-off-canvas-menu a', function (e) { 4127 var settings = self.get_settings(e); 4128 var parent = S(this).parent(); 4129 4130 if (settings.close_on_click && !parent.hasClass('has-submenu') && !parent.hasClass('back')) { 4131 self.hide.call(self, move_class + top_postfix, self.get_wrapper(e)); 4132 parent.parent().removeClass(move_class + top_postfix); 4133 } else if (S(this).parent().hasClass('has-submenu')) { 4134 e.preventDefault(); 4135 S(this).siblings('.bottom-submenu').toggleClass(move_class + top_postfix); 4136 } else if (parent.hasClass('back')) { 4137 e.preventDefault(); 4138 parent.parent().removeClass(move_class + top_postfix); 4139 } 4140 $('.bottom-off-canvas-toggle').attr('aria-expanded', 'true'); 4141 }) 4142 //end of bottom 4143 .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) { 4144 self.click_remove_class(e, move_class + left_postfix); 4145 S('.right-submenu').removeClass(move_class + left_postfix); 4146 if (right_postfix) { 4147 self.click_remove_class(e, move_class + right_postfix); 4148 S('.left-submenu').removeClass(move_class + left_postfix); 4149 } 4150 $('.right-off-canvas-toggle').attr('aria-expanded', 'true'); 4151 }) 4152 .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) { 4153 self.click_remove_class(e, move_class + left_postfix); 4154 $('.left-off-canvas-toggle').attr('aria-expanded', 'false'); 4155 if (right_postfix) { 4156 self.click_remove_class(e, move_class + right_postfix); 4157 $('.right-off-canvas-toggle').attr('aria-expanded', 'false'); 4158 } 4159 }) 4160 .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) { 4161 self.click_remove_class(e, move_class + top_postfix); 4162 S('.bottom-submenu').removeClass(move_class + top_postfix); 4163 if (bottom_postfix) { 4164 self.click_remove_class(e, move_class + bottom_postfix); 4165 S('.top-submenu').removeClass(move_class + top_postfix); 4166 } 4167 $('.bottom-off-canvas-toggle').attr('aria-expanded', 'true'); 4168 }) 4169 .on('click.fndtn.offcanvas', '.exit-off-canvas', function (e) { 4170 self.click_remove_class(e, move_class + top_postfix); 4171 $('.top-off-canvas-toggle').attr('aria-expanded', 'false'); 4172 if (bottom_postfix) { 4173 self.click_remove_class(e, move_class + bottom_postfix); 4174 $('.bottom-off-canvas-toggle').attr('aria-expanded', 'false'); 4175 } 4176 }); 4177 }, 4178 4179 toggle : function (class_name, $off_canvas) { 4180 $off_canvas = $off_canvas || this.get_wrapper(); 4181 if ($off_canvas.is('.' + class_name)) { 4182 this.hide(class_name, $off_canvas); 4183 } else { 4184 this.show(class_name, $off_canvas); 4185 } 4186 }, 4187 4188 show : function (class_name, $off_canvas) { 4189 $off_canvas = $off_canvas || this.get_wrapper(); 4190 $off_canvas.trigger('open.fndtn.offcanvas'); 4191 $off_canvas.addClass(class_name); 4192 }, 4193 4194 hide : function (class_name, $off_canvas) { 4195 $off_canvas = $off_canvas || this.get_wrapper(); 4196 $off_canvas.trigger('close.fndtn.offcanvas'); 4197 $off_canvas.removeClass(class_name); 4198 }, 4199 4200 click_toggle_class : function (e, class_name) { 4201 e.preventDefault(); 4202 var $off_canvas = this.get_wrapper(e); 4203 this.toggle(class_name, $off_canvas); 4204 }, 4205 4206 click_remove_class : function (e, class_name) { 4207 e.preventDefault(); 4208 var $off_canvas = this.get_wrapper(e); 4209 this.hide(class_name, $off_canvas); 4210 }, 4211 4212 get_settings : function (e) { 4213 var offcanvas = this.S(e.target).closest('[' + this.attr_name() + ']'); 4214 return offcanvas.data(this.attr_name(true) + '-init') || this.settings; 4215 }, 4216 4217 get_wrapper : function (e) { 4218 var $off_canvas = this.S(e ? e.target : this.scope).closest('.off-canvas-wrap'); 4219 4220 if ($off_canvas.length === 0) { 4221 $off_canvas = this.S('.off-canvas-wrap'); 4222 } 4223 return $off_canvas; 4224 }, 4225 4226 reflow : function () {} 4227 }; 4228}(jQuery, window, window.document)); 4229 4230;(function ($, window, document, undefined) { 4231 'use strict'; 4232 4233 var noop = function () {}; 4234 4235 var Orbit = function (el, settings) { 4236 // Don't reinitialize plugin
4237 if (el.hasClass(settings.slides_container_class)) { 4238 return this; 4239 } 4240 4241 var self = this, 4242 container, 4243 slides_container = el, 4244 number_container, 4245 bullets_container, 4246 timer_container, 4247 idx = 0, 4248 animate, 4249 timer, 4250 locked = false, 4251 adjust_height_after = false; 4252 4253 self.slides = function () { 4254 return slides_container.children(settings.slide_selector); 4255 }; 4256 4257 self.slides().first().addClass(settings.active_slide_class); 4258 4259 self.update_slide_number = function (index) { 4260 if (settings.slide_number) { 4261 number_container.find('span:first').text(parseInt(index) + 1); 4262 number_container.find('span:last').text(self.slides().length); 4263 } 4264 if (settings.bullets) { 4265 bullets_container.children().removeClass(settings.bullets_active_class); 4266 $(bullets_container.children().get(index)).addClass(settings.bullets_active_class); 4267 } 4268 }; 4269 4270 self.update_active_link = function (index) { 4271 var link = $('[data-orbit-link="' + self.slides().eq(index).attr('data-orbit-slide') + '"]'); 4272 link.siblings().removeClass(settings.bullets_active_class); 4273 link.addClass(settings.bullets_active_class); 4274 }; 4275 4276 self.build_markup = function () { 4277 slides_container.wrap('<div class="' + settings.container_
4277class + '"></div>'); 4278 container = slides_container.parent(); 4279 slides_container.addClass(settings.slides_container_class); 4280 4281 if (settings.stack_on_small) { 4282 container.addClass(settings.stack_on_small_class); 4283 } 4284 4285 if (settings.navigation_arrows) { 4286 container.append($('<a href="#"><span></span></a>').addClass(settings.prev_class)); 4287 container.append($('<a href="#"><span></span></a>').addClass(settings.next_class)); 4288 } 4289 4290 if (settings.timer) { 4291 timer_container = $('<div>').addClass(settings.timer_container_class); 4292 timer_container.append('<span>'); 4293 timer_container.append($('<div>').addClass(settings.timer_progress_class)); 4294 timer_container.addClass(settings.timer_paused_class); 4295 container.append(timer_container); 4296 } 4297 4298 if (settings.slide_number) { 4299 number_container = $('<div>').addClass(settings.slide_number_class); 4300 number_container.append('<span></span> ' + settings.slide_number_text + ' <span></span>'); 4301 container.append(number_container); 4302 } 4303 4304 if (settings.bullets) { 4305 bullets_container = $('<ol>').addClass(settings.bullets_container_class); 4306 container.append(bullets_container); 4307 bullets_container.wrap('<div class="orbit-bullets-container"></div>'); 4308 self.slides().each(function (idx, el) { 4309 var bullet = $('<li>').attr('data-orbit-slide', idx).on('click', self.link_bullet);; 4310 bullets_container.append(bullet); 4311 }); 4312 } 4313 4314 }; 4315 4316 self._goto = function (next_idx, start_timer) { 4317 // if (locked) {return false;} 4318 if (next_idx === idx) {return false;} 4319 if (typeof timer === 'object') {timer.restart();} 4320 var slides = self.slides(); 4321 4322 var dir = 'next'; 4323 locked = true; 4324 if (next_idx < idx) {dir = 'prev';} 4325 if (next_idx >= slides.length) { 4326 if (!settings.circular) { 4327 return false; 4328 } 4329 next_idx = 0; 4330 } else if (next_idx < 0) { 4331 if (!settings.circular) { 4332 return false; 4333 } 4334 next_idx = slides.length - 1; 4335 } 4336 4337 var current = $(slides.get(idx)); 4338 var next = $(slides.get(next_idx)); 4339 4340 current.css('zIndex', 2); 4341 current.removeClass(settings.active_slide_class); 4342 next.css('zIndex', 4).addClass(settings.active_slide_class); 4343
4344 slides_container.trigger('before-slide-change.fndtn.orbit'); 4345 settings.before_slide_change(); 4346 self.update_active_link(next_idx); 4347 4348 var callback = function () { 4349 var unlock = function () { 4350 idx = next_idx; 4351 locked = false; 4352 if (start_timer === true) {timer = self.create_timer(); timer.start();} 4353 self.update_slide_number(idx); 4354 slides_container.trigger('after-slide-change.fndtn.orbit', [{slide_number : idx, total_slides : slides.length}]); 4355 settings.after_slide_change(idx, slides.length); 4356 }; 4357 if (slides_container.outerHeight() != next.outerHeight() && settings.variable_height) { 4358 slides_container.animate({'height': next.outerHeight()}, 250, 'linear', unlock); 4359 } else { 4360 unlock(); 4361 } 4362 }; 4363 4364 if (slides.length === 1) {callback(); return false;} 4365 4366 var start_animation = function () { 4367 if (dir === 'next') {animate.next(current, next, callback);} 4368 if (dir === 'prev') {animate.prev(current, next, callback);} 4369 }; 4370 4371 if (next.outerHeight() > slides_container.outerHeight() && settings.variable_height) { 4372 slides_container.animate({'height': next.outerHeight()}, 250, 'linear', start_animation); 4373 } else { 4374 start_animation(); 4375 } 4376 }; 4377 4378 self.next = function (e) { 4379 e.stopImmediatePropagation(); 4380 e.preventDefault(); 4381 self._goto(idx + 1); 4382 }; 4383 4384 self.prev = function (e) { 4385 e.stopImmediatePropagation(); 4386 e.preventDefault(); 4387 self._goto(idx - 1); 4388 }; 4389 4390 self.link_custom = function (e) { 4391 e.preventDefault(); 4392 var link = $(this).attr('data-orbit-link'); 4393 if ((typeof link === 'string') && (link = $.trim(link)) != '') { 4394 var slide = container.find('[data-orbit-slide=' + link + ']'); 4395 if (slide.index() != -1) {self._goto(slide.index());} 4396 } 4397 }; 4398 4399 self.link_bullet = function (e) { 4400 var index = $(this).attr('data-orbit-slide'); 4401 if ((typeof index === 'string') && (index = $.trim(index)) != '') { 4402 if (isNaN(parseInt(index))) { 4403 var slide = container.find('[data-orbit-slide=' + index + ']'); 4404 if (slide.index() != -1) {self._goto(slide.index() + 1);} 4405 } else { 4406 self._goto(parseInt(index)); 4407 } 4408 } 4409 4410 } 4411 4412 self.timer_callback = function () { 4413 self._goto(idx + 1, true); 4414 } 4415 4416 self.compute_dimensions = function () { 4417 var current = $(self.slides().get(idx)); 4418 var h = current.outerHeight(); 4419 if (!settings.variable_height) { 4420 self.slides().each(function(){ 4421 if ($(this).outerHeight() > h) { h = $(this).outerHeight(); } 4422 }); 4423 } 4424 slides_container.height(h); 4425 }; 4426 4427 self.create_timer = function () { 4428 var t = new Timer( 4429 container.find('.' + settings.timer_container_class), 4430 settings, 4431 self.timer_callback 4432 ); 4433 return t; 4434 }; 4435 4436 self.stop_timer = function () { 4437 if (typeof timer === 'object') { 4438 timer.stop(); 4439 } 4440 }; 4441 4442 self.toggle_timer = function () { 4443 var t = container.find('.' + settings.timer_container_class); 4444 if (t.hasClass(settings.timer_paused_class)) { 4445 if (typeof timer === 'undefined') {timer = self.create_timer();} 4446 timer.start(); 4447 } else { 4448 if (typeof timer === 'object') {timer.stop();} 4449 } 4450 }; 4451 4452 self.init = function () { 4453 self.build_markup(); 4454 if (settings.timer) { 4455 timer = self.create_timer(); 4456 Foundation.utils.image_loaded(this.slides().children('img'), timer.start); 4457 } 4458 animate = new FadeAnimation(settings, slides_container); 4459 if (settings.animation === 'slide') { 4460 animate = new SlideAnimation(settings, slides_container); 4461 } 4462 4463 container.on('click', '.' + settings.next_class, self.next); 4464 container.on('click', '.' + settings.prev_class, self.prev); 4465 4466 if (settings.next_on_click) { 4467 container.on('click', '.' + settings.slides_container_class + ' [data-orbit-slide]', self.link_bullet); 4468 } 4469 4470 container.on('click', self.toggle_timer); 4471 if (settings.swipe) { 4472 container.on('touchstart.fndtn.orbit', function (e) { 4473 if (!e.touches) {e = e.originalEvent;} 4474 var data = { 4475 start_page_x : e.touches[0].pageX, 4476 start_page_y : e.touches[0].pageY, 4477 start_time : (new Date()).getTime(), 4478 delta_x : 0, 4479 is_scrolling : undefined 4480 }; 4481 container.data('swipe-transition', data); 4482 e.stopPropagation(); 4483 }) 4484 .on('touchmove.fndtn.orbit', function (e) { 4485 if (!e.touches) { 4486 e = e.originalEvent; 4487 } 4488 // Ignore pinch/zoom events 4489 if (e.touches.length > 1 || e.scale && e.scale !== 1) { 4490 return; 4491 } 4492 4493 var data = container.data('swipe-transition'); 4494 if (typeof data === 'undefined') {data = {};} 4495 4496 data.delta_x = e.touches[0].pageX - data.start_page_x; 4497 4498 if ( typeof data.is_scrolling === 'undefined') { 4499 data.is_scrolling = !!( data.is_scrolling || Math.abs(data.delta_x) < Math.abs(e.touches[0].pageY - data.start_page_y) ); 4500 } 4501 4502 if (!data.is_scrolling && !data.active) { 4503 e.preventDefault(); 4504 var direction = (data.delta_x < 0) ? (idx + 1) : (idx - 1); 4505 data.active = true; 4506 self._goto(direction); 4507 } 4508 }) 4509 .on('touchend.fndtn.orbit', function (e) { 4510 container.data('swipe-transition', {}); 4511 e.stopPropagation(); 4512 }) 4513 } 4514 container.on('mouseenter.fndtn.orbit', function (e) { 4515 if (settings.timer && settings.pause_on_hover) { 4516 self.stop_timer(); 4517 } 4518 }) 4519 .on('mouseleave.fndtn.orbit', function (e) { 4520 if (settings.timer && settings.resume_on_mouseout) { 4521 timer.start(); 4522 } 4523 }); 4524 4525 $(document).on('click', '[data-orbit-link]', self.link_custom); 4526 $(window).on('load resize', self.compute_dimensions); 4527 Foundation.utils.image_loaded(this.slides().children('img'), self.compute_dimensions); 4528 Foundation.utils.image_loaded(this.slides().children('img'), function () { 4529 container.prev('.' + settings.preloader_class).css('display', 'none'); 4530 self.update_slide_number(0); 4531 self.update_active_link(0); 4532 slides_container.trigger('ready.fndtn.orbit'); 4533 }); 4534 }; 4535 4536 self.init(); 4537 }; 4538
4539 var Timer = function (el, settings, callback) { 4540 var self = this, 4541 duration = settings.timer_speed, 4542 progress = el.find('.' + settings.timer_progress_class), 4543 start, 4544 timeout, 4545 left = -1; 4546 4547 this.update_progress = function (w) { 4548 var new_progress = progress.clone(); 4549 new_progress.attr('style', ''); 4550 new_progress.css('width', w + '%'); 4551 progress.replaceWith(new_progress); 4552 progress = new_progress; 4553 }; 4554 4555 this.restart = function () { 4556 clearTimeout(timeout); 4557 el.addClass(settings.timer_paused_class); 4558 left = -1; 4559 self.update_progress(0); 4560 }; 4561 4562 this.start = function () { 4563 if (!el.hasClass(settings.timer_paused_class)) {return true;} 4564 left = (left === -1) ? duration : left; 4565 el.removeClass(settings.timer_paused_class); 4566 start = new Date().getTime(); 4567 progress.animate({'width' : '100%'}, left, 'linear'); 4568 timeout = setTimeout(function () { 4569 self.restart(); 4570 callback(); 4571 }, left); 4572 el.trigger('timer-started.fndtn.orbit') 4573 }; 4574 4575 this.stop = function () { 4576 if (el.hasClass(settings.timer_paused_class)) {return true;} 4577 clearTimeout(timeout); 4578 el.addClass(settings.timer_paused_class); 4579 var end = new Date().getTime(); 4580 left = left - (end - start); 4581 var w = 100 - ((left / duration) * 100); 4582 self.update_progress(w); 4583 el.trigger('timer-stopped.fndtn.orbit'); 4584 }; 4585 }; 4586 4587 var SlideAnimation = function (settings, container) { 4588 var duration = settings.animation_speed; 4589 var is_rtl = ($('html[dir=rtl]').length === 1); 4590 var margin = is_rtl ? 'marginRight' : 'marginLeft'; 4591 var animMargin = {}; 4592 animMargin[margin] = '0%'; 4593 4594 this.next = function (current, next, callback) { 4595 current.animate({marginLeft : '-100%'}, duration); 4596 next.animate(animMargin, duration, function () { 4597 current.css(margin, '100%'); 4598 callback(); 4599 }); 4600 }; 4601 4602 this.prev = function (current, prev, callback) { 4603 current.animate({marginLeft : '100%'}, duration); 4604 prev.css(margin, '-100%'); 4605 prev.animate(animMargin, duration, function () { 4606 current.css(margin, '100%'); 4607 callback(); 4608 }); 4609 }; 4610 }; 4611 4612 var FadeAnimation = function (settings, container) { 4613 var duration = settings.animation_speed; 4614 var is_rtl = ($('html[dir=rtl]').length === 1); 4615 var margin = is_rtl ? 'marginRight' : 'marginLeft'; 4616 4617 this.next = function (current, next, callback) { 4618 next.css({'margin' : '0%', 'opacity' : '0.01'}); 4619 next.animate({'opacity' :'1'}, duration, 'linear', function () { 4620 current.css('margin', '100%'); 4621 callback(); 4622 }); 4623 }; 4624 4625 this.prev = function (current, prev, callback) { 4626 prev.css({'margin' : '0%', 'opacity' : '0.01'}); 4627 prev.animate({'opacity' : '1'}, duration, 'linear', function () { 4628 current.css('margin', '100%'); 4629 callback(); 4630 }); 4631 }; 4632 }; 4633 4634 Foundation.libs = Foundation.libs || {}; 4635 4636 Foundation.libs.orbit = { 4637 name : 'orbit', 4638 4639 version : '5.5.3', 4640 4641 settings : { 4642 animation : 'slide', 4643 timer_speed : 10000, 4644 pause_on_hover : true, 4645 resume_on_mouseout : false, 4646 next_on_click : true, 4647 animation_speed : 500, 4648 stack_on_small : false, 4649 navigation_arrows : true, 4650 slide_number : true, 4651 slide_number_text : 'of',
4652 container_class : 'orbit-container', 4653 stack_on_small_class : 'orbit-stack-on-small', 4654 next_class : 'orbit-next', 4655 prev_class : 'orbit-prev', 4656 timer_container_class : 'orbit-timer', 4657 timer_paused_class : 'paused', 4658 timer_progress_class : 'orbit-progress', 4659 slides_container_class : 'orbit-slides-container', 4660 preloader_class : 'preloader', 4661 slide_selector : '*', 4662 bullets_container_class : 'orbit-bullets', 4663 bullets_active_class : 'active', 4664 slide_number_class : 'orbit-slide-number', 4665 caption_class : 'orbit-caption', 4666 active_slide_class : 'active', 4667 orbit_transition_class : 'orbit-transitioning', 4668 bullets : true, 4669 circular : true, 4670 timer : true, 4671 variable_height : false, 4672 swipe : true, 4673 before_slide_change : noop, 4674 after_slide_change : noop 4675 }, 4676 4677 init : function (scope, method, options) { 4678 var self = this; 4679 this.bindings(method, options); 4680 }, 4681 4682 events : function (instance) { 4683 var orbit_instance = new Orbit(this.S(instance), this.S(instance).data('orbit-init')); 4684 this.S(instance).data(this.name + '-instance', orbit_instance); 4685 }, 4686 4687 reflow : function () { 4688 var self = this; 4689 4690 if (self.S(self.scope).is('[data-orbit]')) { 4691 var $el = self.S(self.scope); 4692 var instance = $el.data(self.name + '-instance'); 4693 instance.compute_dimensions(); 4694 } else { 4695 self.S('[data-orbit]', self.scope).each(function (idx, el) { 4696 var $el = self.S(el); 4697 var opts = self.data_options($el); 4698 var instance = $el.data(self.name + '-instance'); 4699 instance.compute_dimensions(); 4700 }); 4701 } 4702 } 4703 }; 4704 4705}(jQuery, window, window.document)); 4706 4707;(function ($, window, document, undefined) { 4708 'use strict'; 4709 4710 var openModals = []; 4711 4712 Foundation.libs.reveal = { 4713 name : 'reveal', 4714 4715 version : '5.5.3', 4716 4717 locked : false, 4718 4719 settings : { 4720 animation : 'fadeAndPop', 4721 animation_speed : 250, 4722 close_on_background_click : true, 4723 close_on_esc : true,
4724 dismiss_modal_class : 'close-reveal-modal', 4725 multiple_opened : false, 4726 bg_class : 'reveal-modal-bg', 4727 root_element : 'body', 4728 open : function(){}, 4729 opened : function(){}, 4730 close : function(){}, 4731 closed : function(){}, 4732 on_ajax_error: $.noop, 4733 bg : $('.reveal-modal-bg'), 4734 css : { 4735 open : { 4736 'opacity' : 0, 4737 'visibility' : 'visible', 4738 'display' : 'block' 4739 }, 4740 close : { 4741 'opacity' : 1, 4742 'visibility' : 'hidden', 4743 'display' : 'none' 4744 } 4745 } 4746 }, 4747 4748 init : function (scope, method, options) { 4749 $.extend(true, this.settings, method, options); 4750 this.bindings(method, options); 4751 }, 4752 4753 events : function (scope) { 4754 var self = this, 4755 S = self.S; 4756 4757 S(this.scope) 4758 .off('.reveal') 4759 .on('click.fndtn.reveal', '[' + this.add_namespace('data-reveal-id') + ']:not([disabled])', function (e) { 4760 e.preventDefault(); 4761 4762 if (!self.locked) { 4763 var element = S(this), 4764 ajax = element.data(self.data_attr('reveal-ajax')), 4765 replaceContentSel = element.data(self.data_attr('reveal-replace-content')); 4766 4767 self.locked = true; 4768 4769 if (typeof ajax === 'undefined') { 4770 self.open.call(self, element); 4771 } else { 4772 var url = ajax === true ? element.attr('href') : ajax; 4773 self.open.call(self, element, {url : url}, { replaceContentSel : replaceContentSel }); 4774 } 4775 } 4776 }); 4777 4778 S(document) 4779 .on('click.fndtn.reveal', this.close_targets(), function (e) { 4780 e.preventDefault(); 4781 if (!self.locked) { 4782 var settings = S('[' + self.attr_name() + '].open').data(self.attr_name(true) + '-init') || self.settings, 4783 bg_clicked = S(e.target)[0] === S('.' + settings.bg_class)[0]; 4784 4785 if (bg_clicked) { 4786 if (settings.close_on_background_click) { 4787 e.stopPropagation(); 4788 } else { 4789 return; 4790 } 4791 } 4792 4793 self.locked = true; 4794 self.close.call(self, bg_clicked ? S('[' + self.attr_name() + '].open:not(.toback)') : S(this).closest('[' + self.attr_name() + ']')); 4795 } 4796 }); 4797 4798 if (S('[' + self.attr_name() + ']', this.scope).length > 0) { 4799 S(this.scope) 4800 // .off('.reveal') 4801 .on('open.fndtn.reveal', this.settings.open) 4802 .on('opened.fndtn.reveal', this.settings.opened) 4803 .on('opened.fndtn.reveal', this.open_video) 4804 .on('close.fndtn.reveal', this.settings.close) 4805 .on('closed.fndtn.reveal', this.settings.closed) 4806 .on('closed.fndtn.reveal', this.close_video); 4807 } else { 4808 S(this.scope) 4809 // .off('.reveal') 4810 .on('open.fndtn.reveal', '[' + self.attr_name() + ']', this.settings.open) 4811 .on('opened.fndtn.reveal', '[' + self.attr_name() + ']', this.settings.opened) 4812 .on('opened.fndtn.reveal', '[' + self.attr_name() + ']', this.open_video) 4813 .on('close.fndtn.reveal', '[' + self.attr_name() + ']', this.settings.close) 4814 .on('closed.fndtn.reveal', '[' + self.attr_name() + ']', this.settings.closed) 4815 .on('closed.fndtn.reveal', '[' + self.attr_name() + ']', this.close_video); 4816 } 4817 4818 return true; 4819 }, 4820 4821 // PATCH #3: turning on key up capture only when a reveal window is open 4822 key_up_on : function (scope) { 4823 var self = this; 4824 4825 // PATCH #1: fixing multiple keyup event trigger from single key press 4826 self.S('body').off('keyup.fndtn.reveal').on('keyup.fndtn.reveal', function ( event ) { 4827 var open_modal = self.S('[' + self.attr_name() + '].open'), 4828 settings = open_modal.data(self.attr_name(true) + '-init') || self.settings ; 4829 // PATCH #2: making sure that the close event can be called only while unlocked, 4830 // so that multiple keyup.fndtn.reveal events don't prevent clean closing of the reveal window. 4831 if ( settings && event.which === 27 && settings.close_on_esc && !self.locked) { // 27 is the keycode for the Escape key 4832 self.close.call(self, open_modal); 4833 } 4834 }); 4835 4836 return true; 4837 }, 4838 4839 // PATCH #3: turning on key up capture only when a reveal window is open 4840 key_up_off : function (scope) { 4841 this.S('body').off('keyup.fndtn.reveal'); 4842 return true; 4843 }, 4844 4845 open : function (target, ajax_settings) { 4846 var self = this, 4847 modal; 4848 4849 if (target) { 4850 if (typeof target.selector !== 'undefined') { 4851 // Find the named node; only use the first one found, since the rest of the code assumes there's only one node 4852 modal = self.S('#' + target.data(self.data_attr('reveal-id'))).first(); 4853 } else { 4854 modal = self.S(this.scope); 4855 4856 ajax_settings = target; 4857 } 4858 } else { 4859 modal = self.S(this.scope); 4860 } 4861 4862 var settings = modal.data(self.attr_name(true) + '-init'); 4863 settings = settings || this.settings; 4864 4865 4866 if (modal.hasClass('open') && target !== undefined && target.attr('data-reveal-id') == modal.attr('id')) { 4867 return self.close(modal); 4868 } 4869 4870 if (!modal.hasClass('open')) { 4871 var open_modal = self.S('[' + self.attr_name() + '].open'); 4872 4873 if (typeof modal.data('css-top') === 'undefined') { 4874 modal.data('css-top', parseInt(modal.css('top'), 10)) 4875 .data('offset', this.cache_offset(modal)); 4876 } 4877 4878 modal.attr('tabindex','0').attr('aria-hidden','false'); 4879 4880 this.key_up_on(modal); // PATCH #3: turning on key up capture only when a reveal window is open 4881 4882 // Prevent namespace event from triggering twice 4883 modal.on('open.fndtn.reveal', function(e) { 4884 if (e.namespace !== 'fndtn.reveal') return; 4885 }); 4886 4887 modal.on('open.fndtn.reveal').trigger('open.fndtn.reveal'); 4888 4889 if (open_modal.length < 1) { 4890 this.toggle_bg(modal, true); 4891 } 4892 4893 if (typeof ajax_settings === 'string') { 4894 ajax_settings = { 4895 url : ajax_settings 4896 }; 4897 } 4898 4899 var openModal = function() { 4900 if(open_modal.length > 0) { 4901 if(settings.multiple_opened) { 4902 self.to_back(open_modal); 4903 } else { 4904 self.hide(open_modal, settings.css.close); 4905 } 4906 } 4907 4908 // bl: add the open_modal that isn't already in the background to the openM
4908odals array 4909 if(settings.multiple_opened) { 4910 openModals.push(modal); 4911 } 4912 4913 self.show(modal, settings.css.open); 4914 }; 4915 4916 if (typeof ajax_settings === 'undefined' || !ajax_settings.url) { 4917 openModal(); 4918 } else { 4919 var old_success = typeof ajax_settings.success !== 'undefined' ? ajax_settings.success : null; 4920 $.extend(ajax_settings, { 4921 success : function (data, textStatus, jqXHR) { 4922 if ( $.isFunction(old_success) ) { 4923 var result = old_success(data, textStatus, jqXHR); 4924 if (typeof result == 'string') { 4925 data = result; 4926 } 4927 } 4928 4929 if (typeof options !== 'undefined' && typeof options.replaceContentSel !== 'undefined') { 4930 modal.find(options.replaceContentSel).html(data); 4931 } else { 4932 modal.html(data); 4933 } 4934 4935 self.S(modal).foundation('section', 'reflow'); 4936 self.S(modal).children().foundation(); 4937 4938 openModal(); 4939 } 4940 }); 4941 4942 // check for if user initalized with error callback 4943 if (settings.on_ajax_error !== $.noop) { 4944 $.extend(ajax_settings, { 4945 error : settings.on_ajax_error 4946 }); 4947 } 4948 4949 $.ajax(ajax_settings); 4950 } 4951 } 4952 self.S(window).trigger('resize'); 4953 }, 4954 4955 close : function (modal) { 4956 var modal = modal && modal.length ? modal : this.S(this.scope), 4957 open_modals = this.S('[' + this.attr_name() + '].open'), 4958 settings = modal.data(this.attr_name(true) + '-init') || this.settings, 4959 self = this; 4960 4961 if (open_modals.length > 0) { 4962 4963 modal.removeAttr('tabindex','0').attr('aria-hidden','true'); 4964 4965 this.locked = true; 4966 this.key_up_off(modal); // PATCH #3: turning on key up capture only when a reveal window is open 4967 4968 modal.trigger('close.fndtn.reveal'); 4969 4970 if ((settings.multiple_opened && open_modals.length === 1) || !sett
4970ings.multiple_opened || modal.length > 1) { 4971 self.toggle_bg(modal, false); 4972 self.to_front(modal); 4973 } 4974 4975 if (settings.multiple_opened) { 4976 var isCurrent = modal.is(':not(.toback)'); 4977 self.hide(modal, settings.css.close, settings); 4978 if(isCurrent) { 4979 // remove the last modal since it is now closed 4980 openModals.pop(); 4981 } else { 4982 // if this isn't the current modal, then find it in the array and remove it 4983 openModals = $.grep(openModals, function(elt) { 4984 var isThis = elt[0]===modal[0]; 4985 if(isThis) { 4986 // since it's not currently in the front, put it in the front now that it is hidden 4987 // so that if it's re-opened, it won't be .toback 4988 self.to_front(modal); 4989 } 4990 return !isThis; 4991 }); 4992 } 4993 // finally, show the next modal in the stack, if there is one 4994 if(openModals.length>0) { 4995 self.to_front(openModals[openModals.length - 1]); 4996 } 4997 } else { 4998 self.hide(open_modals, settings.css.close, settings); 4999 } 5000 } 5001 }, 5002 5003 close_targets : function () { 5004 var base = '.' + this.settings.dismiss_modal_class; 5005 5006 if (this.settings.close_on_background_click) { 5007 return base + ', .' + this.settings.bg_class; 5008 } 5009 5010 return base; 5011 }, 5012 5013 toggle_bg : function (modal, state) { 5014 if (this.S('.' + this.settings.bg_class).length === 0) { 5015 this.settings.bg = $('<div />', {'class': this.settings.bg_class}) 5016 .appendTo('body').hide(); 5017 } 5018 5019 var visible = this.settings.bg.filter(':visible').length > 0; 5020 if ( state != visible ) { 5021 if ( state == undefined ? visible : !state ) { 5022 this.hide(this.settings.bg); 5023 } else { 5024 this.show(this.settings.bg); 5025 } 5026 } 5027 }, 5028 5029 show : function (el, css) { 5030 // is modal 5031 if (css) { 5032 var settings = el.data(this.attr_name(true) + '-init') || this.settings, 5033 root_element = settings.root_element, 5034 context = this; 5035 5036 if (el.parent(root_element).length === 0) { 5037 var placeholder = el.wrap('<div style="display: none;" />').parent(); 5038 5039 el.on('closed.fndtn.reveal.wrapped', function () { 5040 el.detach().appendTo(placeholder); 5041 el.unwrap().unbind('closed.fndtn.reveal.wrapped'); 5042 }); 5043 5044 el.detach().appendTo(root_element); 5045 } 5046 5047 var animData = getAnimationData(settings.animation); 5048 if (!animData.animate) { 5049 this.locked = false; 5050 } 5051 if (animData.pop) { 5052 css.top = $(window).scrollTop() - el.data('offset') + 'px'; 5053 var end_css = { 5054 top: $(window).scrollTop() + el.data('css-top') + 'px', 5055 opacity: 1 5056 }; 5057 5058 return setTimeout(function () { 5059 return el 5060 .css(css) 5061 .animate(end_css, settings.animation_speed, 'linear', function () { 5062 context.locked = false; 5063 el.trigger('opened.fndtn.reveal'); 5064 }) 5065 .addClass('open'); 5066 }, settings.animation_speed / 2); 5067 } 5068 5069 css.top = $(window).scrollTop() + el.data('css-top') + 'px'; 5070 5071 if (animData.fade) { 5072 var end_css = {opacity: 1}; 5073 5074 return setTimeout(function () { 5075 return el 5076 .css(css) 5077 .animate(end_css, settings.animation_speed, 'linear', function () { 5078 context.locked = false; 5079 el.trigger('opened.fndtn.reveal'); 5080 }) 5081 .addClass('open'); 5082 }, settings.animation_speed / 2); 5083 } 5084 5085 return el.css(css).show().css({opacity : 1}).addClass('open').trigger('opened.fndtn.reveal'); 5086 } 5087 5088 var settings = this.settings; 5089 5090 // should we animate the background? 5091 if (getAnimationData(settings.animation).fade) { 5092 return el.fadeIn(settings.animation_speed / 2); 5093 } 5094 5095 this.locked = false;
5096 5097 return el.show(); 5098 }, 5099 5100 to_back : function(el) { 5101 el.addClass('toback'); 5102 }, 5103 5104 to_front : function(el) { 5105 el.removeClass('toback'); 5106 }, 5107 5108 hide : function (el, css) { 5109 // is modal 5110 if (css) { 5111 var settings = el.data(this.attr_name(true) + '-init'), 5112 context = this; 5113 settings = settings || this.settings; 5114 5115 var animData = getAnimationData(settings.animation); 5116 if (!animData.animate) { 5117 this.locked = false; 5118 } 5119 if (animData.pop) { 5120 var end_css = { 5121 top: - $(window).scrollTop() - el.data('offset') + 'px', 5122 opacity: 0 5123 }; 5124 5125 return setTimeout(function () { 5126 return el 5127 .animate(end_css, settings.animation_speed, 'linear', function () { 5128 context.locked = false; 5129 el.css(css).trigger('closed.fndtn.reveal'); 5130 }) 5131 .removeClass('open'); 5132 }, settings.animation_speed / 2); 5133 } 5134 5135 if (animData.fade) { 5136 var end_css = {opacity : 0}; 5137 5138 return setTimeout(function () { 5139 return el 5140 .animate(end_css, settings.animation_speed, 'linear', function () { 5141 context.locked = false; 5142 el.css(css).trigger('closed.fndtn.reveal'); 5143 }) 5144 .removeClass('open'); 5145 }, settings.animation_speed / 2); 5146 } 5147 5148 return el.hide().css(css).removeClass('open').trigger('closed.fndtn.reveal'); 5149 } 5150 5151 var settings = this.settings; 5152 5153 // should we animate the background? 5154 if (getAnimationData(settings.animation).fade) { 5155 return el.fadeOut(settings.animation_speed / 2); 5156 } 5157 5158 return el.hide(); 5159 }, 5160 5161 close_video : function (e) { 5162 var video = $('.flex-video', e.target), 5163 iframe = $('iframe', video); 5164 5165 if (iframe.length > 0) { 5166 iframe.attr('data-src', iframe[0].src); 5167 iframe.attr('src', iframe.attr('src')); 5168 video.hide(); 5169 } 5170 }, 5171 5172 open_video : function (e) { 5173 var video = $('.flex-video', e.target), 5174 iframe = video.find('iframe'); 5175 5176 if (iframe.length > 0) { 5177 var data_src = iframe.attr('data-src'); 5178 if (typeof data_src === 'string') { 5179 iframe[0].src = iframe.attr('data-src'); 5180 } else { 5181 var src = iframe[0].src; 5182 iframe[0].src = undefined; 5183 iframe[0].src = src; 5184 } 5185 video.show(); 5186 } 5187 }, 5188 5189 data_attr : function (str) { 5190 if (this.namespace.length > 0) { 5191 return this.namespace + '-' + str; 5192 } 5193 5194 return str; 5195 }, 5196 5197 cache_offset : function (modal) { 5198 var offset = modal.show().height() + parseInt(modal.css('top'), 10) + modal.scrollY; 5199 5200 modal.hide(); 5201 5202 return offset; 5203 }, 5204 5205 off : function () { 5206 $(this.scope).off('.fndtn.reveal'); 5207 }, 5208 5209 reflow : function () {} 5210 }; 5211 5212 /* 5213 * getAnimationData('popAndFade') // {animate: true, pop: true, fade: true} 5214 * getAnimationData('fade') // {animate: true, pop: false, fade: true} 5215 * getAnimationData('pop') // {animate: true, pop: true, fade: false} 5216 * getAnimationData('foo') // {animate: false, pop: false, fade: false} 5217 * getAnimationData(null) // {animate: false, pop: false, fade: false} 5218 */ 5219 function getAnimationData(str) { 5220 var fade = /fade/i.test(str); 5221 var pop = /pop/i.test(str); 5222 return { 5223 animate : fade || pop, 5224 pop : pop, 5225 fade : fade 5226 }; 5227 } 5228}(jQuery, window, window.document)); 5229 5230;(function ($, window, document, undefined) { 5231 'use strict'; 5232 5233 Foundation.libs.slider = { 5234 name : 'slider', 5235 5236 version : '5.5.3', 5237 5238 settings : { 5239 start : 0, 5240 end : 100, 5241 step : 1, 5242 precision : 2, 5243 initial : null, 5244 display_selector : '', 5245 vertical : false, 5246 trigger_input_change : false, 5247 on_change : function () {} 5248 }, 5249 5250 cache : {}, 5251 5252 init : function (scope, method, options) { 5253 Foundation.inherit(this, 'throttle'); 5254 this.bindings(method, options); 5255 this.reflow(); 5256 }, 5257 5258 events : function () { 5259 var self = this; 5260 $(this.scope) 5261 .off('.slider') 5262 .on('mousedown.fndtn.slider touchstart.fndtn.slider pointerdown.fndtn.slider', 5263 '[' + self.attr_name() + ']:not(.disabled, [disabled]) .range-slider-handle', function (e) {
5264 if (!self.cache.active) { 5265 e.preventDefault(); 5266 self.set_active_slider($(e.target)); 5267 } 5268 }) 5269 .on('mousemove.fndtn.slider touchmove.fndtn.slider pointermove.fndtn.slider', function (e) { 5270 if (!!self.cache.active) { 5271 e.preventDefault(); 5272 if ($.data(self.cache.active[0], 'settings').vertical) { 5273 var scroll_offset = 0; 5274 if (!e.pageY) { 5275 scroll_offset = window.scrollY; 5276 } 5277 self.calculate_position(self.cache.active, self.get_cursor_position(e, 'y') + scroll_offset); 5278 } else { 5279 self.calculate_position(self.cache.active, self.get_cursor_position(e, 'x')); 5280 } 5281 } 5282 }) 5283 .on('mouseup.fndtn.slider touchend.fndtn.slider pointerup.fndtn.slider', function (e) { 5284 if(!self.cache.active) { 5285 // if the user has just clicked into the slider without starting to drag the handle 5286 var slider = $(e.target).attr('role') === 'slider' ? $(e.target) : $(e.target).closest('.range-slider').find("[role='slider']"); 5287 5288 if (slider.length && (!slider.parent().hasClass('disabled') && !slider.parent().attr('disabled'))) { 5289 self.set_active_slider(slider); 5290 if ($.data(self.cache.active[0], 'settings').vertical) { 5291 var scroll_offset = 0; 5292 if (!e.pageY) { 5293 scroll_offset = window.scrollY; 5294 } 5295 self.calculate_position(self.cache.active, self.get_cursor_position(e, 'y') + scroll_offset); 5296 } else { 5297 self.calculate_position(self.cache.active, self.get_cursor_position(e, 'x')); 5298 } 5299 } 5300 } 5301 self.remove_active_slider(); 5302 }) 5303 .on('change.fndtn.slider', function (e) { 5304 self.settings.on_change(); 5305 }); 5306 5307 self.S(window) 5308 .on('resize.fndtn.slider', self.throttle(function (e) { 5309 self.reflow(); 5310 }, 300)); 5311 5312 // update slider value as users change input value 5313 this.S('[' + this.attr_name() + ']').each(function () { 5314 var slider = $(this), 5315 handle = slider.children('.range-slider-handle')[0], 5316 settings = self.initialize_settings(handle); 5317 5318 if (settings.display_selector != '') { 5319 $(settings.display_selector).each(function(){ 5320 if ($(this).attr('value')) { 5321 $(this).off('change').on('change', function () { 5322 slider.foundation("slider", "set_value", $(this).val()); 5323 }); 5324 } 5325 }); 5326 } 5327 }); 5328 }, 5329 5330 get_cursor_position : function (e, xy) { 5331 var pageXY = 'page' + xy.toUpperCase(), 5332 clientXY = 'client' + xy.toUpperCase(), 5333 position; 5334 5335 if (typeof e[pageXY] !== 'undefined') { 5336 position = e[pageXY]; 5337 } else if (typeof e.originalEvent[clientXY] !== 'undefined') { 5338 position = e.originalEvent[clientXY]; 5339 } else if (e.originalEvent.touches && e.originalEvent.touches[0] && typeof e.originalEvent.touches[0][clientXY] !== 'undefined') { 5340 position = e.originalEvent.touches[0][clientXY]; 5341 } else if (e.currentPoint && typeof e.currentPoint[xy] !== 'undefined') { 5342 position = e.currentPoint[xy]; 5343 } 5344 5345 return position; 5346 }, 5347 5348 set_active_slider : function ($handle) { 5349 this.cache.active = $handle; 5350 }, 5351 5352 remove_active_slider : function () { 5353 this.cache.active = null; 5354 }, 5355 5356 calculate_position : function ($handle, cursor_x) { 5357 var self = this, 5358 settings = $.data($handle[0], 'settings'), 5359 handle_l = $.data($handle[0], 'handle_l'), 5360 handle_o = $.data($handle[0], 'handle_o'), 5361 bar_l = $.data($handle[0], 'bar_l'), 5362 bar_o = $.data($handle[0], 'bar_o'); 5363 5364 requestAnimationFrame(function () { 5365 var pct; 5366 5367 if (Foundation.rtl && !settings.vertical) { 5368 pct = self.limit_to(((bar_o + bar_l - cursor_x) / bar_l), 0, 1); 5369 } else { 5370 pct = self.limit_to(((cursor_x - bar_o) / bar_l), 0, 1); 5371 } 5372 5373 pct = settings.vertical ? 1 - pct : pct; 5374 5375 var norm = self.normalized_value(pct, settings.start, settings.end, settings.step, settings.precision); 5376 5377 self.set_ui($handle, norm); 5378 }); 5379 }, 5380 5381 set_ui : function ($handle, value) { 5382 var settings = $.data($handle[0], 'settings'), 5383 handle_l = $.data($handle[0], 'handle_l'), 5384 bar_l = $.data($handle[0], 'bar_l'), 5385 norm_pct = this.normalized_percentage(value, settings.start, settings.end), 5386 handle_offset = norm_pct * (bar_l - handle_l) - 1, 5387 progress_bar_length = norm_pct * 100,
5388 $handle_parent = $handle.parent(), 5389 $hidden_inputs = $handle.parent().children('input[type=hidden]'); 5390 5391 if (Foundation.rtl && !settings.vertical) { 5392 handle_offset = -handle_offset; 5393 } 5394 5395 handle_offset = settings.vertical ? -handle_offset + bar_l - handle_l + 1 : handle_offset; 5396 this.set_translate($handle, handle_offset, settings.vertical); 5397 5398 if (settings.vertical) { 5399 $handle.siblings('.range-slider-active-segment').css('height', progress_bar_length + '%'); 5400 } else { 5401 $handle.siblings('.range-slider-active-segment').css('width', progress_bar_length + '%'); 5402 } 5403 5404 $handle_parent.attr(this.attr_name(), value).trigger('change.fndtn.slider'); 5405 5406 $hidden_inputs.val(value); 5407 if (settings.trigger_input_change) { 5408 $hidden_inputs.trigger('change.fndtn.slider'); 5409 } 5410 5411 if (!$handle[0].hasAttribute('aria-valuemin')) { 5412 $handle.attr({ 5413 'aria-valuemin' : settings.start, 5414 'aria-valuemax' : settings.end 5415 }); 5416 } 5417 $handle.attr('aria-valuenow', value); 5418 5419 if (settings.display_selector != '') { 5420 $(settings.display_selector).each(function () { 5421 if (this.hasAttribute('value')) { 5422 $(this).val(value); 5423 } else { 5424 $(this).text(value); 5425 } 5426 }); 5427 } 5428 5429 }, 5430 5431 normalized_percentage : function (val, start, end) { 5432 return Math.min(1, (val - start) / (end - start)); 5433 }, 5434 5435 normalized_value : function (val, start, end, step, precision) { 5436 var range = end - start, 5437 point = val * range, 5438 mod = (point - (point % step)) / step, 5439 rem = point % step, 5440 round = ( rem >= step * 0.5 ? step : 0); 5441 return ((mod * step + round) + start).toFixed(precision); 5442 }, 5443 5444 set_translate : function (ele, offset, vertical) { 5445 if (vertical) { 5446 $(ele) 5447 .css('-webkit-transform', 'translateY(' + offset + 'px)') 5448 .css('-moz-transform', 'translateY(' + offset + 'px)') 5449 .css('-ms-transform', 'translateY(' + offset + 'px)') 5450 .css('-o-transform', 'translateY(' + offset + 'px)') 5451 .css('transform', 'translateY(' + offset + 'px)'); 5452 } else { 5453 $(ele) 5454 .css('-webkit-transform', 'translateX(' + offset + 'px)') 5455 .css('-moz-transform', 'translateX(' + offset + 'px)') 5456 .css('-ms-transform', 'translateX(' + offset + 'px)') 5457 .css('-o-transform', 'translateX(' + offset + 'px)') 5458 .css('transform', 'translateX(' + offset + 'px)'); 5459 } 5460 }, 5461 5462 limit_to : function (val, min, max) { 5463 return Math.min(Math.max(val, min), max); 5464 }, 5465 5466 initialize_settings : function (handle) { 5467 var settings = $.extend({}, this.settings, this.data_options($(handle).parent())), 5468 decimal_places_match_result; 5469 5470 if (settings.precision === null) { 5471 decimal_places_match_result = ('' + settings.step).match(/\.([\d]*)/); 5472 settings.precision = decimal_places_match_result && decimal_places_match_result[1] ? decimal_places_match_result[1].length : 0; 5473 } 5474 5475 if (settings.vertical) { 5476 $.data(handle, 'bar_o', $(handle).parent().offset().top); 5477 $.data(handle, 'bar_l', $(handle).parent().outerHeight()); 5478 $.data(handle, 'handle_o', $(handle).offset().top); 5479 $.data(handle, 'handle_l', $(handle).outerHeight()); 5480 } else { 5481 $.data(handle, 'bar_o', $(handle).parent().offset().left); 5482 $.data(handle, 'bar_l', $(handle).parent().outerWidth()); 5483 $.data(handle, 'handle_o', $(handle).offset().left); 5484 $.data(handle, 'handle_l', $(handle).outerWidth()); 5485 } 5486 5487 $.data(handle, 'bar', $(handle).parent()); 5488 return $.data(handle, 'settings', settings); 5489 }, 5490 5491 set_initial_position : function ($ele) { 5492 var settings = $.data($ele.children('.range-slider-handle')[0], 'settings'), 5493 initial = ((typeof settings.initial == 'number' && !isNaN(settings.initial)) ? settings.initial : Math.floor((settings.end - settings.start) * 0.5 / settings.step) * settings.step + settings.start), 5494 $handle = $ele.children('.range-slider-handle'); 5495 this.set_ui($handle, initial); 5496 }, 5497 5498 set_value : function (value) { 5499 var self = this; 5500 $('[' + self.attr_name() + ']', this.scope).each(function () { 5501 $(this).attr(self.attr_name(), value); 5502 }); 5503 if (!!$(this.scope).attr(self.attr_name())) { 5504 $(this.scope).attr(self.attr_name(), value); 5505 } 5506 self.reflow(); 5507 }, 5508 5509 reflow : function () { 5510 var self = this; 5511 self.S('[' + this.attr_name() + ']').each(function () { 5512 var handle = $(this).children('.range-slider-handle')[0], 5513 val = $(this).attr(self.attr_name()); 5514 self.initialize_settings(handle); 5515 5516 if (val) { 5517 self.set_ui($(handle), parseFloat(val)); 5518 } else { 5519 self.set_initial_position($(this)); 5520 } 5521 }); 5522 } 5523 }; 5524 5525}(jQuery, window, window.document)); 5526 5527;(function ($, window, document, undefined) { 5528 'use strict'; 5529 5530 Foundation.libs.tab = { 5531 name : 'tab', 5532 5533 version : '5.5.3', 5534 5535 settings : { 5536 active_class : 'active', 5537 callback : function () {}, 5538 deep_linking : false, 5539 scroll_to_content : true, 5540 is_hover : false 5541 }, 5542 5543 default_tab_hashes : [], 5544 5545 init : function (scope, method, options) { 5546 var self = this, 5547 S = this.S; 5548 5549 // Store the default active tabs which will be referenced when the 5550 // location hash is absent, as in the case of navigating the tabs and 5551 // returning to the first viewing via the browser Back button. 5552 S('[' + this.attr_name() + '] > .active > a', this.scope).each(function () { 5553 self.default_tab_hashes.push(this.hash); 5554 }); 5555 5556 this.bindings(method, options); 5557 this.handle_location_hash_change(); 5558 }, 5559 5560 events : function () { 5561 var self = this, 5562 S = this.S; 5563 5564 var usual_tab_behavior = function (e, target) { 5565 var settings = S(target).closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init'); 5566 if (!settings.is_hover || Modernizr.touch) { 5567 // if user did not pressed tab key, prevent default action 5568 var keyCode = e.keyCode || e.which; 5569 if (keyCode !== 9) { 5570 e.preventDefault(); 5571 e.stopPropagation(); 5572 } 5573 self.toggle_active_tab(S(target).parent()); 5574 5575 } 5576 }; 5577 5578 S(this.scope) 5579 .off('.tab') 5580 // Key event: focus/tab key 5581 .on('keydown.fndtn.tab', '[' + this.attr_name() + '] > * > a', function(e) { 5582 var keyCode = e.keyCode || e.which; 5583 // if user pressed tab key 5584 if (keyCode === 13 || keyCode === 32) { // enter or space 5585 var el = this; 5586 usual_tab_behavior(e, el); 5587 } 5588 }) 5589 // Click event: tab title 5590 .on('click.fndtn.tab', '[' + this.attr_name() + '] > * > a', function(e) { 5591 var el = this; 5592 usual_tab_behavior(e, el); 5593 }) 5594 // Hover event: tab title 5595 .on('mouseenter.fndtn.tab', '[' + this.attr_name() + '] > * > a', function (e) { 5596 var settings = S(this).closest('[' + self.attr_name() + ']').data(self.attr_name(true) + '-init'); 5597 if (settings.is_hover) { 5598 self.toggle_active_tab(S(this).parent()); 5599 } 5600 }); 5601 5602 // Location hash change event 5603 S(window).on('hashchange.fndtn.tab', function (e) { 5604 e.preventDefault(); 5605 self.handle_location_hash_change(); 5606 }); 5607 }, 5608 5609 handle_location_hash_change : function () { 5610 5611 var self = this, 5612 S = this.S; 5613 5614 S('[' + this.attr_name() + ']', this.scope).each(function () { 5615 var settings = S(this).data(self.attr_name(true) + '-init'); 5616 if (settings.deep_linking) { 5617 // Match the location hash to a label 5618 var hash; 5619 if (settings.scroll_to_content) { 5620 hash = self.scope.location.hash; 5621 } else { 5622 // prefix the hash to prevent anchor scrolling 5623 hash = self.scope.location.hash.replace('fndtn-', ''); 5624 } 5625 if (hash != '') { 5626 // Check whether the location hash references a tab content div or 5627 // another element on the page (inside or outside the tab content div) 5628 var hash_element = S(hash); 5629 if (hash_element.hasClass('content') && hash_element.parent().hasClass('tabs-content')) { 5630 // Tab content div 5631 self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=' + hash + ']').parent()); 5632 } else { 5633 // Not the tab content div. If inside the tab content, find the 5634 // containing tab and toggle it as active. 5635 var hash_tab_container_id = hash_element.closest('.content').attr('id'); 5636 if (hash_tab_container_id != undefined) { 5637 self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=#' + hash_tab_container_id + ']').parent(), hash); 5638 } 5639 } 5640 } else { 5641 // Reference the default tab hashes which were initialized in the init function 5642 for (var ind = 0; ind < self.default_tab_hashes.length; ind++) { 5643 self.toggle_active_tab($('[' + self.attr_name() + '] > * > a[href=' + self.default_tab_hashes[ind] + ']').parent()); 5644 } 5645 } 5646 } 5647 }); 5648 }, 5649 5650 toggle_active_tab : function (tab, location_hash) { 5651 var self = this, 5652 S = self.S, 5653 tabs = tab.closest('[' + this.attr_name() + ']'), 5654 tab_link = tab.find('a'), 5655 anchor = tab.children('a').first(), 5656 target_hash = '#' + anchor.attr('href').split('#')[1], 5657 target = S(target_hash), 5658 siblings = tab.siblings(), 5659 settings = tabs.data(this.attr_name(true) + '-init'), 5660 interpret_keyup_action = function (e) { 5661 // Light modification of Heydon Pickering's Practical ARIA Examples: http://heydonworks.com/practical_aria_examples/js/a11y.js 5662 5663 // define current, previous and next (possible) tabs 5664 5665 var $original = $(this); 5666 var $prev = $(this).parents('li').prev().children('[role="tab"]'); 5667 var $next = $(this).parents('li').next().children('[role="tab"]'); 5668 var $target; 5669 5670 // find the direction (prev or next) 5671 5672 switch (e.keyCode) { 5673 case 37: 5674 $target = $prev; 5675 break; 5676 case 39: 5677 $target = $next; 5678 break; 5679 default: 5680 $target = false 5681 break; 5682 } 5683 5684 if ($target.length) { 5685 $original.attr({ 5686 'tabindex' : '-1', 5687 'aria-selected' : null 5688 }); 5689 $target.attr({ 5690 'tabindex' : '0', 5691 'aria-selected' : true 5692 }).focus(); 5693 } 5694 5695 // Hide panels 5696 5697 $('[role="tabpanel"]') 5698 .attr('aria-hidden', 'true'); 5699 5700 // Show panel which corresponds to target 5701 5702 $('#' + $(document.activeElement).attr('href').substring(1)) 5703 .attr('aria-hidden', null); 5704 5705 }, 5706 go_to_hash = function(hash) { 5707 // This function allows correct behaviour of the browser's back button when deep linking is enabled. Without it 5708 // the user would get continually redirected to the default hash. 5709 var default_hash = settings.scroll_to_content ? self.default_tab_hashes[0] : 'fndtn-' + self.default_tab_hashes[0].replace('#', ''); 5710 5711 if (hash !== default_hash || window.location.hash) { 5712 window.location.hash = hash; 5713 } 5714 }; 5715 5716 // allow usage of data-tab-content attribute instead of href 5717 if (anchor.data('tab-content')) { 5718 target_hash = '#' + anchor.data('tab-content').split('#')[1]; 5719 target = S(target_hash); 5720 } 5721 5722 if (settings.deep_linking) { 5723 5724 if (settings.scroll_to_content) { 5725 5726 // retain current hash to scroll to content 5727 go_to_hash(location_hash || target_hash); 5728 5729 if (location_hash == undefined || location_hash == target_hash) { 5730 tab.parent()[0].scrollIntoView(); 5731 } else { 5732 S(target_hash)[0].scrollIntoView(); 5733 } 5734 } else { 5735 // prefix the hashes so that the browser doesn't scroll down 5736 if (location_hash != undefined) { 5737 go_to_hash('fndtn-' + location_hash.replace('#', '')); 5738 } else { 5739 go_to_hash('fndtn-' + target_hash.replace('#', '')); 5740 } 5741 } 5742 } 5743 5744 // WARNING: The activation and deactivation of the tab content must 5745 // occur after the deep linking in order to properly refresh the browser 5746 // window (notably in Chrome). 5747 // Clean up multiple attr instances to done once 5748 tab.addClass(settings.active_class).triggerHandler('opened'); 5749 tab_link.attr({'aria-selected' : 'true', tabindex : 0}); 5750 siblings.removeClass(settings.active_class) 5751 siblings.find('a').attr({'aria-selected' : 'false'/*, tabindex : -1*/}); 5752 target.siblings().removeClass(settings.active_class).attr({'aria-hidden' : 'true'/*, tabindex : -1*/}); 5753 target.addClass(settings.active_class).attr('aria-hidden', 'false').removeAttr('tabindex'); 5754 settings.callback(tab); 5755 target.triggerHandler('toggled', [target]); 5756 tabs.triggerHandler('toggled', [tab]); 5757 5758 tab_link.off('keydown').on('keydown', interpret_keyup_action ); 5759 }, 5760 5761 data_attr : function (str) { 5762 if (this.namespace.length > 0) { 5763 return this.namespace + '-' + str; 5764 } 5765 5766 return str; 5767 }, 5768 5769 off : function () {}, 5770 5771 reflow : function () {} 5772 }; 5773}(jQuery, window, window.document)); 5774 5775;(function ($, window, document, undefined) { 5776 'use strict'; 5777 5778 Foundation.libs.tooltip = { 5779 name : 'tooltip', 5780 5781 version : '5.5.3', 5782 5783 settings : { 5784 additional_inheritable_classes : [], 5785 tooltip_class : '.tooltip', 5786 append_to : 'body', 5787 touch_close_text : 'Tap To Close', 5788 disable_for_touch : false, 5789 hover_delay : 200, 5790 fade_in_duration : 150, 5791 fade_out_duration : 150, 5792 show_on : 'all', 5793 tip_template : function (selector, content) { 5794 return '<span data-selector="' + selector + '" id="' + selector + '" class="' 5795 + Foundation.libs.tooltip.settings.tooltip_class.substring(1) 5796 + '" role="tooltip">' + content + '<span class="nub"></span></span>'; 5797 } 5798 }, 5799 5800 cache : {}, 5801 5802 init : function (scope, method, options) { 5803 Foundation.inherit(this, 'random_str'); 5804 this.bindings(method, options); 5805 }, 5806 5807 should_show : function (target, tip) { 5808 var settings = $.extend({}, this.settings, this.data_options(target)); 5809 5810 if (settings.show_on === 'all') { 5811 return true; 5812 }
5812 else if (this.small() && settings.show_on === 'small') { 5813 return true; 5814 } else if (this.medium() && settings.show_on === 'medium') { 5815 return true; 5816 } else if (this.large() && settings.show_on === 'large') { 5817 return true; 5818 } 5819 return false; 5820 }, 5821 5822 medium : function () { 5823 return matchMedia(Foundation.media_queries['medium']).matches; 5824 }, 5825 5826 large : function () { 5827 return matchMedia(Foundation.media_queries['large']).matches; 5828 }, 5829 5830 events : function (instance) { 5831 var self = this, 5832 S = self.S; 5833 5834 self.create(this.S(instance)); 5835 5836 function _startShow(elt, $this, immediate) { 5837 if (elt.timer) { 5838 return; 5839 } 5840 5841 if (immediate) { 5842 elt.timer = null; 5843 self.showTip($this); 5844 } else { 5845 elt.timer = setTimeout(function () { 5846 elt.timer = null; 5847 self.showTip($this); 5848 }.bind(elt), self.settings.hover_delay); 5849 } 5850 } 5851 5852 function _startHide(elt, $this) { 5853 if (elt.timer) { 5854 clearTimeout(elt.timer); 5855 elt.timer = null; 5856 } 5857 5858 self.hide($this); 5859 } 5860 5861 $(this.scope) 5862 .off('.tooltip') 5863 .on('mouseenter.fndtn.tooltip mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', 5864 '[' + this.attr_name() + ']', function (e) { 5865 var $this = S(this), 5866 settings = $.extend({}, self.settings, self.data_options($this)), 5867 is_touch = false; 5868 5869 if (Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type) && S(e.target).is('a')) { 5870 return false; 5871 } 5872 5873 if (/mouse/i.test(e.type) && self.ie_touch(e)) { 5874 return false; 5875 } 5876 5877 if ($this.hasClass('open')) { 5878 if (Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) { 5879 e.preventDefault(); 5880 } 5881 self.hide($this); 5882 } else { 5883 if (settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) { 5884 return; 5885 } else if (!settings.disable_for_touch && Modernizr.touch && /touchstart|MSPointerDown/i.test(e.type)) { 5886 e.preventDefault(); 5887 S(settings.tooltip_class + '.open').hide(); 5888 is_touch = true; 5889 // close other open tooltips on touch 5890 if ($('.open[' + self.attr_name() + ']').length > 0) { 5891 var prevOpen = S($('.open[' + self.attr_name() + ']')[0]); 5892 self.hide(prevOpen); 5893 } 5894 } 5895 5896 if (/enter|over/i.test(e.type)) { 5897 _startShow(this, $this); 5898 5899 } else if (e.type === 'mouseout' || e.type === 'mouseleave') { 5900 _startHide(this, $this); 5901 } else { 5902 _startShow(this, $this, true); 5903 } 5904 } 5905 }) 5906 .on('mouseleave.fndtn.tooltip touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', '[' + this.attr_name() + '].open', function (e) { 5907 if (/mouse/i.test(e.type) && self.ie_touch(e)) { 5908 return false; 5909 } 5910 5911 if ($(this).data('tooltip-open-event-type') == 'touch' && e.type == 'mouseleave') { 5912 return; 5913 } else if ($(this).data('tooltip-open-event-type') == 'mouse' && /MSPointerDown|touchstart/i.test(e.type)) { 5914 self.convert_to_touch($(this)); 5915 } else { 5916 _startHide(this, $(this)); 5917 } 5918 }) 5919 .on('DOMNodeRemoved DOMAttrModified', '[' + this.attr_name() + ']:not(a)', function (e) { 5920 _startHide(this, S(this)); 5921 }); 5922 }, 5923 5924 ie_touch : function (e) { 5925 // How do I distinguish between IE11 and Windows Phone 8????? 5926 return false; 5927 }, 5928 5929 showTip : function ($target) { 5930 var $tip = this.getTip($target); 5931 if (this.should_show($target, $tip)) { 5932 return this.show($target); 5933 } 5934 return; 5935 }, 5936 5937 getTip : function ($target) { 5938 var selector = this.selector($target), 5939 settings = $.extend({}, this.settings, this.data_options($target)), 5940 tip = null; 5941 5942 if (selector) { 5943 tip = this.S('span[data-selector="' + selector + '"]' + settings.tooltip_class); 5944 } 5945 5946 return (typeof tip === 'object') ? tip : false;
5947 }, 5948 5949 selector : function ($target) { 5950 var dataSelector = $target.attr(this.attr_name()) || $target.attr('data-selector'); 5951 5952 if (typeof dataSelector != 'string') { 5953 dataSelector = this.random_str(6); 5954 $target 5955 .attr('data-selector', dataSelector) 5956 .attr('aria-describedby', dataSelector); 5957 } 5958 5959 return dataSelector; 5960 }, 5961 5962 create : function ($target) { 5963 var self = this, 5964 settings = $.extend({}, this.settings, this.data_options($target)), 5965 tip_template = this.settings.tip_template; 5966 5967 if (typeof settings.tip_template === 'string' && window.hasOwnProperty(settings.tip_template)) { 5968 tip_template = window[settings.tip_template]; 5969 } 5970 5971 var $tip = $(tip_template(this.selector($target), $('<div></div>').html($target.attr('title')).html())), 5972 classes = this.inheritable_classes($target); 5973 5974 $tip.addClass(classes).appendTo(settings.append_to); 5975 5976 if (Modernizr.touch) { 5977 $tip.append('<span class="tap-to-close">' + settings.touch_close_text + '</span>'); 5978 $tip.on('touchstart.fndtn.tooltip MSPointerDown.fndtn.tooltip', function (e) { 5979 self.hide($target); 5980 }); 5981 } 5982 5983 $target.removeAttr('title').attr('title', ''); 5984 }, 5985 5986 reposition : function (target, tip, classes) { 5987 var width, nub, nubHeight, nubWidth, objPos; 5988 5989 tip.css('visibility', 'hidden').show(); 5990 5991 width = target.data('width'); 5992 nub = tip.children('.nub'); 5993 nubHeight = nub.outerHeight(); 5994 nubWidth = nub.outerWidth(); 5995 5996 if (this.small()) { 5997 tip.css({'width' : '100%'}); 5998 } else { 5999 tip.css({'width' : (width) ? width : 'auto'}); 6000 } 6001 6002 objPos = function (obj, top, right, bottom, left, width) { 6003 return obj.css({ 6004 'top' : (top) ? top : 'auto', 6005 'bottom' : (bottom) ? bottom : 'auto', 6006 'left' : (left) ? left : 'auto', 6007 'right' : (right) ? right : 'auto' 6008 }).end(); 6009 }; 6010 6011 var o_top = target.offset().top; 6012 var o_left = target.offset().left; 6013 var outerHeight = target.outerHeight(); 6014 6015 objPos(tip, (o_top + outerHeight + 10), 'auto', 'auto', o_left); 6016 6017 if (this.small()) { 6018 objPos(tip, (o_top + outerHeight + 10), 'auto', 'auto', 12.5, $(this.scope).width()); 6019 tip.addClass('tip-override'); 6020 objPos(nub, -nubHeight, 'auto', 'auto', o_left); 6021 } else { 6022 6023 if (Foundation.rtl) { 6024 nub.addClass('rtl'); 6025 o_left = o_left + target.outerWidth() - tip.outerWidth(); 6026 } 6027 6028 objPos(tip, (o_top + outerHeight + 10), 'auto', 'auto', o_left); 6029 // reset nub from small styles, if they've been applied 6030 if (nub.attr('style')) { 6031 nub.removeAttr('style'); 6032 } 6033 6034 tip.removeClass('tip-override'); 6035 6036 var tip_outerHeight = tip.outerHeight(); 6037 6038 if (classes && classes.indexOf('tip-top') > -1) { 6039 if (Foundation.rtl) { 6040 nub.addClass('rtl'); 6041 } 6042 objPos(tip, (o_top - tip_outerHeight), 'auto', 'auto', o_left) 6043 .removeClass('tip-override'); 6044 } else if (classes && classes.indexOf('tip-left') > -1) { 6045 objPos(tip, (o_top + (outerHeight / 2) - (tip_outerHeight / 2)), 'auto', 'auto', (o_left - tip.outerWidth() - nubHeight)) 6046 .removeClass('tip-override'); 6047 nub.removeClass('rtl'); 6048 } else if (classes && classes.indexOf('tip-right') > -1) { 6049 objPos(tip, (o_top + (outerHeight / 2) - (tip_outerHeight / 2)), 'auto', 'auto', (o_left + target.outerWidth() + nubHeight)) 6050 .removeClass('tip-override'); 6051 nub.removeClass('rtl'); 6052 } 6053 } 6054 6055 tip.css('visibility', 'visible').hide(); 6056 }, 6057 6058 small : function () { 6059 return matchMedia(Foundation.media_queries.small).matches && 6060 !matchMedia(Foundation.media_queries.medium).matches; 6061 }, 6062 6063 inheritable_classes : function ($target) { 6064 var settings = $.extend({}, this.settings, this.data_options($target)), 6065 inheritables = ['tip-top', 'tip-left', 'tip-bottom', 'tip-right', 'radius', 'round'].concat(settings.additional_inheritable_classes), 6066 classes = $target.attr('class'), 6067 filtered = classes ? $.map(classes.split(' '), function (el, i) { 6068 if ($.inArray(el, inheritables) !== -1) { 6069 return el; 6070 } 6071 }).join(' ') : ''; 6072 6073 return $.trim(filtered); 6074 }, 6075 6076 convert_to_touch : function ($target) { 6077 var self = this, 6078 $tip = self.getTip($target), 6079 settings = $.extend({}, self.settings, self.data_options($target)); 6080 6081 if ($tip.find('.tap-to-close').length === 0) { 6082 $tip.append('<span class="tap-to-close">' + settings.touch_close_text + '</span>'); 6083 $tip.on('click.fndtn.tooltip.tapclose touchstart.fndtn.tooltip.tapclose MSPointerDown.fndtn.tooltip.tapclose', function (e) { 6084 self.hide($target); 6085 }); 6086 } 6087 6088 $target.data('tooltip-open-event-type', 'touch'); 6089 }, 6090 6091 show : function ($target) { 6092 var $tip = this.getTip($target); 6093 if ($target.data('tooltip-open-event-type') == 'touch') { 6094 this.convert_to_touch($target); 6095 } 6096 6097 this.reposition($target, $tip, $target.attr('class')); 6098 $target.addClass('open'); 6099 $tip.fadeIn(this.settings.fade_in_duration); 6100 }, 6101 6102 hide : function ($target) { 6103 var $tip = this.getTip($target); 6104 6105 $tip.fadeOut(this.settings.fade_out_duration, function () { 6106 $tip.find('.tap-to-close').remove(); 6107 $tip.off('click.fndtn.tooltip.tapclose MSPointerDown.fndtn.tapclose'); 6108 $target.removeClass('open'); 6109 }); 6110 }, 6111 6112 off : function () { 6113 var self = this; 6114 this.S(this.scope).off('.fndtn.tooltip'); 6115 this.S(this.settings.tooltip_class).each(function (i) { 6116 $('[' + self.attr_name() + ']').eq(i).attr('title', $(this).text()); 6117 }).remove(); 6118 }, 6119 6120 reflow : function () {} 6121 }; 6122}(jQuery, window, window.document)); 6123 6124;(function ($, window, document, undefined) { 6125 'use strict'; 6126 6127 Foundation.libs.topbar = { 6128 name : 'topbar', 6129 6130 version : '5.5.3', 6131 6132 settings : { 6133 index : 0, 6134 start_offset : 0, 6135 sticky_class : 'sticky', 6136 custom_back_text : true, 6137 back_text : 'Back', 6138 mobile_show_parent_link : true, 6139 is_hover : true, 6140 scrolltop : true, // jump to top when sticky nav menu toggle is clicked 6141 sticky_on : 'all', 6142 dropdown_autoclose: true 6143 }, 6144 6145 init : function (section, method, options) { 6146 Foundation.inherit(this, 'add_custom_rule register_media throttle'); 6147 var self = this; 6148 6149 self.register_media('topbar', 'foundation-mq-topbar'); 6150 6151 this.bindings(method, options); 6152 6153 self.S('[' + this.attr_name() + ']', this.scope).each(function () { 6154 var topbar = $(this), 6155 settings = topbar.data(self.attr_name(true) + '-init'),
6156 section = self.S('section, .top-bar-section', this); 6157 topbar.data('index', 0); 6158 var topbarContainer = topbar.parent(); 6159 if (topbarContainer.hasClass('fixed') || self.is_sticky(topbar, topbarContainer, settings) ) { 6160 self.settings.sticky_class = settings.sticky_class; 6161 self.settings.sticky_topbar = topbar; 6162 topbar.data('height', topbarContainer.outerHeight()); 6163 topbar.data('stickyoffset', topbarContainer.offset().top); 6164 } else { 6165 topbar.data('height', topbar.outerHeight()); 6166 } 6167 6168 if (!settings.assembled) { 6169 self.assemble(topbar); 6170 } 6171 6172 if (settings.is_hover) { 6173 self.S('.has-dropdown', topbar).addClass('not-click'); 6174 } else { 6175 self.S('.has-dropdown', topbar).removeClass('not-click'); 6176 } 6177 6178 // Pad body when sticky (scrolled) or fixed. 6179 self.add_custom_rule('.f-topbar-fixed { padding-top: ' + topbar.data('height') + 'px }'); 6180 6181 if (topbarContainer.hasClass('fixed')) { 6182 self.S('body').addClass('f-topbar-fixed'); 6183 } 6184 }); 6185 6186 }, 6187 6188 is_sticky : function (topbar, topbarContainer, settings) { 6189 var sticky = topbarContainer.hasClass(settings.sticky_class); 6190 var smallMatch = matchMedia(Foundation.media_queries.small).matches; 6191 var medMatch = matchMedia(Foundation.media_queries.medium).matches; 6192 var lrgMatch = matchMedia(Foundation.media_queries.large).matches; 6193 6194 if (sticky && settings.sticky_on === 'all') { 6195 return true; 6196 } 6197 if (sticky && this.small() && settings.sticky_on.indexOf('small') !== -1) { 6198 if (smallMatch && !medMatch && !lrgMatch) { return true; } 6199 } 6200 if (sticky && this.medium() && settings.sticky_on.indexOf('medium') !== -1) { 6201 if (smallMatch && medMatch && !lrgMatch) { return true; } 6202 } 6203 if (sticky && this.large() && settings.sticky_on.indexOf('large') !== -1) { 6204 if (smallMatch && medMatch && lrgMatch) { return true; } 6205 } 6206 6207 return false; 6208 }, 6209 6210 toggle : function (toggleEl) { 6211 var self = this, 6212 topbar; 6213 6214 if (toggleEl) { 6215 topbar = self.S(toggleEl).closest('[' + this.attr_name() + ']'); 6216 } else { 6217 topbar = self.S('[' + this.attr_name() + ']'); 6218 } 6219 6220 var settings = topbar.data(this.attr_name(true) + '-init'); 6221 6222 var section = self.S('section, .top-bar-section', topbar); 6223 6224 if (self.breakpoint()) { 6225 if (!self.rtl) { 6226 section.css({left : '0%'}); 6227 $('>.name', section).css({left : '100%'}); 6228 } else { 6229 section.css({right : '0%'}); 6230 $('>.name', section).css({right : '100%'}); 6231 } 6232 6233 self.S('li.moved', section).removeClass('moved'); 6234 topbar.data('index', 0); 6235 6236 topbar 6237 .toggleClass('expanded') 6238 .css('height', ''); 6239 } 6240 6241 if (settings.scrolltop) { 6242 if (!topbar.hasClass('expanded')) { 6243 if (topbar.hasClass('fixed')) { 6244 topbar.parent().addClass('fixed'); 6245 topbar.removeClass('fixed'); 6246 self.S('body').addClass('f-topbar-fixed'); 6247 } 6248 } else if (topbar.parent().hasClass('fixed')) { 6249 if (settings.scrolltop) { 6250 topbar.parent().removeClass('fixed'); 6251 topbar.addClass('fixed'); 6252 self.S('body').removeClass('f-topbar-fixed'); 6253 6254 window.scrollTo(0, 0); 6255 } else { 6256 topbar.parent().removeClass('expanded'); 6257 } 6258 } 6259 } else { 6260 if (self.is_sticky(topbar, topbar.parent(), settings)) { 6261 topbar.parent().addClass('fixed'); 6262 } 6263 6264 if (topbar.parent().hasClass('fixed')) { 6265 if (!topbar.hasClass('expanded')) { 6266 topbar.removeClass('fixed'); 6267 topbar.parent().removeClass('expanded'); 6268 self.update_sticky_positioning(); 6269 } else { 6270 topbar.addClass('fixed'); 6271 topbar.parent().addClass('expanded'); 6272 self.S('body').addClass('f-topbar-fixed'); 6273 } 6274 } 6275 } 6276 }, 6277 6278 timer : null, 6279 6280 events : function (bar) { 6281 var self = this, 6282 S = this.S; 6283 6284 S(this.scope) 6285 .off('.topbar') 6286 .on('click.fndtn.topbar', '[' + this.attr_name() + '] .toggle-topbar', function (e) { 6287 e.preventDefault(); 6288 self.toggle(this); 6289 }) 6290 .on('click.fndtn.topbar contextmenu.fndtn.topbar', '.top-bar .top-bar-section li a[href^="#"],[' + this.attr_name() + '] .top-bar-section li a[href^="#"]', function (e) { 6291 var li = $(this).closest('li'), 6292 topbar = li.closest('[' + self.attr_name() + ']'), 6293 settings = topbar.data(self.attr_name(true) + '-init'); 6294 6295 if (settings.dropdown_autoclose && settings.is_hover) { 6296 var hoverLi = $(this).closest('.hover'); 6297 hoverLi.removeClass('hover'); 6298 } 6299 if (self.breakpoint() && !li.hasClass('back') && !li.hasClass('has-dropdown')) {
6300 self.toggle(); 6301 } 6302 6303 }) 6304 .on('click.fndtn.topbar', '[' + this.attr_name() + '] li.has-dropdown', function (e) { 6305 var li = S(this), 6306 target = S(e.target), 6307 topbar = li.closest('[' + self.attr_name() + ']'), 6308 settings = topbar.data(self.attr_name(true) + '-init'); 6309 6310 if (target.data('revealId')) { 6311 self.toggle(); 6312 return; 6313 } 6314 6315 if (self.breakpoint()) { 6316 return; 6317 } 6318 6319 if (settings.is_hover && !Modernizr.touch) { 6320 return; 6321 } 6322 6323 e.stopImmediatePropagation(); 6324 6325 if (li.hasClass('hover')) { 6326 li 6327 .removeClass('hover') 6328 .find('li') 6329 .removeClass('hover'); 6330 6331 li.parents('li.hover') 6332 .removeClass('hover'); 6333 } else { 6334 li.addClass('hover'); 6335 6336 $(li).siblings().removeClass('hover'); 6337 6338 if (target[0].nodeName === 'A' && target.parent().hasClass('has-dropdown')) { 6339 e.preventDefault(); 6340 } 6341 } 6342 }) 6343 .on('click.fndtn.topbar', '[' + this.attr_name() + '] .has-dropdown>a', function (e) { 6344 if (self.breakpoint()) { 6345 6346 e.preventDefault(); 6347 6348 var $this = S(this), 6349 topbar = $this.closest('[' + self.attr_name() + ']'), 6350 section = topbar.find('section, .top-bar-section'), 6351 dropdownHeight = $this.next('.dropdown').outerHeight(), 6352 $selectedLi = $this.closest('li'); 6353 6354 topbar.data('index', topbar.data('index') + 1); 6355 $selectedLi.addClass('moved'); 6356 6357 if (!self.rtl) { 6358 section.css({left : -(100 * topbar.data('index')) + '%'}); 6359 section.find('>.name').css({left : 100 * topbar.data('index') + '%'}); 6360 } else { 6361 section.css({right : -(100 * topbar.data('index')) + '%'}); 6362 section.find('>.name').css({right : 100 * topbar.data('index') + '%'}); 6363 } 6364 6365 topbar.css('height', $this.siblings('ul').outerHeight(true) + topbar.data('height')); 6366 } 6367 }); 6368 6369 S(window).off('.topbar').on('resize.fndtn.topbar', self.throttle(function () { 6370 self.resize.call(self); 6371 }, 50)).trigger('resize.fndtn.topbar').load(function () { 6372 // Ensure that the offset is calculated after all of the pages resources have loaded 6373 S(this).trigger('resize.fndtn.topbar'); 6374 }); 6375 6376 S('body').off('.topbar').on('click.fndtn.topbar', function (e) { 6377 var parent = S(e.target).closest('li').closest('li.hover'); 6378 6379 if (parent.length > 0) { 6380 return; 6381 } 6382 6383 S('[' + self.attr_name() + '] li.hover').removeClass('hover'); 6384 }); 6385 6386 // Go up a level on Click 6387 S(this.scope).on('click.fndtn.topbar', '[' + this.attr_name() + '] .has-dropdown .back', function (e) { 6388 e.preventDefault(); 6389 6390 var $this = S(this), 6391 topbar = $this.closest('[' + self.attr_name() + ']'), 6392 section = topbar.find('section, .top-bar-section'), 6393 settings = topbar.data(self.attr_name(true) + '-init'), 6394 $movedLi = $this.closest('li.moved'), 6395 $previousLevelUl = $movedLi.parent(); 6396 6397 topbar.data('index', topbar.data('index') - 1); 6398 6399 if (!self.rtl) { 6400 section.css({left : -(100 * topbar.data('index')) + '%'}); 6401 section.find('>.name').css({left : 100 * topbar.data('index') + '%'}); 6402 } else { 6403 section.css({right : -(100 * topbar.data('index')) + '%'}); 6404 section.find('>.name').css({right : 100 * topbar.data('index') + '%'}); 6405 } 6406 6407 if (topbar.data('index') === 0) { 6408 topbar.css('height', ''); 6409 } else { 6410 topbar.css('height', $previousLevelUl.outerHeight(true) + topbar.data('height')); 6411 } 6412 6413 setTimeout(function () { 6414 $movedLi.removeClass('moved'); 6415 }, 300); 6416 }); 6417 6418 // Show dropdown menus when their items are focused 6419 S(this.scope).find('.dropdown a') 6420 .focus(function () { 6421 $(this).parents('.has-dropdown').addClass('hover'); 6422 }) 6423 .blur(function () { 6424 $(this).parents('.has-dropdown').removeClass('hover'); 6425 }); 6426 }, 6427 6428 resize : function () { 6429 var self = this; 6430 self.S('[' + this.attr_name() + ']').each(function () { 6431 var topbar = self.S(this), 6432 settings = topbar.data(self.attr_name(true) + '-init'); 6433 6434 var stickyContainer = topbar.parent('.' + self.settings.sticky_class); 6435 var stickyOffset; 6436 6437 if (!self.breakpoint()) { 6438 var doToggle = topbar.hasClass('expanded'); 6439 topbar 6440 .css('height', '') 6441 .removeClass('expanded') 6442 .find('li') 6443 .removeClass('hover'); 6444 6445 if (doToggle) { 6446 self.toggle(topbar); 6447 } 6448 } 6449 6450 if (self.is_sticky(topbar, stickyContainer, settings)) { 6451 if (stickyContainer.hasClass('fixed')) {
6452 // Remove the fixed to allow for correct calculation of the offset. 6453 stickyContainer.removeClass('fixed'); 6454 6455 stickyOffset = stickyContainer.offset().top; 6456 if (self.S(document.body).hasClass('f-topbar-fixed')) { 6457 stickyOffset -= topbar.data('height'); 6458 } 6459 6460 topbar.data('stickyoffset', stickyOffset); 6461 stickyContainer.addClass('fixed'); 6462 } else { 6463 stickyOffset = stickyContainer.offset().top; 6464 topbar.data('stickyoffset', stickyOffset); 6465 } 6466 } 6467 6468 }); 6469 }, 6470 6471 breakpoint : function () { 6472 return !matchMedia(Foundation.media_queries['topbar']).matches; 6473 }, 6474 6475 small : function () { 6476 return matchMedia(Foundation.media_queries['small']).matches; 6477 }, 6478 6479 medium : function () { 6480 return matchMedia(Foundation.media_queries['medium']).matches; 6481 }, 6482 6483 large : function () { 6484 return matchMedia(Foundation.media_queries['large']).matches; 6485 }, 6486 6487 assemble : function (topbar) { 6488 var self = this, 6489 settings = topbar.data(this.attr_name(true) + '-init'), 6490 section = self.S('section, .top-bar-section', topbar); 6491 6492 // Pull element out of the DOM for manipulation 6493 section.detach(); 6494 6495 self.S('.has-dropdown>a', section).each(function () { 6496 var $link = self.S(this), 6497 $dropdown = $link.siblings('.dropdown'), 6498 url = $link.attr('href'), 6499 $titleLi; 6500 6501 if (!$dropdown.find('.title.back').length) { 6502 6503 if (settings.mobile_show_parent_link == true && url) { 6504 $titleLi = $('<li class="title back js-generated"><h5><a href="javascript:void(0)"></a></h5></li><li class="parent-link hide-for-medium-up"><a class="parent-link js-generated" href="' + url + '">' + $link.html() +'</a></li>'); 6505 } else { 6506 $titleLi = $('<li class="title back js-generated"><h5><a href="javascript:void(0)"></a></h5>'); 6507 } 6508 6509 // Copy link to subnav 6510 if (settings.custom_back_text == true) { 6511 $('h5>
6511a', $titleLi).html(settings.back_text); 6512 } else { 6513 $('h5>a', $titleLi).html('« ' + $link.html()); 6514 } 6515 $dropdown.prepend($titleLi); 6516 } 6517 }); 6518 6519 // Put element back in the DOM 6520 section.appendTo(topbar); 6521 6522 // check for sticky 6523 this.sticky(); 6524 6525 this.assembled(topbar); 6526 }, 6527 6528 assembled : function (topbar) { 6529 topbar.data(this.attr_name(true), $.extend({}, topbar.data(this.attr_name(true)), {assembled : true})); 6530 }, 6531 6532 height : function (ul) { 6533 var total = 0, 6534 self = this; 6535 6536 $('> li', ul).each(function () { 6537 total += self.S(this).outerHeight(true); 6538 }); 6539 6540 return total; 6541 }, 6542 6543 sticky : function () { 6544 var self = this; 6545 6546 this.S(window).on('scroll', function () { 6547 self.update_sticky_positioning(); 6548 }); 6549 }, 6550 6551 update_sticky_positioning : function () { 6552 var klass = '.' + this.settings.sticky_class, 6553 $window = this.S(window), 6554 self = this; 6555 6556 if (self.settings.sticky_topbar && self.is_sticky(this.settings.sticky_topbar,this.settings.sticky_topbar.parent(), this.settings)) { 6557 var distance = this.settings.sticky_topbar.data('stickyoffset') + this.settings.start_offset; 6558 if (!self.S(klass).hasClass('expanded')) { 6559 if ($window.scrollTop() > (distance)) { 6560 if (!self.S(klass).hasClass('fixed')) { 6561 self.S(klass).addClass('fixed'); 6562 self.S('body').addClass('f-topbar-fixed'); 6563 } 6564 } else if ($window.scrollTop() <= distance) { 6565 if (self.S(klass).hasClass('fixed')) { 6566 self.S(klass).removeClass('fixed'); 6567 self.S('body').removeClass('f-topbar-fixed'); 6568 } 6569 } 6570 } 6571 } 6572 }, 6573 6574 off : function () { 6575 this.S(this.scope).off('.fndtn.topbar'); 6576 this.S(window).off('.fndtn.topbar'); 6577 }, 6578 6579 reflow : function () {} 6580 }; 6581}(jQuery, window, 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.