1/*! 2 * Webflow: Front-end site library 3 * @license MIT 4 * Inline scripts may access the api using an async handler: 5 * var Webflow = Webflow || []; 6 * Webflow.push(readyFunction); 7 */ 8/******/ 9(function(modules) { // webpackBootstrap 10 /******/ // The module cache 11 /******/ 12 var installedModules = {}; 13 14 /******/ // The require function 15 /******/ 16 function __webpack_require__(moduleId) { 17 18 /******/ // Check if module is in cache 19 /******/ 20 if (installedModules[moduleId]) 21 /******/ 22 return installedModules[moduleId].exports; 23 24 /******/ // Create a new module (and put it into the cache) 25 /******/ 26 var module = installedModules[moduleId] = { 27 /******/ 28 exports: {}, 29 /******/ 30 id: moduleId, 31 /******/ 32 loaded: false 33 /******/ 34 }; 35 36 /******/ // Execute the module function 37 /******/ 38 modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 39 40 /******/ // Flag the module as loaded 41 /******/ 42 module.loaded = true; 43 44 /******/ // Return the exports of the module 45 /******/ 46 return module.exports; 47 /******/ 48 } 49 50 51 /******/ // expose the modules object (__webpack_modules__) 52 /******/ 53 __webpack_require__.m = modules; 54 55 /******/ // expose the module cache 56 /******/ 57 __webpack_require__.c = installedModules; 58 59 /******/ // __webpack_public_path__ 60 /******/ 61 __webpack_require__.p = "/"; 62 63 /******/ // Load entry module and return exports 64 /******/ 65 return __webpack_require__(0); 66 /******/ 67}) 68/************************************************************************/ 69/******/ 70([ 71 /* 0 */ 72 /***/ 73 function(module, exports, __webpack_require__) { 74 75 __webpack_require__(5); 76 __webpack_require__(6); 77 __webpack_require__(7); 78 __webpack_require__(8); 79 __webpack_require__(9); 80 __webpack_require__(10); 81 __webpack_require__(11); 82 __webpack_require__(12); 83 __webpack_require__(1); 84 __webpack_require__(13); 85 __webpack_require__(14); 86 __webpack_require__(15); 87 __webpack_require__(16); 88 __webpack_require__(17); 89 __webpack_require__(18); 90 __webpack_require__(19); 91 module.exports = __webpack_require__(20); 92 93 94 /***/ 95 }, 96 /* 1 */ 97 /***/ 98 function(module, exports, __webpack_require__) { 99 100 /* WEBPACK VAR INJECTION */ 101 (function(process) { 102 'use strict'; 103 104 /** 105 * Webflow: Core site library 106 */ 107 108 var Webflow = {}; 109 var modules = {}; 110 var primary = []; 111 var secondary = window.Webflow || []; 112 var $ = window.jQuery; 113 var $win = $(window); 114 var $doc = $(document); 115 var isFunction = $.isFunction; 116 var _ = Webflow._ = __webpack_require__(21); 117 var tram = __webpack_require__(3) && $.tram; 118 var domready = false; 119 var destroyed = false; 120 var Modernizr = window.Modernizr; 121 tram.config.hideBackface = false; 122 tram.config.keepInherited = true; 123 124 /** 125 * Webflow.define - Define a named module 126 * @param {string} name 127 * @param {function} factory 128 * @param {object} options 129 * @return {object} 130 */ 131 Webflow.define = function(name, factory, options) { 132 if (modules[name]) unbindModule(modules[name]); 133 var instance = modules[name] = factory($, _, options) || {}; 134 bindModule(instance); 135 return instance; 136 }; 137 138 /** 139 * Webflow.require - Require a named module 140 * @param {string} name 141 * @return {object} 142 */ 143 Webflow.require = function(name) { 144 return modules[name]; 145 }; 146 147 function bindModule(module) {
148 // If running in Webflow app, subscribe to design/preview events 149 if (Webflow.env()) { 150 isFunction(module.design) && $win.on('__wf_design', module.design); 151 isFunction(module.preview) && $win.on('__wf_preview', module.preview); 152 } 153 // Subscribe to front-end destroy event 154 isFunction(module.destroy) && $win.on('__wf_destroy', module.destroy); 155 // Look for ready method on module 156 if (module.ready && isFunction(module.ready)) { 157 addReady(module); 158 } 159 } 160 161 function addReady(module) { 162 // If domready has already happened, run ready method 163 if (domready) { 164 module.ready(); 165 return; 166 } 167 // Otherwise add ready method to the primary queue (only once) 168 if (_.contains(primary, module.ready)) return; 169 primary.push(module.ready); 170 } 171 172 function unbindModule(module) { 173 // Unsubscribe module from window events 174 isFunction(module.design) && $win.off('__wf_design', module.design); 175 isFunction(module.preview) && $win.off('__wf_preview', module.preview); 176 isFunction(module.destroy) && $win.off('__wf_destroy', module.destroy); 177 // Remove ready method from primary queue 178 if (module.ready && isFunction(module.ready)) { 179 removeReady(module); 180 } 181 } 182 183 function removeReady(module) { 184 primary = _.filter(primary, function(readyFn) { 185 return readyFn !== module.ready; 186 }); 187 } 188 189 /** 190 * Webflow.push - Add a ready handler into secondary queue 191 * @param {function} ready Callback to invoke on domready 192 */ 193 Webflow.push = function(ready) { 194 // If domready has already happened, invoke handler 195 if (domready) { 196 isFunction(ready) && ready(); 197 return; 198 } 199 // Otherwise push into secondary queue 200 secondary.push(ready); 201 }; 202 203 /** 204 * Webflow.env - Get the state of the Webflow app 205 * @param {string} mode [optional] 206 * @return {boolean} 207 */ 208 Webflow.env = function(mode) { 209 var designFlag = window.__wf_design; 210 var inApp = typeof designFlag !== 'undefined'; 211 if (!mode) return inApp; 212 if (mode === 'design') return inApp && designFlag; 213 if (mode === 'preview') return inApp && !designFlag; 214 if (mode === 'slug') return inApp && window.__wf_slug; 215 if (mode === 'editor') return window.WebflowEditor; 216 if (mode === 'test') return process.env.NODE_ENV === 'test' || window.__wf_test; 217 if (mode === 'frame') return window !== window.top; 218 }; 219 220 // Feature detects + browser sniffs ಠ_ಠ221 var userAgent = navigator.userAgent.toLowerCase(); 222 var appVersion = navigator.appVersion.toLowerCase(); 223 var touch = Webflow.env.touch = ('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch; 224 var chrome = Webflow.env.chrome = /chrome/.test(userAgent) && /Google/.test(navigator.vendor) && parseInt(appVersion.match(/chrome\/(\d+)\./)[1], 10); 225 var ios = Webflow.env.ios = Modernizr && Modernizr.ios; 226 Webflow.env.safari = /safari/.test(userAgent) && !chrome && !ios; 227 228 // Maintain current touch target to prevent late clicks on touch devices 229 var touchTarget; 230 // Listen for both events to support touch/mouse hybrid devices 231 touch && $doc.on('touchstart mousedown', function(evt) { 232 touchTarget = evt.target; 233 }); 234 235 /** 236 * Webflow.validClick - validate click target against current touch target 237 * @param {HTMLElement} clickTarget Element being clicked 238 * @return {Boolean} True if click target is valid (always true on non-touch) 239 */ 240 Webflow.validClick = touch ? function(clickTarget) { 241 return clickTarget === touchTarget || $.contains(clickTarget, touchTarget); 242 } : function() { 243 return true; 244 }; 245 246 /** 247 * Webflow.resize, Webflow.scroll - throttled event proxies 248 */ 249 var resizeEvents = 'resize.webflow orientationchange.webflow load.webflow';
250 var scrollEvents = 'scroll.webflow ' + resizeEvents; 251 Webflow.resize = eventProxy($win, resizeEvents); 252 Webflow.scroll = eventProxy($win, scrollEvents); 253 Webflow.redraw = eventProxy(); 254 255 // Create a proxy instance for throttled events 256 function eventProxy(target, types) { 257 258 // Set up throttled method (using custom frame-based _.throttle) 259 var handlers = []; 260 var proxy = {}; 261 proxy.up = _.throttle(function(evt) { 262 _.each(handlers, function(h) { 263 h(evt); 264 }); 265 }); 266 267 // Bind events to target 268 if (target && types) target.on(types, proxy.up); 269 270 /** 271 * Add an event handler 272 * @param {function} handler 273 */ 274 proxy.on = function(handler) { 275 if (typeof handler !== 'function') return; 276 if (_.contains(handlers, handler)) return; 277 handlers.push(handler); 278 }; 279 280 /** 281 * Remove an event handler 282 * @param {function} handler 283 */ 284 proxy.off = function(handler) { 285 // If no arguments supplied, clear all handlers 286 if (!arguments.length) { 287 handlers = []; 288 return; 289 } 290 // Otherwise, remove handler from the list 291 handlers = _.filter(handlers, function(h) { 292 return h !== handler; 293 }); 294 }; 295 296 return proxy; 297 } 298 299 // Webflow.location - Wrap window.location in api 300 Webflow.location = function(url) { 301 window.location = url; 302 }; 303 304 // Webflow.app - Designer-specific methods 305 Webflow.app = Webflow.env() ? {} : null; 306 if (Webflow.app) { 307 308 // Trigger redraw for specific elements 309 var redraw = new Event('__wf_redraw'); 310 Webflow.app.redrawElement = function(i, el) { 311 el.dispatchEvent(redraw); 312 }; 313 314 // Webflow.location - Re-route location change to trigger an event 315 Webflow.location = function(url) { 316 window.dispatchEvent(new CustomEvent('__wf_location', { 317 detail: url 318 })); 319 }; 320 } 321 322 // Webflow.ready - Call primary and secondary handlers 323 Webflow.ready = function() { 324 domready = true; 325 326 // Restore modules after destroy 327 if (destroyed) { 328 restoreModules(); 329 330 // Otherwise run primary ready methods 331 } else { 332 _.each(primary, callReady); 333 } 334 335 // Run secondary ready methods 336 _.each(secondary, callReady); 337 338 // Trigger resize 339 Webflow.resize.up(); 340 }; 341 342 function callReady(readyFn) { 343 isFunction(readyFn) && readyFn(); 344 } 345 346 function restoreModules() { 347 destroyed = false; 348 _.each(modules, bindModule); 349 } 350 351 /** 352 * Webflow.load - Add a window load handler that will run even if load event has already happened 353 * @param {function} handler 354 */ 355 var deferLoad; 356 Webflow.load = function(handler) { 357 deferLoad.then(handler); 358 }; 359 360 function bindLoad() { 361 // Reject any previous deferred (to support destroy) 362 if (deferLoad) { 363 deferLoad.reject(); 364 $win.off('load', deferLoad.resolve); 365 } 366 // Create deferred and bind window load event 367 deferLoad = new $.Deferred(); 368 $win.on('load', deferLoad.resolve); 369 } 370 371 // Webflow.destroy - Trigger a destroy event for all modules 372 Webflow.destroy = function(options) { 373 options = options || {}; 374 destroyed = true; 375 $win.triggerHandler('__wf_destroy'); 376 377 // Allow domready reset for tests 378 if (options.domready != null) { 379 domready = options.domready; 380 } 381 382 // Unbind modules 383 _.each(modules, unbindModule); 384 385 // Clear any proxy event handlers 386 Webflow.resize.off(); 387 Webflow.scroll.off(); 388 Webflow.redraw.off(); 389 390 // Clear any queued ready methods 391 primary = []; 392 secondary = []; 393 394 // If load event has not yet fired, replace the deferred 395 if (deferLoad.state() === 'pending') bindLoad(); 396 }; 397 398 // Listen for domready 399 $(Webflow.ready); 400 401 // Listen for window.onload and resolve deferred 402 bindLoad(); 403 404 // Export commonjs module 405 module.exports = window.Webflow = Webflow; 406 407 /* WEBPACK VAR INJECTION */ 408 }.call(exports, __webpack_require__(4))) 409 410 /***/ 411 }, 412 /* 2 */ 413 /***/
414 function(module, exports) { 415 416 'use strict'; 417 418 /** 419 * Webflow: IX Event triggers for other modules 420 */ 421 422 var $ = window.jQuery; 423 var api = {}; 424 var eventQueue = []; 425 var namespace = '.w-ix'; 426 427 var eventTriggers = { 428 reset: function(i, el) { 429 el.__wf_intro = null; 430 }, 431 intro: function(i, el) { 432 if (el.__wf_intro) return; 433 el.__wf_intro = true; 434 $(el).triggerHandler(api.types.INTRO); 435 }, 436 outro: function(i, el) { 437 if (!el.__wf_intro) return; 438 el.__wf_intro = null; 439 $(el).triggerHandler(api.types.OUTRO); 440 } 441 }; 442 443 api.triggers = {}; 444 445 api.types = { 446 INTRO: 'w-ix-intro' + namespace, 447 OUTRO: 'w-ix-outro' + namespace 448 }; 449 450 // Trigger any events in queue + restore trigger methods 451 api.init = function() { 452 var count = eventQueue.length; 453 for (var i = 0; i < count; i++) { 454 var memo = eventQueue[i]; 455 memo[0](0, memo[1]); 456 } 457 eventQueue = []; 458 $.extend(api.triggers, eventTriggers); 459 }; 460 461 // Replace all triggers with async wrapper to queue events until init 462 api.async = function() { 463 for (var key in eventTriggers) { 464 var func = eventTriggers[key]; 465 if (!eventTriggers.hasOwnProperty(key)) continue; 466 467 // Replace trigger method with async wrapper 468 api.triggers[key] = function(i, el) { 469 eventQueue.push([func, el]); 470 }; 471 } 472 }; 473 474 // Default triggers to async queue 475 api.async(); 476 477 module.exports = api; 478 479 480 /***/ 481 }, 482 /* 3 */ 483 /***/ 484 function(module, exports) { 485 486 /*! 487 * tram.js v0.8.1-global 488 * Cross-browser CSS3 transitions in JavaScript 489 * https://github.com/bkwld/tram 490 * MIT License 491 */ 492 window.tram = function(a) { 493 function b(a, b) { 494 var c = new L.Bare; 495 return c.init(a, b) 496 } 497 498 function c(a) { 499 return a.replace(/[A-Z]/g, function(a) { 500 return "-" + a.toLowerCase() 501 }) 502 } 503 504 function d(a) { 505 var b = parseInt(a.slice(1), 16), 506 c = b >> 16 & 255, 507 d = b >> 8 & 255, 508 e = 255 & b; 509 return [c, d, e] 510 } 511 512 function e(a, b, c) { 513 return "#" + (1 << 24 | a << 16 | b << 8 | c).toString(16).slice(1) 514 } 515 516 function f() {} 517 518 function g(a, b) { 519 _("Type warning: Expected: [" + a + "] Got: [" + typeof b + "] " + b) 520 } 521 522 function h(a, b, c) { 523 _("Units do not match [" + a + "]: " + b + ", " + c) 524 } 525 526 function i(a, b, c) { 527 if (void 0 !== b && (c = b), void 0 === a) return c; 528 var d = c; 529 return Z.test(a) || !$.test(a) ? d = parseInt(a, 10) : $.test(a) && (d = 1e3 * parseFloat(a)), 0 > d && (d = 0), d === d ? d : c 530 } 531 532 function j(a) { 533 for (var b = -1, c = a ? a.length : 0, d = []; ++b < c;) { 534 var e = a[b]; 535 e && d.push(e) 536 } 537 return d 538 } 539 var k = function(a, b, c) { 540 function d(a) { 541 return "object" == typeof a 542 } 543 544 function e(a) { 545 return "function" == typeof a 546 } 547 548 function f() {} 549 550 function g(h, i) { 551 function j() { 552 var a = new k; 553 return e(a.init) && a.init.apply(a, arguments), a 554 } 555 556 function k() {} 557 i === c && (i = h, h = Object), j.Bare = k; 558 var l, m = f[a] = h[a], 559 n = k[a] = j[a] = new f; 560 return n.constructor = j, j.mixin = function(b) { 561 return k[a] = j[a] = g(j, b)[a], j 562 }, j.open = function(a) { 563 if (l = {}, e(a) ? l = a.call(j, n, m, j, h) : d(a) && (l = a), d(l)) 564 for (var c in l) b.call(l, c) && (n[c] = l[c]); 565 return e(n.init) || (n.init = h), j 566 }, j.open(i) 567 } 568 return g 569 }("prototype", {}.hasOwnProperty), 570 l = { 571 ease: ["ease", 572 function(a, b, c, d) { 573 var e = (a /= d) * a, 574 f = e * a; 575 return b + c * (-2.75 * f * e + 11 * e * e + -15.5 * f + 8 * e + .25 * a) 576 } 577 ], 578 "ease-in": ["ease-in", 579 function(a, b, c, d) { 580 var e = (a /= d) * a, 581 f = e * a; 582 return b + c * (-1 * f * e + 3 * e * e + -3 * f + 2 * e) 583 } 584 ], 585 "ease-out": ["ease-out", 586 function(a, b, c, d) { 587 var e = (a /= d) * a, 588 f = e * a; 589 return b + c * (.3 * f * e + -1.6 * e * e + 2.2 * f + -1.8 * e + 1.9 * a) 590 } 591 ], 592 "ease-in-out": ["ease-in-out", 593 function(a, b, c, d) { 594 var e = (a /= d) * a, 595 f = e * a; 596 return b + c * (2 * f * e + -5 * e * e + 2 * f + 2 * e) 597 } 598 ], 599 linear: ["linear", 600 function(a, b, c, d) { 601 return c * a / d + b 602 } 603 ], 604 "ease-in-quad": ["cubic-bezier(0.550, 0.085, 0.680, 0.530)", 605 function(a, b, c, d) { 606 return c * (a /= d) * a + b 607 } 608 ], 609 "ease-out-quad": ["cubic-bezier(0.250, 0.460, 0.450, 0.940)", 610 function(a, b, c, d) { 611 return -c * (a /= d) * (a - 2) + b 612 } 613 ], 614 "ease-in-out-quad": ["cubic-bezier(0.455, 0.030, 0.515, 0.955)", 615 function(a, b, c, d) { 616 return (a /= d / 2) < 1 ? c / 2 * a * a + b : -c / 2 * (--a * (a - 2) - 1) + b 617 } 618 ], 619 "ease-in-cubic": ["cubic-bezier(0.550, 0.055, 0.675, 0.190)", 620 function(a, b, c, d) { 621 return c * (a /= d) * a * a + b 622 } 623 ], 624 "ease-out-cubic": ["cubic-bezier(0.215, 0.610, 0.355, 1)", 625 function(a, b, c, d) { 626 return c * ((a = a / d - 1) * a * a + 1) + b 627 } 628 ], 629 "ease-in-out-cubic": ["cubic-bezier(0.645, 0.045, 0.355, 1)", 630 function(a, b, c, d) { 631 return (a /= d / 2) < 1 ? c / 2 * a * a * a + b : c / 2 * ((a -= 2) * a * a + 2) + b 632 } 633 ], 634 "ease-in-quart": ["cubic-bezier(0.895, 0.030, 0.685, 0.220)", 635 function(a, b, c, d) { 636 return c * (a /= d) * a * a * a + b 637 } 638 ], 639 "ease-out-quart": ["cubic-bezier(0.165, 0.840, 0.440, 1)", 640 function(a, b, c, d) { 641 return -c * ((a = a / d - 1) * a * a * a - 1) + b 642 } 643 ], 644 "ease-in-out-quart": ["cubic-bezier(0.770, 0, 0.175, 1)", 645 function(a, b, c, d) { 646 return (a /= d / 2) < 1 ? c / 2 * a * a * a * a + b : -c / 2 * ((a -= 2) * a * a * a - 2) + b 647 } 648 ], 649 "ease-in-quint": ["cubic-bezier(0.755, 0.050, 0.855, 0.060)", 650 function(a, b, c, d) { 651 return c * (a /= d) * a * a * a * a + b 652 } 653 ], 654 "ease-out-quint": ["cubic-bezier(0.230, 1, 0.320, 1)", 655 function(a, b, c, d) { 656 return c * ((a = a / d - 1) * a * a * a * a + 1) + b 657 } 658 ], 659 "ease-in-out-quint": ["cubic-bezier(0.860, 0, 0.070, 1)", 660 function(a, b, c, d) { 661 return (a /= d / 2) < 1 ? c / 2 * a * a * a * a * a + b : c / 2 * ((a -= 2) * a * a * a * a + 2) + b 662 } 663 ], 664 "ease-in-sine": ["cubic-bezier(0.470, 0, 0.745, 0.715)", 665 function(a, b, c, d) { 666 return -c * Math.cos(a / d * (Math.PI / 2)) + c + b 667 } 668 ], 669 "ease-out-sine": ["cubic-bezier(0.390, 0.575, 0.565, 1)", 670 function(a, b, c, d) { 671 return c * Math.sin(a / d * (Math.PI / 2)) + b 672 } 673 ], 674 "ease-in-out-sine": ["cubic-bezier(0.445, 0.050, 0.550, 0.950)", 675 function(a, b, c, d) { 676 return -c / 2 * (Math.cos(Math.PI * a / d) - 1) + b 677 } 678 ], 679 "ease-in-expo": ["cubic-bezier(0.950, 0.050, 0.795, 0.035)", 680 function(a, b, c, d) { 681 return 0 === a ? b : c * Math.pow(2, 10 * (a / d - 1)) + b 682 } 683 ], 684 "ease-out-expo": ["cubic-bezier(0.190, 1, 0.220, 1)", 685 function(a, b, c, d) { 686 return a === d ? b + c : c * (-Math.pow(2, -10 * a / d) + 1) + b 687 } 688 ], 689 "ease-in-out-expo": ["cubic-bezier(1, 0, 0, 1)", 690 function(a, b, c, d) { 691 return 0 === a ? b : a === d ? b + c : (a /= d / 2) < 1 ? c / 2 * Math.pow(2, 10 * (a - 1)) + b : c / 2 * (-Math.pow(2, -10 * --a) + 2) + b 692 } 693 ], 694 "ease-in-circ": ["cubic-bezier(0.600, 0.040, 0.980, 0.335)", 695 function(a, b, c, d) { 696 return -c * (Math.sqrt(1 - (a /= d) * a) - 1) + b 697 } 698 ], 699 "ease-out-circ": ["cubic-bezier(0.075, 0.820, 0.165, 1)", 700 function(a, b, c, d) { 701 return c * Math.sqrt(1 - (a = a / d - 1) * a) + b 702 } 703 ], 704 "ease-in-out-circ": ["cubic-bezier(0.785, 0.135, 0.150, 0.860)", 705 function(a, b, c, d) { 706 return (a /= d / 2) < 1 ? -c / 2 * (Math.sqrt(1 - a * a) - 1) + b : c / 2 * (Math.sqrt(1 - (a -= 2) * a) + 1) + b 707 } 708 ], 709 "ease-in-back": ["cubic-bezier(0.600, -0.280, 0.735, 0.045)", 710 function(a, b, c, d, e) { 711 return void 0 === e && (e = 1.70158), c * (a /= d) * a * ((e + 1) * a - e) + b 712 } 713 ], 714 "ease-out-back": ["cubic-bezier(0.175, 0.885, 0.320, 1.275)", 715 function(a, b, c, d, e) { 716 return void 0 === e && (e = 1.70158), c * ((a = a / d - 1) * a * ((e + 1) * a + e) + 1) + b 717 } 718 ], 719 "ease-in-out-back": ["cubic-bezier(0.680, -0.550, 0.265, 1.550)", 720 function(a, b, c, d, e) { 721 return void 0 === e && (e = 1.70158), (a /= d / 2) < 1 ? c / 2 * a * a * (((e *= 1.525) + 1) * a - e) + b : c / 2 * ((a -= 2) * a * (((e *= 1.525) + 1) * a + e) + 2) + b 722 } 723 ] 724 }, 725 m = { 726 "ease-in-back": "cubic-bezier(0.600, 0, 0.735, 0.045)", 727 "ease-out-back": "cubic-bezier(0.175, 0.885, 0.320, 1)", 728 "ease-in-out-back": "cubic-bezier(0.680, 0, 0.265, 1)" 729 }, 730 n = document, 731 o = window, 732 p = "bkwld-tram", 733 q = /[\-\.0-9]/g, 734 r = /[A-Z]/, 735 s = "number", 736 t = /^(rgb|#)/, 737 u = /(em|cm|mm|in|pt|pc|px)$/, 738 v = /(em|cm|mm|in|pt|pc|px|%)$/, 739 w = /(deg|rad|turn)$/, 740 x = "unitless", 741 y = /(all|none) 0s ease 0s/, 742 z = /^(width|height)$/, 743 A = " ", 744 B = n.createElement("a"), 745 C = ["Webkit", "Moz", "O", "ms"], 746 D = ["-webkit-", "-moz-", "-o-", "-ms-"], 747 E = function(a) { 748 if (a in B.style) return { 749 dom: a, 750 css: a 751 }; 752 var b, c, d = "", 753 e = a.split("-"); 754 for (b = 0; b < e.length; b++) d += e[b].charAt(0).toUpperCase() + e[b].slice(1); 755 for (b = 0; b < C.length; b++) 756 if (c = C[b] + d, c in B.style) return { 757 dom: c, 758 css: D[b] + a 759 } 760 }, 761 F = b.support = { 762 bind: Function.prototype.bind, 763 transform: E("transform"), 764 transition: E("transition"), 765 backface: E("backface-visibility"), 766 timing: E("transition-timing-function") 767 }; 768 if (F.transition) { 769 var G = F.timing.dom; 770 if (B.style[G] = l["ease-in-back"][0], !B.style[G]) 771 for (var H in m) l[H][0] = m[H] 772 } 773 var I = b.frame = function() { 774 var a = o.requestAnimationFrame || o.webkitRequestAnimationFrame || o.mozRequestAnimationFrame || o.oRequestAnimationFrame || o.msRequestAnimationFrame; 775 return a && F.bind ? a.bind(o) : function(a) { 776 o.setTimeout(a, 16) 777 } 778 }(), 779 J = b.now = function() { 780 var a = o.performance, 781 b = a && (a.now || a.webkitNow || a.msNow || a.mozNow); 782 return b && F.bind ? b.bind(a) : Date.now || function() { 783 return +new Date 784 } 785 }(), 786 K = k(function(b) { 787 function d(a, b) { 788 var c = j(("" + a).split(A)), 789 d = c[0]; 790 b = b || {}; 791 var e = X[d]; 792 if (!e) return _("Unsupported property: " + d); 793 if (!b.weak || !this.props[d]) { 794 var f = e[0], 795 g = this.props[d]; 796 return g || (g = this.props[d] = new f.Bare), g.init(this.$el, c, e, b), g 797 } 798 } 799 800 function e(a, b, c) { 801
801 if (a) { 802 var e = typeof a; 803 if (b || (this.timer && this.timer.destroy(), this.queue = [], this.active = !1), "number" == e && b) return this.timer = new R({ 804 duration: a, 805 context: this, 806 complete: h 807 }), void(this.active = !0); 808 if ("string" == e && b) { 809 switch (a) { 810 case "hide": 811 n.call(this); 812 break; 813 case "stop": 814 k.call(this); 815 break; 816 case "redraw": 817 o.call(this); 818 break; 819 default: 820 d.call(this, a, c && c[1]) 821 } 822 return h.call(this) 823 } 824 if ("function" == e) return void a.call(this, this); 825 if ("object" == e) { 826 var f = 0; 827 t.call(this, a, function(a, b) { 828 a.span > f && (f = a.span), a.stop(), a.animate(b) 829 }, function(a) { 830 "wait" in a && (f = i(a.wait, 0)) 831 }), s.call(this), f > 0 && (this.timer = new R({ 832 duration: f, 833 context: this 834 }), this.active = !0, b && (this.timer.complete = h)); 835 var g = this, 836 j = !1, 837 l = {}; 838 I(function() { 839 t.call(g, a, function(a) { 840 a.active && (j = !0, l[a.name] = a.nextStyle) 841 }), j && g.$el.css(l) 842 }) 843 } 844 } 845 } 846 847 function f(a) { 848 a = i(a, 0), this.active ? this.queue.push({ 849 options: a 850 }) : (this.timer = new R({ 851 duration: a, 852 context: this, 853 complete: h 854 }), this.active = !0) 855 } 856 857 function g(a) { 858 return this.active ? (this.queue.push({ 859 options: a, 860 args: arguments 861 }), void(this.timer.complete = h)) : _("No active transition timer. Use start() or wait() before then().") 862 } 863 864 function h() { 865 if (this.timer && this.timer.destroy(), this.active = !1, this.queue.length) { 866 var a = this.queue.shift(); 867 e.call(this, a.options, !0, a.args) 868 } 869 } 870 871 function k(a) { 872 this.timer && this.timer.destroy(), this.queue = [], this.active = !1; 873 var b; 874 "string" == typeof a ? (b = {}, b[a] = 1) : b = "object" == typeof a && null != a ? a : this.props, t.call(this, b, u), s.call(this) 875 } 876 877 function l(a) { 878 k.call(this, a), t.call(this, a, v, w) 879 } 880 881 function m(a) { 882 "string" != typeof a && (a = "block"), this.el.style.display = a 883 } 884 885 function n() { 886 k.call(this), this.el.style.display = "none" 887 } 888 889 function o() { 890 this.el.offsetHeight 891 } 892 893 function q() { 894 k.call(this), a.removeData(this.el, p), this.$el = this.el = null 895 } 896 897 function s() { 898 var a, b, c = []; 899 this.upstream && c.push(this.upstream); 900 for (a in this.props) b = this.props[a], b.active && c.push(b.string); 901 c = c.join(","), this.style !== c && (this.style = c, this.el.style[F.transition.dom] = c) 902 } 903 904 function t(a, b, e) { 905 var f, g, h, i, j = b !== u, 906 k = {}; 907 for (f in a) h = a[f], f in Y ? (k.transform || (k.transform = {}), k.transform[f] = h) : (r.test(f) && (f = c(f)), f in X ? k[f] = h : (i || (i = {}), i[f] = h)); 908 for (f in k) { 909 if (h = k[f], g = this.props[f], !g) { 910 if (!j) continue; 911 g = d.call(this, f) 912 } 913 b.call(this, g, h) 914 } 915 e && i && e.call(this, i) 916 } 917 918 function u(a) { 919 a.stop() 920 } 921 922 function v(a, b) { 923 a.set(b) 924 } 925 926 function w(a) { 927 this.$el.css(a) 928 } 929
930 function x(a, c) { 931 b[a] = function() { 932 return this.children ? z.call(this, c, arguments) : (this.el && c.apply(this, arguments), this) 933 } 934 } 935 936 function z(a, b) { 937 var c, d = this.children.length; 938 for (c = 0; d > c; c++) a.apply(this.children[c], b); 939 return this 940 } 941 b.init = function(b) { 942 if (this.$el = a(b), this.el = this.$el[0], this.props = {}, this.queue = [], this.style = "", this.active = !1, T.keepInherited && !T.fallback) { 943 var c = V(this.el, "transition"); 944 c && !y.test(c) && (this.upstream = c) 945 } 946 F.backface && T.hideBackface && U(this.el, F.backface.css, "hidden") 947 }, x("add", d), x("start", e), x("wait", f), x("then", g), x("next", h), x("stop", k), x("set", l), x("show", m), x("hide", n), x("redraw", o), x("destroy", q) 948 }), 949 L = k(K, function(b) { 950 function c(b, c) { 951 var d = a.data(b, p) || a.data(b, p, new K.Bare); 952 return d.el || d.init(b), c ? d.start(c) : d 953 } 954 b.init = function(b, d) { 955 var e = a(b); 956 if (!e.length) return this; 957 if (1 === e.length) return c(e[0], d); 958 var f = []; 959 return e.each(function(a, b) { 960 f.push(c(b, d)) 961 }), this.children = f, this 962 } 963 }), 964 M = k(function(a) { 965 function b() { 966 var a = this.get(); 967 this.update("auto"); 968 var b = this.get(); 969 return this.update(a), b 970 } 971 972 function c(a, b, c) { 973 return void 0 !== b && (c = b), a in l ? a : c 974 } 975 976 function d(a) { 977 var b = /rgba?\((\d+),\s*(\d+),\s*(\d+)/.exec(a); 978 return (b ? e(b[1], b[2], b[3]) : a).replace(/#(\w)(\w)(\w)$/, "#$1$1$2$2$3$3") 979 } 980 var f = { 981 duration: 500, 982 ease: "ease", 983 delay: 0 984 }; 985 a.init = function(a, b, d, e) { 986 this.$el = a, this.el = a[0]; 987 var g = b[0]; 988 d[2] && (g = d[2]), W[g] && (g = W[g]), this.name = g, this.type = d[1], this.duration = i(b[1], this.duration, f.duration), this.ease = c(b[2], this.ease, f.ease), this.delay = i(b[3], this.delay, f.delay), this.span = this.duration + this.delay, this.active = !1, this.nextStyle = null, this.auto = z.test(this.name), this.unit = e.unit || this.unit || T.defaultUnit, this.angle = e.angle || this.angle || T.defaultAngle, T.fallback || e.fallback ? this.animate = this.fallback : (this.animate = this.transition, this.string = this.name + A + this.duration + "ms" + ("ease" != this.ease ? A + l[this.ease][0] : "") + (this.delay ? A + this.delay + "ms" : "")) 989 }, a.set = function(a) { 990 a = this.convert(a, this.type), this.update(a), this.redraw() 991 }, a.transition = function(a) { 992 this.active = !0, a = this.convert(a, this.type), this.auto && ("auto" == this.el.style[this.name] && (this.update(this.get()), this.redraw()), "auto" == a && (a = b.call(this))), this.nextStyle = a 993 }, a.fallback = function(a) { 994 var c = this.el.style[this.name] || this.convert(this.get(), this.type); 995 a = this.convert(a, this.type), this.auto && ("auto" == c && (c = this.convert(this.get(), this.type)), "auto" == a && (a = b.call(this))), this.tween = new Q({ 996 from: c, 997 to: a, 998 duration: this.duration, 999 delay: this.delay, 1000 ease: this.ease, 1001 update: this.update, 1002 context: this 1003 }) 1004 }, a.get = function() { 1005 return V(this.el, this.name) 1006 }, a.update = function(a) { 1007 U(this.el, this.name, a) 1008 }, a.stop = function() { 1009 (this.active || this.nextStyle) && (this.active = !1, this.nextStyle = null, U(this.el, this.name, this.get())); 1010 var a = this.tween; 1011 a && a.context && a.destroy() 1012 }, a.convert = function(a, b) { 1013 if ("auto" == a && this.auto) return a; 1014 var c, e = "number" == typeof a, 1015 f = "string" == typeof a; 1016 switch (b) { 1017 case s: 1018 if (e) return a; 1019 if (f && "" === a.replace(q, "")) return +a; 1020 c = "number(unitless)"; 1021 break; 1022 case t: 1023 if (f) { 1024 if ("" === a && this.original) return this.original; 1025 if (b.test(a)) return "#" == a.charAt(0) && 7 == a.length ? a : d(a) 1026 } 1027 c = "hex or rgb string"; 1028 break; 1029 case u: 1030 if (e) return a + this.unit; 1031 if (f && b.test(a)) return a; 1032 c = "number(px) or string(unit)"; 1033 break; 1034 case v: 1035 if (e) return a + this.unit; 1036 if (f && b.test(a)) return a; 1037 c = "number(px) or string(unit or %)"; 1038 break; 1039 case w: 1040 if (e) return a + this.angle; 1041 if (f && b.test(a)) return a; 1042 c = "number(deg) or string(angle)"; 1043 break; 1044 case x: 1045 if (e) return a; 1046 if (f && v.test(a)) return a; 1047 c = "number(unitless) or string(unit or %)" 1048 } 1049 return g(c, a), a 1050 }, a.redraw = function() { 1051 this.el.offsetHeight 1052 } 1053 }), 1054 N = k(M, function(a, b) { 1055 a.init = function() {
1056 b.init.apply(this, arguments), this.original || (this.original = this.convert(this.get(), t)) 1057 } 1058 }), 1059 O = k(M, function(a, b) { 1060 a.init = function() { 1061 b.init.apply(this, arguments), this.animate = this.fallback 1062 }, a.get = function() { 1063 return this.$el[this.name]() 1064 }, a.update = function(a) { 1065 this.$el[this.name](a) 1066 } 1067 }), 1068 P = k(M, function(a, b) { 1069 function c(a, b) { 1070 var c, d, e, f, g; 1071 for (c in a) f = Y[c], e = f[0], d = f[1] || c, g = this.convert(a[c], e), b.call(this, d, g, e) 1072 } 1073 a.init = function() { 1074 b.init.apply(this, arguments), this.current || (this.current = {}, Y.perspective && T.perspective && (this.current.perspective = T.perspective, U(this.el, this.name, this.style(this.current)), this.redraw())) 1075 }, a.set = function(a) { 1076 c.call(this, a, function(a, b) { 1077 this.current[a] = b 1078 }), U(this.el, this.name, this.style(this.current)), this.redraw() 1079 }, a.transition = function(a) { 1080 var b = this.values(a); 1081 this.tween = new S({ 1082 current: this.current, 1083 values: b, 1084 duration: this.duration, 1085 delay: this.delay, 1086 ease: this.ease 1087 }); 1088 var c, d = {}; 1089 for (c in this.current) d[c] = c in b ? b[c] : this.current[c]; 1090 this.active = !0, this.nextStyle = this.style(d) 1091 }, a.fallback = function(a) { 1092 var b = this.values(a); 1093 this.tween = new S({ 1094 current: this.current, 1095 values: b, 1096 duration: this.duration, 1097 delay: this.delay, 1098 ease: this.ease, 1099 update: this.update, 1100 context: this 1101 }) 1102 }, a.update = function() { 1103 U(this.el, this.name, this.style(this.current)) 1104 }, a.style = function(a) { 1105 var b, c = ""; 1106 for (b in a) c += b + "(" + a[b] + ") "; 1107 return c 1108 }, a.values = function(a) { 1109 var b, d = {}; 1110 return c.call(this, a, function(a, c, e) { 1111 d[a] = c, void 0 === this.current[a] && (b = 0, ~a.indexOf("scale") && (b = 1), this.current[a] = this.convert(b, e)) 1112 }), d 1113 } 1114 }), 1115 Q = k(function(b) { 1116 function c(a) { 1117 1 === n.push(a) && I(g) 1118 } 1119 1120 function g() { 1121 var a, b, c, d = n.length; 1122 if (d) 1123 for (I(g), b = J(), a = d; a--;) c = n[a], c && c.render(b) 1124 } 1125 1126 function i(b) { 1127 var c, d = a.inArray(b, n); 1128 d >= 0 && (c = n.slice(d + 1), n.length = d, c.length && (n = n.concat(c))) 1129 } 1130 1131 function j(a) { 1132 return Math.round(a * o) / o 1133 } 1134 1135 function k(a, b, c) { 1136 return e(a[0] + c * (b[0] - a[0]), a[1] + c * (b[1] - a[1]), a[2] + c * (b[2] - a[2])) 1137 } 1138 var m = { 1139 ease: l.ease[1], 1140 from: 0, 1141 to: 1 1142 }; 1143 b.init = function(a) { 1144 this.duration = a.duration || 0, this.delay = a.delay || 0; 1145 var b = a.ease || m.ease; 1146 l[b] && (b = l[b][1]), "function" != typeof b && (b = m.ease), this.ease = b, this.update = a.update || f, this.complete = a.complete || f, this.context = a.context || this, this.name = a.name; 1147 var c = a.from, 1148 d = a.to; 1149 void 0 === c && (c = m.from), void 0 === d && (d = m.to), this.unit = a.unit || "", "number" == typeof c && "number" == typeof d ? (this.begin = c, this.change = d - c) : this.format(d, c), this.value = this.begin + this.unit, this.start = J(), a.autoplay !== !1 && this.play() 1150 }, b.play = function() { 1151 this.active || (this.start || (this.start = J()), this.active = !0, c(this)) 1152 }, b.stop = function() { 1153 this.active && (this.active = !1, i(this)) 1154 }, b.render = function(a) { 1155 var b, c = a - this.start; 1156 if (this.delay) { 1157 if (c <= this.delay) return; 1158 c -= this.delay 1159 } 1160 if (c < this.duration) { 1161 var d = this.ease(c, 0, 1, this.duration); 1162 return b = this.startRGB ? k(this.startRGB, this.endRGB, d) : j(this.begin + d * this.change), this.value = b + this.unit, void this.update.call(this.context, this.value) 1163 } 1164 b = this.endHex || this.begin + this.change, this.value = b + this.unit, this.update.call(this.context, this.value), this.complete.call(this.context), this.destroy() 1165 }, b.format = function(a, b) { 1166 if (b += "", a += "", "#" == a.charAt(0)) return this.startRGB = d(b), this.endRGB = d(a), this.endHex = a, this.begin = 0, void(this.change = 1); 1167 if (!this.unit) { 1168 var c = b.replace(q, ""), 1169 e = a.replace(q, ""); 1170 c !== e && h("tween", b, a), this.unit = c 1171 } 1172 b = parseFloat(b), a = parseFloat(a), this.begin = this.value = b, this.change = a - b 1173 }, b.destroy = function() { 1174 this.stop(), this.context = null, this.ease = this.update = this.complete = f 1175 }; 1176 var n = [], 1177 o = 1e3 1178 }), 1179 R = k(Q, function(a) { 1180 a.init = function(a) { 1181 this.duration = a.duration || 0, this.complete = a.complete || f, this.context = a.context, this.play() 1182 }, a.render = function(a) { 1183 var b = a - this.start; 1184 b < this.duration || (this.complete.call(this.context), this.destroy()) 1185 } 1186 }), 1187 S = k(Q, function(a, b) { 1188 a.init = function(a) { 1189 this.context = a.context, this.update = a.update, this.tweens = [], this.current = a.current; 1190 var b, c; 1191 for (b in a.values) c = a.values[b], this.current[b] !== c && this.tweens.push(new Q({ 1192 name: b, 1193 from: this.current[b], 1194 to: c, 1195 duration: a.duration, 1196 delay: a.delay, 1197 ease: a.ease, 1198 autoplay: !1 1199 })); 1200 this.play() 1201 }, a.render = function(a) { 1202 var b, c, d = this.tweens.length, 1203 e = !1; 1204 for (b = d; b--;) c = this.tweens[b], c.context && (c.render(a), this.current[c.name] = c.value, e = !0); 1205 return e ? void(this.update && this.update.call(this.context)) : this.destroy() 1206 }, a.destroy = function() { 1207 if (b.destroy.call(this), this.tweens) { 1208 var a, c = this.tweens.length; 1209 for (a = c; a--;) this.tweens[a].destroy(); 1210 this.tweens = null, this.current = null 1211 } 1212 } 1213 }), 1214 T = b.config = { 1215 defaultUnit: "px", 1216 defaultAngle: "deg", 1217 keepInherited: !1, 1218 hideBackface: !1, 1219 perspective: "", 1220 fallback: !F.transition, 1221 agentTests: [] 1222 }; 1223 b.fallback = function(a) { 1224 if (!F.transition) return T.fallback = !0; 1225 T.agentTests.push("(" + a + ")"); 1226 var b = new RegExp(T.agentTests.join("|"), "i"); 1227 T.fallback = b.test(navigator.userAgent) 1228 }, b.fallback("6.0.[2-5] Safari"), b.tween = function(a) { 1229 return new Q(a) 1230 }, b.delay = function(a, b, c) { 1231 return new R({ 1232 complete: b, 1233 duration: a, 1234 context: c 1235 }) 1236 }, a.fn.tram = function(a) { 1237 return b.call(null, this, a) 1238 }; 1239 var U = a.style, 1240 V = a.css, 1241 W = { 1242 transform: F.transform && F.transform.css 1243 }, 1244 X = { 1245 color: [N, t], 1246 background: [N, t, "background-color"], 1247 "outline-color": [N, t], 1248 "border-color": [N, t], 1249 "border-top-color": [N, t], 1250 "border-right-color": [N, t], 1251 "border-bottom-color": [N, t], 1252 "border-left-color": [N, t], 1253 "border-width": [M, u], 1254 "border-top-width": [M, u], 1255 "border-right-width": [M, u], 1256 "border-bottom-width": [M, u], 1257 "border-left-width": [M, u], 1258 "border-spacing": [M, u], 1259 "letter-spacing": [M, u], 1260 margin: [M, u], 1261 "margin-top": [M, u], 1262 "margin-right": [M, u], 1263 "margin-bottom": [M, u], 1264 "margin-left": [M, u], 1265 padding: [M, u], 1266 "padding-top": [M, u], 1267 "padding-right": [M, u], 1268 "padding-bottom": [M, u], 1269 "padding-left": [M, u], 1270 "outline-width": [M, u], 1271 opacity: [M, s], 1272 top: [M, v], 1273 right: [M, v], 1274 bottom: [M, v], 1275 left: [M, v], 1276 "font-size": [M, v], 1277 "text-indent": [M, v], 1278 "word-spacing": [M, v], 1279 width: [M, v], 1280 "min-width": [M, v], 1281 "max-width": [M, v], 1282 height: [M, v], 1283 "min-height": [M, v], 1284 "max-height": [M, v], 1285 "line-height": [M, x], 1286 "scroll-top": [O, s, "scrollTop"], 1287 "scroll-left": [O, s, "scrollLeft"] 1288 }, 1289 Y = {}; 1290 F.transform && (X.transform = [P], Y = { 1291 x: [v, "translateX"], 1292 y: [v, "translateY"],
1293 rotate: [w], 1294 rotateX: [w], 1295 rotateY: [w], 1296 scale: [s], 1297 scaleX: [s], 1298 scaleY: [s], 1299 skew: [w], 1300 skewX: [w], 1301 skewY: [w] 1302 }), F.transform && F.backface && (Y.z = [v, "translateZ"], Y.rotateZ = [w], Y.scaleZ = [s], Y.perspective = [u]); 1303 var Z = /ms/, 1304 $ = /s|\./, 1305 _ = function() { 1306 var a = "warn", 1307 b = window.console; 1308 return b && b[a] ? function(c) { 1309 b[a](c) 1310 } : f 1311 }(); 1312 return a.tram = b 1313 }(window.jQuery); 1314 1315 1316 /***/ 1317 }, 1318 /* 4 */ 1319 /***/ 1320 function(module, exports) { 1321 1322 // shim for using process in browser 1323 1324 var process = module.exports = {}; 1325 var queue = []; 1326 var draining = false; 1327 var currentQueue; 1328 var queueIndex = -1; 1329 1330 function cleanUpNextTick() { 1331 if (!draining || !currentQueue) { 1332 return; 1333 } 1334 draining = false; 1335 if (currentQueue.length) { 1336 queue = currentQueue.concat(queue); 1337 } else { 1338 queueIndex = -1; 1339 } 1340 if (queue.length) { 1341 drainQueue(); 1342 } 1343 } 1344 1345 function drainQueue() { 1346 if (draining) { 1347 return; 1348 } 1349 var timeout = setTimeout(cleanUpNextTick); 1350 draining = true; 1351 1352 var len = queue.length; 1353 while (len) { 1354 currentQueue = queue; 1355 queue = []; 1356 while (++queueIndex < len) { 1357 if (currentQueue) { 1358 currentQueue[queueIndex].run(); 1359 } 1360 } 1361 queueIndex = -1; 1362 len = queue.length; 1363 } 1364 currentQueue = null; 1365 draining = false; 1366 clearTimeout(timeout); 1367 } 1368 1369 process.nextTick = function(fun) { 1370 var args = new Array(arguments.length - 1); 1371 if (arguments.length > 1) { 1372 for (var i = 1; i < arguments.length; i++) { 1373 args[i - 1] = arguments[i]; 1374 } 1375 } 1376 queue.push(new Item(fun, args)); 1377 if (queue.length === 1 && !draining) { 1378 setTimeout(drainQueue, 0); 1379 } 1380 }; 1381 1382 // v8 likes predictible objects 1383 function Item(fun, array) { 1384 this.fun = fun; 1385 this.array = array; 1386 } 1387 Item.prototype.run = function() { 1388 this.fun.apply(null, this.array); 1389 }; 1390 process.title = 'browser'; 1391 process.browser = true; 1392 process.env = {}; 1393 process.argv = []; 1394 process.version = ''; // empty string to avoid regexp issues 1395 process.versions = {}; 1396 1397 function noop() {} 1398 1399 process.on = noop; 1400 process.addListener = noop; 1401 process.once = noop; 1402 process.off = noop; 1403 process.removeListener = noop; 1404 process.removeAllListeners = noop; 1405 process.emit = noop; 1406 1407 process.binding = function(name) { 1408 throw new Error('process.binding is not supported'); 1409 }; 1410 1411 process.cwd = function() { 1412 return '/' 1413 }; 1414 process.chdir = function(dir) { 1415 throw new Error('process.chdir is not supported'); 1416 }; 1417 process.umask = function() { 1418 return 0; 1419 }; 1420 1421 1422 /***/ 1423 }, 1424 /* 5 */ 1425 /***/ 1426 function(module, exports, __webpack_require__) { 1427 1428 'use strict'; 1429 1430 /** 1431 * Webflow: Background Video component 1432 */ 1433 1434 var Webflow = __webpack_require__(1); 1435 1436 Webflow.define('backgroundVideo', module.exports = function($, _) { 1437 var namespace = '.w-background-video'; 1438 var doc = $(document); 1439 1440 function ready() { 1441 var backgroundVideoNodes = $(document).find('.w-background-video'); 1442 if (backgroundVideoNodes.length === 0) { 1443 return; 1444 } 1445 1446 backgroundVideoNodes.each(function(_, node) { 1447 $(node).prepend(createVideoNode(node)); 1448 }); 1449 } 1450 1451 function createVideoNode(nativeNode) { 1452 var nodeData = nativeNode.dataset; 1453 1454 if (!nodeData.videoUrls) { 1455 return $('<video />
1455'); 1456 } 1457 1458 // Prevent loading the videos on mobile browsers as its likely that they 1459 // are on low-bandwidth connections. 1460 if (Webflow.isMobile()) { 1461 return $('<video />').css('background-image', 'url(' + nodeData.posterUrl + ')'); 1462 } 1463 1464 var videoURLs = nodeData.videoUrls.split(','); 1465 var sourceNodes = videoURLs.map(function(url) { 1466 return $('<source />').attr({ 1467 src: url, 1468 'data-wf-ignore': '', 1469 }); 1470 }); 1471 1472 var videoNode = $('<video />').attr({ 1473 autoplay: nodeData.autoplay, 1474 loop: nodeData.loop, 1475 }) 1476 .css('background-image', 'url(' + nodeData.posterUrl + ')'); 1477 1478 videoNode.append(sourceNodes); 1479 1480 return videoNode; 1481 } 1482 1483 return { 1484 ready: ready 1485 }; 1486 }); 1487 1488 1489 /***/ 1490 }, 1491 /* 6 */ 1492 /***/ 1493 function(module, exports, __webpack_require__) { 1494 1495 'use strict'; 1496 1497 /** 1498 * Webflow: Brand pages on the subdomain 1499 */ 1500 1501 var Webflow = __webpack_require__(1); 1502 1503 Webflow.define('brand', module.exports = function($, _) { 1504 var api = {}; 1505 var $html = $('html'); 1506 var $body = $('body'); 1507 var location = window.location; 1508 var inApp = Webflow.env(); 1509 1510 // ----------------------------------- 1511 // Module methods 1512 1513 api.ready = function() { 1514 var doBranding = $html.attr('data-wf-status'); 1515 var publishedDomain = $html.attr('data-wf-domain') || ''; 1516 1517 if (/\.webflow\.io$/i.test(publishedDomain) && location.hostname !== publishedDomain) { 1518 doBranding = true; 1519 } 1520 1521 if (doBranding) { 1522 var $branding = $('<div></div>'); 1523 var $link = $('<a></a>'); 1524 $link.attr('href', 'http://webflow.com?utm_campaign=brandjs'); 1525 1526 $branding.css({ 1527 position: 'fixed', 1528 bottom: 0, 1529 right: 0, 1530 borderTopLeftRadius: '5px', 1531 backgroundColor: '#2b3239', 1532 padding: '8px 12px 5px 15px', 1533 fontFamily: 'Arial', 1534 fontSize: '10px', 1535 textTransform: 'uppercase', 1536 opacity: '0', 1537 transition: 'opacity 0.50s ease-in-out' 1538 }); 1539 1540 $link.css({ 1541 color: '#AAADB0', 1542 textDecoration: 'none' 1543 }); 1544 1545 var $webflowLogo = $('<img>'); 1546 $webflowLogo.attr('src', 'https://daks2k3a4ib2z.cloudfront.net/54153e6a3d25f2755b1f14ed/5445a4b1944ecdaa4df86d3e_subdomain-brand.svg'); 1547 $webflowLogo.css({ 1548 opacity: 0.9, 1549 width: '57px', 1550 verticalAlign: 'middle', 1551 paddingLeft: '4px', 1552 paddingBottom: '3px' 1553 }); 1554 1555 $branding.text('Built with'); 1556 $branding.append($webflowLogo); 1557 $link.append($branding); 1558 1559 $body.append($link); 1560 1561 if (/PhantomJS/.test(window.navigator.userAgent)) { 1562 return; 1563 } 1564 1565 $branding.css({ 1566 opacity: '1.0' 1567 }); 1568 } 1569 }; 1570 1571 // Export module 1572 return api; 1573 }); 1574 1575 1576 /***/ 1577 }, 1578 /* 7 */ 1579 /***/ 1580 function(module, exports, __webpack_require__) { 1581 1582 'use strict'; 1583 1584 /** 1585 * Webflow: Dropdown component 1586 */ 1587 1588 var Webflow = __webpack_require__(1); 1589 var IXEvents = __webpack_require__(2); 1590 1591 Webflow.define('dropdown', module.exports = function($, _) { 1592 var api = {}; 1593 var $doc = $(document); 1594 var $dropdowns; 1595 var designer; 1596 var inApp = Webflow.env(); 1597 var touch = Webflow.env.touch; 1598 var namespace = '.w-dropdown'; 1599 var stateOpen = 'w--open'; 1600 var closeEvent = 'w-close' + namespace; 1601 var ix = IXEvents.triggers; 1602 1603 // ----------------------------------- 1604 // Module methods 1605 1606 api.ready = api.design = api.preview = init; 1607 1608 // ----------------------------------- 1609 // Private methods 1610
1611 function init() { 1612 designer = inApp && Webflow.env('design'); 1613 1614 // Find all instances on the page 1615 $dropdowns = $doc.find(namespace); 1616 $dropdowns.each(build); 1617 } 1618 1619 function build(i, el) { 1620 var $el = $(el); 1621 1622 // Store state in data 1623 var data = $.data(el, namespace); 1624 if (!data) data = $.data(el, namespace, { 1625 open: false, 1626 el: $el, 1627 config: {} 1628 }); 1629 data.toggle = $el.children('.w-dropdown-toggle'); 1630 data.list = $('.w-dropdown-list' + data.toggle.attr('data-tltp')); 1631 data.links = data.list.children('.w-dropdown-link'); 1632 data.outside = outside(data); 1633 data.complete = complete(data); 1634 data.leave = leave(data); 1635 1636 // Remove old events 1637 $el.off(namespace); 1638 data.toggle.off(namespace); 1639 1640 // Set config from data attributes 1641 configure(data); 1642 1643 if (data.nav) data.nav.off(namespace); 1644 data.nav = $el.closest('.w-nav'); 1645 data.nav.on(closeEvent, handler(data)); 1646 1647 // Add events based on mode 1648 if (designer) { 1649 $el.on('setting' + namespace, handler(data)); 1650 } else { 1651 data.toggle.on('tap' + namespace, toggle(data)); 1652 if (data.config.hover) { 1653 data.toggle.on('mouseenter' + namespace, enter(data)); 1654 } 1655 $el.on(closeEvent, handler(data)); 1656 // Close in preview mode 1657 inApp && close(data); 1658 } 1659 } 1660 1661 function configure(data) { 1662 data.config = { 1663 hover: Boolean(data.el.attr('data-hover')) && !touch, 1664 delay: Number(data.el.attr('data-delay')) || 0 1665 }; 1666 } 1667 1668 function handler(data) { 1669 return function(evt, options) { 1670 options = options || {}; 1671 1672 if (evt.type === 'w-close') { 1673 return close(data); 1674 } 1675 1676 if (evt.type === 'setting') { 1677 configure(data); 1678 options.open === true && open(data, true); 1679 options.open === false && close(data, true); 1680 return; 1681 } 1682 }; 1683 } 1684 1685 function toggle(data) { 1686 return _.debounce(function() { 1687 data.open ? close(data) : open(data); 1688 }); 1689 } 1690 1691 function open(data) { 1692 if (data.open) return; 1693 closeOthers(data); 1694 data.open = true; 1695 data.list.addClass(stateOpen); 1696 data.toggle.addClass(stateOpen); 1697 ix.intro(0, data.el[0]); 1698 Webflow.redraw.up(); 1699 1700 // Listen for tap outside events 1701 if (!designer) $doc.on('tap' + namespace, data.outside); 1702 if (data.hovering) data.el.on('mouseleave' + namespace, data.leave); 1703 1704 // Clear previous delay 1705 window.clearTimeout(data.delayId); 1706 } 1707 1708 function close(data, immediate) { 1709 if (!data.open) 1710 return; 1711 1712 // Do not close hover-based menus if currently hovering 1713 if (data.config.hover && data.hovering) 1714 return; 1715 1716 data.open = false; 1717 var config = data.config; 1718 ix.outro(0, data.el[0]); 1719 1720 // Stop listening for tap outside events 1721 $doc.off('tap' + namespace, data.outside); 1722 data.el.off('mouseleave' + namespace, data.leave); 1723 1724 // Clear previous delay 1725 window.clearTimeout(data.delayId); 1726 1727 // Skip delay during immediate 1728 if (!config.delay || immediate) return data.complete(); 1729 1730 // Optionally wait for delay before close 1731 data.delayId = window.setTimeout(data.complete, config.delay); 1732 } 1733 1734 function closeOthers(data) { 1735 var self = data.el[0]; 1736 $dropdowns.each(function(i, other) { 1737 var $other = $(other); 1738 if ($other.is(self) || $other.has(self).length) return; 1739 $other.triggerHandler(closeEvent); 1740 }); 1741 } 1742 1743 function outside(data) { 1744 // Unbind previous tap handler if it exists 1745 if (data.outside) $doc.off('tap' + namespace, data.outside); 1746 1747 // Close menu when tapped outside 1748 return _.debounce(function(evt) { 1749 if (!data.open) 1750 return; 1751 var $target = $(evt.target); 1752 if ($target.closest('.w-dropdown-toggle').length) 1753 return; 1754 if ($target.closest('.tltp-fltr').length) 1755 return; 1756 1757 if (!data.el.is($target.closest(namespace))) { 1758 close(data); 1759 } 1760 }); 1761 } 1762 1763 function complete(data) { 1764 return function() { 1765 data.list.removeClass(stateOpen); 1766 data.toggle.removeClass(stateOpen); 1767 }; 1768 } 1769 1770 function enter(data) { 1771 return function() { 1772 data.hovering = true; 1773 open(data); 1774 }; 1775 } 1776 1777 function leave(data) { 1778 return function() { 1779 data.hovering = false;
1780 close(data); 1781 }; 1782 } 1783 1784 // Export module 1785 return api; 1786 }); 1787 1788 1789 /***/ 1790 }, 1791 /* 8 */ 1792 /***/ 1793 function(module, exports, __webpack_require__) { 1794 1795 'use strict'; 1796 1797 /** 1798 * Webflow: Editor loader 1799 */ 1800 1801 var Webflow = __webpack_require__(1); 1802 1803 Webflow.define('edit', module.exports = function($, _, options) { 1804 options = options || {}; 1805 1806 // Exit early in test env or when inside an iframe 1807 if (Webflow.env('test') || Webflow.env('frame')) { 1808 // Allow test fixtures to continue 1809 if (!options.fixture) { 1810 return { 1811 exit: 1 1812 }; 1813 } 1814 } 1815 1816 var api = {}; 1817 var $win = $(window); 1818 var $html = $(document.documentElement); 1819 var location = document.location; 1820 var hashchange = 'hashchange'; 1821 var loaded; 1822 var loadEditor = options.load || load; 1823 var hasLocalStorage = false; 1824 1825 try { 1826 // Check localStorage for editor data 1827 hasLocalStorage = localStorage && localStorage.getItem && localStorage.getItem('WebflowEditor'); 1828 } catch (e) { 1829 // SecurityError: browser storage has been disabled 1830 } 1831 1832 if (hasLocalStorage) { 1833 loadEditor(); 1834 1835 } else if (location.search) { 1836 // Check url query for `edit` parameter or any url ending in `?edit` 1837 if (/[?&](edit)(?:[=&?]|$)/.test(location.search) || /\?edit$/.test(location.href)) { 1838 loadEditor(); 1839 } 1840 1841 } else { 1842 // Check hash fragment to support `#hash?edit` 1843 $win.on(hashchange, checkHash).triggerHandler(hashchange); 1844 } 1845 1846 function checkHash() { 1847 if (loaded) return; 1848 // Load editor when hash contains `?edit` 1849 if (/\?edit/.test(location.hash)) loadEditor(); 1850 } 1851 1852 function load() { 1853 loaded = true; 1854 // Predefine global immediately to benefit Webflow.env 1855 window.WebflowEditor = true; 1856 $win.off(hashchange, checkHash); 1857 $.ajax({ 1858 url: cleanSlashes(("https://editor-api.webflow.com") + '/api/editor/view'), 1859 data: { 1860 siteId: $html.attr('data-wf-site') 1861 }, 1862 xhrFields: { 1863 withCredentials: true 1864 }, 1865 dataType: 'json', 1866 crossDomain: true, 1867 success: success 1868 }); 1869 } 1870 1871 function success(data) { 1872 if (!data) { 1873 console.error('Could not load editor data'); 1874 return; 1875 } 1876 getScript(prefix(data.scriptPath), function() { 1877 window.WebflowEditor(data); 1878 }); 1879 } 1880 1881 function getScript(url, done) { 1882 $.ajax({ 1883 type: 'GET', 1884 url: url, 1885 dataType: 'script', 1886 cache: true 1887 }).then(done, error); 1888 } 1889 1890 function error(jqXHR, textStatus, errorThrown) { 1891 console.error('Could not load editor script: ' + textStatus); 1892 throw errorThrown; 1893 } 1894 1895 function prefix(url) { 1896 return (url.indexOf('//') >= 0) ? url : cleanSlashes(("https://editor-api.webflow.com") + url); 1897 } 1898 1899 function cleanSlashes(url) { 1900 return url.replace(/([^:])\/\//g, '$1/'); 1901 } 1902 1903 // Export module 1904 return api; 1905 }); 1906 1907 1908 /***/ 1909 }, 1910 /* 9 */ 1911 /***/ 1912 function(module, exports) { 1913 1914 /** 1915 * Returns a Boolean representing whether or not the client is a mobile browser. 1916 * 1917 * NOTE: Many thanks to detectmobilebrowsers.com for this user agent detection 1918 * regex, without which the mobile internet probably wouldn't exist. 1919 */ 1920 Webflow.isMobile = function() { 1921 var userAgent = navigator.userAgent || navigator.vendor || window.opera; 1922 return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i 1923 .test(userAgent) || 1924 /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|
1924sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i 1925 .test(userAgent.substr(0, 4)); 1926 } 1927 1928 1929 /***/ 1930 }, 1931 /* 10 */ 1932 /***/ 1933 function(module, exports, __webpack_require__) { 1934 1935 /** 1936 * Webflow: Forms 1937 */ 1938 1939 var Webflow = __webpack_require__(1); 1940 1941 Webflow.define('forms', module.exports = function($, _) { 1942 var api = {}; 1943 1944 // Cross-Domain AJAX for IE8 1945 __webpack_require__(22); 1946 1947 var $doc = $(document); 1948 var $forms; 1949 var loc = window.location; 1950 var retro = window.XDomainRequest && !window.atob; 1951 var namespace = '.w-form'; 1952 var siteId; 1953 var emailField = /e(\-)?mail/i; 1954 var emailValue = /^\S+@\S+$/; 1955 var alert = window.alert; 1956 var listening; 1957 1958 // MailChimp domains: list-manage.com + mirrors 1959 var chimpRegex = /list-manage[1-9]?.com/i; 1960 1961 var disconnected = _.debounce(function() { 1962 alert('Oops! This page has improperly configured forms. Please contact your website administrator to fix this issue.'); 1963 }, 100); 1964 1965 api.ready = function() { 1966 // Init forms 1967 init(); 1968
1969 // Wire document events once 1970 if (!listening) addListeners(); 1971 }; 1972 1973 api.preview = api.design = function() { 1974 init(); 1975 }; 1976 1977 function init() { 1978 siteId = $('html').attr('data-wf-site'); 1979 1980 $forms = $(namespace + ' form'); 1981 if (!$forms.length) return; 1982 $forms.each(build); 1983 } 1984 1985 function build(i, el) { 1986 // Store form state using namespace 1987 var $el = $(el); 1988 var data = $.data(el, namespace); 1989 if (!data) data = $.data(el, namespace, { 1990 form: $el 1991 }); // data.form 1992 1993 reset(data); 1994 var wrap = $el.closest('div.w-form'); 1995 data.done = wrap.find('> .w-form-done'); 1996 data.fail = wrap.find('> .w-form-fail'); 1997 1998 var action = data.action = $el.attr('action'); 1999 data.handler = null; 2000 data.redirect = $el.attr('data-redirect'); 2001 2002 // MailChimp form 2003 if (chimpRegex.test(action)) { 2004 data.handler = submitMailChimp; 2005 return; 2006 } 2007 2008 // Custom form action 2009 if (action) return; 2010 2011 // Webflow form 2012 if (siteId) { 2013 data.handler = submitWebflow; 2014 return; 2015 } 2016 2017 // Alert for disconnected Webflow forms 2018 disconnected(); 2019 } 2020 2021 function addListeners() { 2022 listening = true; 2023 2024 // Handle form submission for Webflow forms 2025 $doc.on('submit', namespace + ' form', function(evt) { 2026 var data = $.data(this, namespace); 2027 if (data.handler) { 2028 data.evt = evt; 2029 data.handler(data); 2030 } 2031 }); 2032 } 2033 2034 // Reset data common to all submit handlers 2035 function reset(data) { 2036 var btn = data.btn = data.form.find(':input[type="submit"]'); 2037 data.wait = data.btn.attr('data-wait') || null; 2038 data.success = false; 2039 btn.prop('disabled', false); 2040 data.label && btn.val(data.label); 2041 } 2042 2043 // Disable submit button 2044 function disableBtn(data) { 2045 var btn = data.btn; 2046 var wait = data.wait; 2047 btn.prop('disabled', true); 2048 // Show wait text and store previous label 2049 if (wait) { 2050 data.label = btn.val(); 2051 btn.val(wait); 2052 } 2053 } 2054 2055 // Find form fields, validate, and set value pairs 2056 function findFields(form, result) { 2057 var status = null; 2058 result = result || {}; 2059 2060 // The ":input" selector is a jQuery shortcut to select all inputs, selects, textareas 2061 form.find(':input:not([type="submit"])').each(function(i, el) { 2062 var field = $(el); 2063 var type = field.attr('type'); 2064 var name = field.attr('data-name') || field.attr('name') || ('Field ' + (i + 1)); 2065 var value = field.val(); 2066 2067 if (type === 'checkbox') { 2068 value = field.is(':checked'); 2069 } 2070 if (type === 'radio') { 2071 // Radio group value already processed 2072 if (result[name] === null || typeof result[name] === 'string') { 2073 return; 2074 } 2075 2076 value = form.find('input[name="' + field.attr('name') + '"]:checked').val() || null; 2077 } 2078 2079 if (typeof value === 'string') value = $.trim(value); 2080 result[name] = value; 2081 status = status || getStatus(field, type, name, value); 2082 }); 2083 2084 return status; 2085 } 2086 2087 function getStatus(field, type, name, value) { 2088 var status = null; 2089 2090 if (type === 'password') { 2091 status = 'Passwords cannot be submitted.'; 2092 } else if (field.attr('required')) { 2093 if (!value) { 2094 status = 'Please fill out the required field: ' + name; 2095 } else if (emailField.test(name) || emailField.test(field.attr('type'))) { 2096 if (!emailValue.test(value)) status = 'Please enter a valid email address for: ' + name; 2097 } 2098 } 2099 2100 return status; 2101 } 2102 2103 // Submit form to Webflow 2104 function submitWebflow(data) { 2105 reset(data); 2106 2107 var form = data.form; 2108 var payload = { 2109 name: form.attr('data-name') || form.attr('name') || 'Untitled Form', 2110 source: loc.href, 2111 test: Webflow.env(), 2112 fields: {}, 2113 dolphin: /pass[\s-_]?(word|code)|secret|login|credentials/i.test(form.html()) 2114 }; 2115 2116 preventDefault(data); 2117 2118 // Find & populate all fields 2119 var status = findFields(form, payload.fields); 2120 if (status) return alert(status); 2121 2122 // Disable submit button 2123 disableBtn(data); 2124 2125 // Read site ID 2126 // NOTE: If this site is exported, the HTML tag must retain the data-wf-site attribute for forms to work 2127 if (!siteId) { 2128 afterSubmit(data); 2129 return; 2130 } 2131 var url = ("https://webflow.com") + '/api/v1/form/' + siteId; 2132 2133 // Work around same-protocol IE XDR limitation - without this IE9 and below forms won't submit 2134 if (retro && url.indexOf(("https://webflow.com")) >= 0) { 2135 url = url.replace(("https://webflow.com"), ("http://formdata.webflow.com")); 2136 } 2137 2138 $.ajax({ 2139 url: url, 2140 type: 'POST', 2141 data: payload, 2142 dataType: 'json', 2143 crossDomain: true 2144 }).done(function() { 2145 data.success = true; 2146 afterSubmit(data); 2147 }).fail(function(response, textStatus, jqXHR) { 2148 afterSubmit(data); 2149 }); 2150 } 2151 2152 // Submit form to MailChimp 2153 function submitMailChimp(data) { 2154 reset(data); 2155 2156 var form = data.form; 2157 var payload = {}; 2158 2159 // Skip Ajax submission if http/s mismatch, fallback to POST instead 2160 if (/^https/.test(loc.href) && !/^https/.test(data.action)) { 2161 form.attr('method', 'post'); 2162 return; 2163 } 2164 2165 preventDefault(data); 2166 2167 // Find & populate all fields 2168 var status = findFields(form, payload); 2169 if (status) return alert(status); 2170 2171 // Disable submit button 2172 disableBtn(data); 2173 2174 // Use special format for MailChimp params 2175 var fullName; 2176 _.each(payload, function(value, key) { 2177 if (emailField.test(key)) payload.EMAIL = value; 2178 if (/^((full[ _-]?)?name)$/i.test(key)) fullName = value; 2179 if (/^(first[ _-]?name)$/i.test(key)) payload.FNAME = value; 2180 if (/^(last[ _-]?name)$/i.test(key)) payload.LNAME = value; 2181 }); 2182 2183 if (fullName && !payload.FNAME) { 2184 fullName = fullName.split(' '); 2185 payload.FNAME = fullName[0]; 2186 payload.LNAME = payload.LNAME || fullName[1]; 2187 } 2188 2189 // Use the (undocumented) MailChimp jsonp api 2190 var url = data.action.replace('/post?', '/post-json?') + '&c=?'; 2191 // Add special param to prevent bot signups 2192 var userId = url.indexOf('u=') + 2; 2193 userId = url.substring(userId, url.indexOf('&', userId)); 2194 var listId = url.indexOf('id=') + 3; 2195 listId = url.substring(listId, url.indexOf('&', listId)); 2196 payload['b_' + userId + '_' + listId] = ''; 2197 2198 $.ajax({ 2199 url: url, 2200 data: payload, 2201 dataType: 'jsonp' 2202 }).done(function(resp) { 2203 data.success = (resp.result === 'success' || /already/.test(resp.msg)); 2204 if (!data.success) console.info('MailChimp error: ' + resp.msg); 2205 afterSubmit(data); 2206 }).fail(function(response, textStatus, jqXHR) { 2207 afterSubmit(data); 2208 }); 2209 } 2210 2211 // Common callback which runs after all Ajax submissions 2212 function afterSubmit(data) { 2213 var form = data.form; 2214 var wrap = form.closest('div.w-form'); 2215 var redirect = data.redirect; 2216 var success = data.success; 2217 2218 // Redirect to a success url if defined 2219 if (success && redirect) { 2220 Webflow.location(redirect); 2221 return; 2222 } 2223 2224 // Show or hide status divs 2225 data.done.toggle(success); 2226 data.fail.toggle(!success); 2227 2228 // Hide form on success 2229 form.toggle(!success); 2230 2231 // Reset data and enable submit button 2232 reset(data); 2233 } 2234 2235 function preventDefault(data) { 2236 data.evt && data.evt.preventDefault(); 2237 data.evt = null; 2238 } 2239 2240 // Export module 2241 return api; 2242 }); 2243 2244 2245 /***/ 2246 }, 2247 /* 11 */ 2248 /***/ 2249 function(module, exports, __webpack_require__) { 2250 2251 'use strict'; 2252 2253 /** 2254 * Webflow: Google+ widget 2255 */ 2256 2257 var Webflow = __webpack_require__(1); 2258 2259 Webflow.define('gplus', module.exports = function($, _) { 2260 var $doc = $(document); 2261 var api = {}; 2262 var loaded; 2263 2264 api.ready = function() { 2265 // Load Google+ API on the front-end 2266 if (!Webflow.env() && !loaded) init(); 2267 }; 2268
2269 function init() { 2270 $doc.find('.w-widget-gplus').length && load(); 2271 } 2272 2273 function load() { 2274 loaded = true; 2275 $.getScript('https://apis.google.com/js/plusone.js'); 2276 } 2277 2278 // Export module 2279 return api; 2280 }); 2281 2282 2283 /***/ 2284 }, 2285 /* 12 */ 2286 /***/ 2287 function(module, exports, __webpack_require__) { 2288 2289 'use strict'; 2290 /*eslint no-self-compare:0 */ 2291 2292 /** 2293 * Webflow: Interactions 2294 */ 2295 2296 var Webflow = __webpack_require__(1); 2297 var IXEvents = __webpack_require__(2); 2298 2299 Webflow.define('ix', module.exports = function($, _) { 2300 var api = {}; 2301 var designer; 2302 var $win = $(window); 2303 var namespace = '.w-ix'; 2304 var tram = $.tram; 2305 var env = Webflow.env; 2306 var inApp = env(); 2307 var emptyFix = env.chrome && env.chrome < 35; 2308 var transNone = 'none 0s ease 0s'; 2309 var $subs = $(); 2310 var config = {}; 2311 var anchors = []; 2312 var loads = []; 2313 var readys = []; 2314 var destroyed; 2315 var readyDelay = 1; 2316 2317 // Component types and proxy selectors 2318 var components = { 2319 tabs: '.w-tab-link, .w-tab-pane', 2320 dropdown: '.w-dropdown', 2321 slider: '.w-slide', 2322 navbar: '.w-nav' 2323 }; 2324 2325 // ----------------------------------- 2326 // Module methods 2327 2328 api.init = function(list) { 2329 setTimeout(function() { 2330 configure(list); 2331 }, 1); 2332 }; 2333 2334 api.preview = function() { 2335 designer = false;
2336 readyDelay = 100; 2337 setTimeout(function() { 2338 configure(window.__wf_ix); 2339 }, 1); 2340 }; 2341 2342 api.design = function() { 2343 designer = true; 2344 api.destroy(); 2345 }; 2346 2347 api.destroy = function() { 2348 destroyed = true; 2349 $subs.each(teardown); 2350 Webflow.scroll.off(scroll); 2351 IXEvents.async(); 2352 anchors = []; 2353 loads = []; 2354 readys = []; 2355 }; 2356 2357 api.ready = function() { 2358 // Ready should only be used after destroy, as a way to re-init 2359 if (config && destroyed) { 2360 destroyed = false; 2361 init(); 2362 } 2363 }; 2364 2365 api.run = run; 2366 api.style = inApp ? styleApp : stylePub; 2367 2368 // ----------------------------------- 2369 // Private methods 2370 2371 function configure(list) { 2372 if (!list) return; 2373 2374 // Map all interactions by slug 2375 config = {}; 2376 _.each(list, function(item) { 2377 config[item.slug] = item.value; 2378 }); 2379 2380 // Init ix after config 2381 init(); 2382 } 2383 2384 function init() { 2385 // Build each element's interaction keying from data attribute 2386 var els = $('[data-ix]'); 2387 if (!els.length) return; 2388 els.each(teardown); 2389 els.each(build); 2390 2391 // Listen for scroll events if any anchors exist 2392 if (anchors.length) { 2393 Webflow.scroll.on(scroll); 2394 setTimeout(scroll, 1); 2395 } 2396 2397 // Handle loads or readys if they exist 2398 if (loads.length) Webflow.load(runLoads); 2399 if (readys.length) setTimeout(runReadys, readyDelay); 2400 2401 // Trigger queued events, must happen after init 2402 IXEvents.init(); 2403 2404 // Trigger a redraw to ensure all IX intros play 2405 Webflow.redraw.up(); 2406 } 2407 2408 function build(i, el) { 2409 var $el = $(el); 2410 var id = $el.attr('data-ix'); 2411 var ix = config[id]; 2412 if (!ix) return; 2413 var triggers = ix.triggers; 2414 if (!triggers) return; 2415 2416 // Set styles immediately to provide tram with starting transform values 2417 api.style($el, ix.style); 2418 2419 _.each(triggers, function(trigger) { 2420 var state = {}; 2421 var type = trigger.type; 2422 var stepsB = trigger.stepsB && trigger.stepsB.length; 2423 2424 function runA() { 2425 run(trigger, $el, { 2426 group: 'A' 2427 }); 2428 } 2429 2430 function runB() { 2431 run(trigger, $el, { 2432 group: 'B' 2433 }); 2434 } 2435 2436 if (type === 'load') { 2437 (trigger.preload && !inApp) ? loads.push(runA) : readys.push(runA); 2438 return; 2439 } 2440 2441 if (type === 'click') { 2442 $el.on('click' + namespace, function(evt) { 2443 // Avoid late clicks on touch devices 2444 if (!Webflow.validClick(evt.currentTarget)) return; 2445 2446 // Prevent default on empty hash urls 2447 if ($el.attr('href') === '#') evt.preventDefault(); 2448 2449 run(trigger, $el, { 2450 group: state.clicked ? 'B' : 'A' 2451 }); 2452 if (stepsB) state.clicked = !state.clicked; 2453 }); 2454 $subs = $subs.add($el); 2455 return; 2456 } 2457 2458 if (type === 'hover') { 2459 $el.on('mouseenter' + namespace, runA); 2460 $el.on('mouseleave' + namespace, runB); 2461 $subs = $subs.add($el); 2462 return; 2463 } 2464 2465 if (type === 'scroll') { 2466 anchors.push({ 2467 el: $el, 2468 trigger: trigger, 2469 state: { 2470 active: false 2471 }, 2472 offsetTop: convert(trigger.offsetTop), 2473 offsetBot: convert(trigger.offsetBot) 2474 }); 2475 return; 2476 } 2477 2478 // Check for a proxy component selector 2479 // type == [tabs, dropdown, slider, navbar] 2480 var proxy = components[type]; 2481 if (proxy) { 2482 var $proxy = $el.closest(proxy); 2483 $proxy.on(IXEvents.types.INTRO, runA).on(IXEvents.types.OUTRO, runB); 2484 $subs = $subs.add($proxy); 2485 return; 2486 } 2487 }); 2488 } 2489 2490 function convert(offset) { 2491 if (!offset) return 0; 2492 offset = String(offset); 2493 var result = parseInt(offset, 10); 2494 if (result !== result) return 0; 2495 if (offset.indexOf('%') > 0) { 2496 result /= 100; 2497 if (result >= 1) result = 0.999; 2498 } 2499 return result; 2500 } 2501 2502 function teardown(i, el) { 2503 $(el).off(namespace); 2504 } 2505 2506 function scroll() { 2507 var viewTop = $win.scrollTop(); 2508 var viewHeight = $win.height(); 2509 2510 // Check each anchor for a valid scroll trigger 2511 var count = anchors.length; 2512 for (var i = 0; i < count; i++) { 2513 var anchor = anchors[i]; 2514 var $el = anchor.el; 2515 var trigger = anchor.trigger; 2516 var stepsB = trigger.stepsB && trigger.stepsB.length; 2517 var state = anchor.state; 2518 var top = $el.offset().top; 2519 var height = $el.outerHeight(); 2520 var offsetTop = anchor.offsetTop; 2521 var offsetBot = anchor.offsetBot; 2522 if (offsetTop < 1 && offsetTop > 0) offsetTop *= viewHeight; 2523 if (offsetBot < 1 && offsetBot > 0) offsetBot *= viewHeight; 2524 var active = (top + height - offsetTop >= viewTop && top + offsetBot <= viewTop + viewHeight); 2525 if (active === state.active) continue; 2526 if (active === false && !stepsB) continue; 2527 state.active = active; 2528 run(trigger, $el, { 2529 group: active ? 'A' : 'B' 2530 }); 2531 } 2532 } 2533 2534 function runLoads() { 2535 var count = loads.length; 2536 for (var i = 0; i < count; i++) { 2537 loads[i](); 2538 } 2539 } 2540 2541 function runReadys() { 2542 var count = readys.length; 2543 for (var i = 0; i < count; i++) { 2544 readys[i](); 2545 } 2546 } 2547 2548 function run(trigger, $el, opts, replay) { 2549 opts = opts || {}; 2550 var done = opts.done; 2551
2552 // Do not run in designer unless forced 2553 if (designer && !opts.force) return; 2554 2555 // Operate on a set of grouped steps 2556 var group = opts.group || 'A'; 2557 var loop = trigger['loop' + group]; 2558 var steps = trigger['steps' + group]; 2559 if (!steps || !steps.length) return; 2560 if (steps.length < 2) loop = false; 2561 2562 // One-time init before any loops 2563 if (!replay) { 2564 2565 // Find selector within element descendants, siblings, or query whole document 2566 var selector = trigger.selector; 2567 if (selector) { 2568 if (trigger.descend) { 2569 $el = $el.find(selector); 2570 } else if (trigger.siblings) { 2571 $el = $el.siblings(selector); 2572 } else { 2573 $el = $(selector); 2574 } 2575 if (inApp) $el.attr('data-ix-affect', 1); 2576 } 2577 2578 // Apply empty fix for certain Chrome versions 2579 if (emptyFix) $el.addClass('w-ix-emptyfix'); 2580 2581 // Set preserve3d for triggers with transforms 2582 if (trigger.preserve3d) $el.css('transform-style', 'preserve-3d'); 2583 } 2584 2585 var _tram = tram($el); 2586 2587 // Add steps 2588 var meta = {}; 2589 for (var i = 0; i < steps.length; i++) { 2590 addStep(_tram, steps[i], meta); 2591 } 2592 2593 function fin() { 2594 // Run trigger again if looped 2595 if (loop) return run(trigger, $el, opts, true); 2596 2597 // Reset any 'auto' values 2598 if (meta.width === 'auto') _tram.set({ 2599 width: 'auto' 2600 }); 2601 if (meta.height === 'auto') _tram.set({ 2602 height: 'auto' 2603 }); 2604 2605 // Run callback 2606 done && done(); 2607 } 2608 2609 // Add final step to queue if tram has started 2610 meta.start ? _tram.then(fin) : fin(); 2611 } 2612 2613 function addStep(_tram, step, meta) { 2614 var addMethod = 'add'; 2615 var startMethod = 'start'; 2616 2617 // Once the transition has started, we will always use then() to add to the queue. 2618 if (meta.start) addMethod = startMethod = 'then'; 2619 2620 // Parse transitions string on the current step 2621 var transitions = step.transition; 2622 if (transitions) { 2623 transitions = transitions.split(','); 2624 for (var i = 0; i < transitions.length; i++) { 2625 var transition = transitions[i]; 2626 _tram[addMethod](transition); 2627 } 2628 } 2629 2630 // Build a clean object to pass to the tram method 2631 var clean = tramify(step) || {}; 2632 2633 // Store last width and height values 2634 if (clean.width != null) meta.width = clean.width; 2635 if (clean.height != null) meta.height = clean.height; 2636 2637 // When transitions are not present, set values immediately and continue queue. 2638 if (transitions == null) { 2639 2640 // If we have started, wrap set() in then() and reset queue 2641 if (meta.start) { 2642 _tram.then(function() { 2643 var queue = this.queue; 2644 this.set(clean); 2645 if (clean.display) { 2646 _tram.redraw(); 2647 Webflow.redraw.up(); 2648 } 2649 this.queue = queue; 2650 this.next(); 2651 }); 2652 } else { 2653 _tram.set(clean); 2654 2655 // Always redraw after setting display 2656 if (clean.display) { 2657 _tram.redraw(); 2658 Webflow.redraw.up(); 2659 } 2660 } 2661 2662 // Use the wait() method to kick off queue in absence of transitions. 2663 var wait = clean.wait; 2664 if (wait != null) { 2665 _tram.wait(wait); 2666 meta.start = true; 2667 } 2668 2669 // Otherwise, when transitions are present 2670 } else { 2671 2672 // If display is present, handle it separately 2673 if (clean.display) { 2674 var display = clean.display; 2675 delete clean.display; 2676 2677 // If we've already started, we need to wrap it in a then() 2678 if (meta.start) { 2679 _tram.then(function() { 2680 var queue = this.queue; 2681 this.set({ 2682 display: display 2683 }).redraw(); 2684 Webflow.redraw.up(); 2685 this.queue = queue; 2686 this.next(); 2687 }); 2688 } else { 2689 _tram.set({ 2690 display: display 2691 }).redraw(); 2692 Webflow.redraw.up(); 2693 } 2694 } 2695 2696 // Otherwise, start a transition using the current start method. 2697 _tram[startMethod](clean); 2698 meta.start = true; 2699 } 2700 } 2701 2702 // (In app) Set styles immediately and manage upstream transition
2703 function styleApp(el, data) { 2704 var _tram = tram(el); 2705 2706 // Get computed transition value 2707 el.css('transition', ''); 2708 var computed = el.css('transition'); 2709 2710 // If computed is set to none, clear upstream 2711 if (computed === transNone) computed = _tram.upstream = null; 2712 2713 // Set upstream transition to none temporarily 2714 _tram.upstream = transNone; 2715 2716 // Set values immediately 2717 _tram.set(tramify(data)); 2718 2719 // Only restore upstream in preview mode 2720 _tram.upstream = computed; 2721 } 2722 2723 // (Published) Set styles immediately on specified jquery element 2724 function stylePub(el, data) { 2725 tram(el).set(tramify(data)); 2726 } 2727 2728 // Build a clean object for tram 2729 function tramify(obj) { 2730 var result = {}; 2731 var found = false; 2732 for (var x in obj) { 2733 if (x === 'transition') continue; 2734 result[x] = obj[x]; 2735 found = true; 2736 } 2737 // If empty, return null for tram.set/stop compliance 2738 return found ? result : null; 2739 } 2740 2741 // Export module 2742 return api; 2743 }); 2744 2745 2746 /***/ 2747 }, 2748 /* 13 */ 2749 /***/ 2750 function(module, exports, __webpack_require__) { 2751 2752 'use strict'; 2753 /*eslint 2754 no-use-before-define: 0, 2755 no-shadow: 0 2756 */ 2757 2758 /** 2759 * Webflow: Lightbox component 2760 */ 2761 2762 var Webflow = __webpack_require__(1); 2763 2764 function createLightbox(window, document, $) { 2765 var tram = $.tram; 2766 var isArray = Array.isArray; 2767 var namespace = 'w-lightbox'; 2768 var prefix = namespace + '-'; 2769 var prefixRegex = /(^|\s+)/g; 2770 2771 // Array of objects describing items to be displayed. 2772 var items = []; 2773 2774 // Index of the currently displayed item. 2775 var currentIndex; 2776 2777 // Object holding references to jQuery wrapped nodes. 2778 var $refs; 2779 2780 // Instance of Spinner 2781 var spinner; 2782 2783 function lightbox(thing, index) { 2784 items = isArray(thing) ? thing : [thing]; 2785 2786 if (!$refs) { 2787 lightbox.build(); 2788 } 2789 2790 if (items.length > 1) { 2791 $refs.items = $refs.empty; 2792 2793 items.forEach(function(item) { 2794 var $thumbnail = dom('thumbnail'); 2795 var $item = dom('item').append($thumbnail); 2796 2797 $refs.items = $refs.items.add($item); 2798 2799 loadImage(item.thumbnailUrl || item.url, function($image) { 2800 if ($image.prop('width') > $image.prop('height')) { 2801 addClass($image, 'wide'); 2802 } else { 2803 addClass($image, 'tall'); 2804 } 2805 $thumbnail.append(addClass($image, 'thumbnail-image')); 2806 }); 2807 }); 2808 2809 $refs.strip.empty().append($refs.items); 2810 addClass($refs.content, 'group'); 2811 } 2812 2813 tram( 2814 // Focus the lightbox to receive keyboard events. 2815 removeClass($refs.lightbox, 'hide').focus() 2816 ) 2817 .add('opacity .3s') 2818 .start({ 2819 opacity: 1 2820 }); 2821 2822 // Prevent document from scrolling while lightbox is active. 2823 addClass($refs.html, 'noscroll'); 2824 2825 return lightbox.show(index || 0); 2826 } 2827 2828 /** 2829 * Creates the DOM structure required by the lightbox. 2830 */ 2831 lightbox.build = function() { 2832 // In case `build` is called more than once. 2833 lightbox.destroy(); 2834 2835 $refs = { 2836 html: $(document.documentElement), 2837 // Empty jQuery object can be used to build new ones using `.add`. 2838 empty: $() 2839 }; 2840 2841 $refs.arrowLeft = dom('control left inactive'); 2842 $refs.arrowRight = dom('control right inactive'); 2843 $refs.close = dom('control close'); 2844 2845 $refs.spinner = dom('spinner'); 2846 $refs.strip = dom('strip'); 2847 2848 spinner = new Spinner($refs.spinner, prefixed('hide')); 2849 2850 $refs.content = dom('content') 2851 .append($refs.spinner, $refs.arrowLeft, $refs.arrowRight, $refs.close); 2852 2853 $refs.container = dom('container') 2854 .append($refs.content, $refs.strip); 2855 2856 $refs.lightbox = dom('backdrop hide') 2857 .append($refs.container); 2858 2859 // We are delegating events for performance reasons and also 2860 // to not have to reattach handlers when images change. 2861 $refs.strip.on('tap', selector('item'), itemTapHandler); 2862 $refs.content 2863 .on('swipe', swipeHandler) 2864 .on('tap', selector('left'), handlerPrev) 2865 .on('tap', selector('right'), handlerNext) 2866 .on('tap', selector('close'), handlerHide) 2867 .on('tap', selector('image, caption'), handlerNext); 2868 $refs.container 2869 .on('tap', selector('view, strip'), handlerHide) 2870 // Prevent images from being dragged around. 2871 .on('dragstart', selector('img'), preventDefault); 2872 $refs.lightbox 2873 .on('keydown', keyHandler) 2874 // IE loses focus to inner nodes without letting us know. 2875 .on('focusin', focusThis); 2876 2877 // The `tabindex` attribute is needed to enable non-input elements 2878 // to receive keyboard events. 2879 $('body').append($refs.lightbox.prop('tabIndex', 0)); 2880 2881 return lightbox; 2882 }; 2883 2884 /**
2885 * Dispose of DOM nodes created by the lightbox. 2886 */ 2887 lightbox.destroy = function() { 2888 if (!$refs) { 2889 return; 2890 } 2891 2892 // Event handlers are also removed. 2893 removeClass($refs.html, 'noscroll'); 2894 $refs.lightbox.remove(); 2895 $refs = undefined; 2896 }; 2897 2898 /** 2899 * Show a specific item. 2900 */ 2901 lightbox.show = function(index) { 2902 // Bail if we are already showing this item. 2903 if (index === currentIndex) { 2904 return; 2905 } 2906 2907 var item = items[index]; 2908 if (!item) { 2909 return lightbox.hide(); 2910 } 2911 2912 var previousIndex = currentIndex; 2913 currentIndex = index; 2914 spinner.show(); 2915 2916 // For videos, load an empty SVG with the video dimensions to preserve 2917 // the videoâs aspect ratio while being responsive. 2918 var url = item.html && svgDataUri(item.width, item.height) || item.url; 2919 loadImage(url, function($image) { 2920 // Make sure this is the last item requested to be shown since 2921 // images can finish loading in a different order than they were 2922 // requested in. 2923 if (index !== currentIndex) { 2924 return; 2925 } 2926 2927 var $figure = dom('figure', 'figure').append(addClass($image, 'image')); 2928 var $frame = dom('frame').append($figure); 2929 var $newView = dom('view').append($frame); 2930 var $html, isIframe; 2931 2932 if (item.html) { 2933 $html = $(item.html); 2934 isIframe = $html.is('iframe'); 2935 2936 if (isIframe) { 2937 $html.on('load', transitionToNewView); 2938 } 2939 2940 $figure.append(addClass($html, 'embed')); 2941 } 2942 2943 if (item.caption) { 2944 $figure.append(dom('caption', 'figcaption').text(item.caption)); 2945 } 2946 2947 $refs.spinner.before($newView); 2948 2949 if (!isIframe) { 2950 transitionToNewView(); 2951 } 2952 2953 function transitionToNewView() { 2954 spinner.hide(); 2955 2956 if (index !== currentIndex) { 2957 $newView.remove(); 2958 return; 2959 } 2960 2961 2962 toggleClass($refs.arrowLeft, 'inactive', index <= 0); 2963 toggleClass($refs.arrowRight, 'inactive', index >= items.length - 1); 2964 2965 if ($refs.view) { 2966 tram($refs.view) 2967 .add('opacity .3s') 2968 .start({ 2969 opacity: 0 2970 }) 2971 .then(remover($refs.view)); 2972 2973 tram($newView) 2974 .add('opacity .3s') 2975 .add('transform .3s') 2976 .set({ 2977 x: index > previousIndex ? '80px' : '-80px' 2978 }) 2979 .start({ 2980 opacity: 1, 2981 x: 0 2982 }); 2983 } else { 2984 $newView.css('opacity', 1); 2985 } 2986 2987 $refs.view = $newView; 2988 2989 if ($refs.items) { 2990 // Mark proper thumbnail as active 2991 addClass(removeClass($refs.items, 'active').eq(index), 'active'); 2992 } 2993 } 2994 }); 2995 2996 return lightbox; 2997 }; 2998 2999 /** 3000 * Hides the lightbox. 3001 */ 3002 lightbox.hide = function() { 3003 tram($refs.lightbox) 3004 .add('opacity .3s') 3005 .start({ 3006 opacity: 0 3007 }) 3008 .then(hideLightbox); 3009 3010 return lightbox; 3011 }; 3012 3013 lightbox.prev = function() { 3014 if (currentIndex > 0) { 3015 lightbox.show(currentIndex - 1); 3016 } 3017 }; 3018 3019 lightbox.next = function() { 3020 if (currentIndex < items.length - 1) { 3021 lightbox.show(currentIndex + 1); 3022 } 3023 }; 3024 3025 function createHandler(action) { 3026 return function(event) { 3027 // We only care about events triggered directly on the bound selectors. 3028 if (this !== event.target) { 3029 return; 3030 } 3031 3032 event.stopPropagation(); 3033 event.preventDefault(); 3034 3035 action(); 3036 }; 3037 } 3038 3039 var handlerPrev = createHandler(lightbox.prev); 3040 var handlerNext = createHandler(lightbox.next); 3041 var handlerHide = createHandler(lightbox.hide); 3042 3043 var itemTapHandler = function(event) { 3044 var index = $(this).index(); 3045 3046 event.preventDefault(); 3047 lightbox.show(index); 3048 }; 3049 3050 var swipeHandler = function(event, data) { 3051 // Prevent scrolling. 3052 event.preventDefault(); 3053 3054 if (data.direction === 'left') { 3055 lightbox.next(); 3056 } else if (data.direction === 'right') { 3057 lightbox.prev(); 3058 } 3059 }; 3060 3061 var focusThis = function() { 3062 this.focus(); 3063 }; 3064 3065 function preventDefault(event) { 3066 event.preventDefault(); 3067 } 3068 3069 function keyHandler(event) { 3070 var keyCode = event.keyCode; 3071 3072 // [esc] 3073 if (keyCode === 27) { 3074 lightbox.hide(); 3075 } 3076 3077 // [â] 3078 else if (keyCode === 37) { 3079 lightbox.prev(); 3080 } 3081 3082 // [â¶] 3083 else if (keyCode === 39) { 3084 lightbox.next(); 3085 } 3086 } 3087 3088 function hideLightbox() { 3089 // If the lightbox hasn't been destroyed already 3090 if ($refs) { 3091 removeClass($refs.html, 'noscroll'); 3092 addClass($refs.lightbox, 'hide'); 3093 $refs.strip.empty(); 3094 $refs.view && $refs.view.remove(); 3095 3096 // Reset some stuff 3097 removeClass($refs.content, 'group'); 3098 addClass($refs.arrowLeft, 'inactive'); 3099 addClass($refs.arrowRight, 'inactive'); 3100 3101 currentIndex = $refs.view = undefined; 3102 } 3103 } 3104 3105 function loadImage(url, callback) { 3106 var $image = dom('img', 'img'); 3107 3108 $image.one('load', function() { 3109 callback($image); 3110 }); 3111 3112 // Start loading image. 3113 $image.attr('src', url); 3114 3115 return $image; 3116 } 3117 3118 function remover($element) { 3119 return function() { 3120 $element.remove(); 3121 }; 3122 } 3123 3124 /** 3125 * Spinner 3126 */ 3127 function Spinner($spinner, className, delay) { 3128 this.$element = $spinner; 3129 this.className = className; 3130 this.delay = delay || 200; 3131 this.hide(); 3132 } 3133 3134 Spinner.prototype.show = function() { 3135 var spinner = this; 3136 3137 // Bail if we are already showing the spinner. 3138 if (spinner.timeoutId) { 3139 return; 3140 } 3141 3142 spinner.timeoutId = setTimeout(function() { 3143 spinner.$element.removeClass(spinner.className); 3144 delete spinner.timeoutId; 3145 }, spinner.delay); 3146 }; 3147 3148 Spinner.prototype.hide = function() { 3149 var spinner = this; 3150 if (spinner.timeoutId) { 3151 clearTimeout(spinner.timeoutId); 3152 delete spinner.timeoutId; 3153 return; 3154 } 3155 3156 spinner.$element.addClass(spinner.className); 3157 }; 3158 3159 function prefixed(string, isSelector) { 3160 return string.replace(prefixRegex, (isSelector ? ' .' : ' ') + prefix); 3161 } 3162 3163 function selector(string) { 3164 return prefixed(string, true); 3165 } 3166 3167 /** 3168 * jQuery.addClass with auto-prefixing 3169 * @param {jQuery} Element to add class to 3170 * @param {string}
3170 Class name that will be prefixed and added to element 3171 * @return {jQuery} 3172 */ 3173 function addClass($element, className) { 3174 return $element.addClass(prefixed(className)); 3175 } 3176 3177 /** 3178 * jQuery.removeClass with auto-prefixing 3179 * @param {jQuery} Element to remove class from 3180 * @param {string} Class name that will be prefixed and removed from element 3181 * @return {jQuery} 3182 */ 3183 function removeClass($element, className) { 3184 return $element.removeClass(prefixed(className)); 3185 } 3186 3187 /** 3188 * jQuery.toggleClass with auto-prefixing 3189 * @param {jQuery} Element where class will be toggled 3190 * @param {string} Class name that will be prefixed and toggled 3191 * @param {boolean} Optional boolean that determines if class will be added or removed 3192 * @return {jQuery} 3193 */ 3194 function toggleClass($element, className, shouldAdd) { 3195 return $element.toggleClass(prefixed(className), shouldAdd); 3196 } 3197 3198 /** 3199 * Create a new DOM element wrapped in a jQuery object, 3200 * decorated with our custom methods. 3201 * @param {string} className 3202 * @param {string} [tag] 3203 * @return {jQuery} 3204 */ 3205 function dom(className, tag) { 3206 return addClass($(document.createElement(tag || 'div')), className); 3207 } 3208 3209 function isObject(value) { 3210 return typeof value === 'object' && value != null && !isArray(value); 3211 } 3212 3213 function svgDataUri(width, height) { 3214 var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="' + width + '" height="' + height + '"/>'; 3215 return 'data:image/svg+xml;charset=utf-8,' + encodeURI(svg); 3216 } 3217 3218 // Compute some dimensions manually for iOS < 8, because of buggy support for VH. 3219 // Also, Android built-in browser does not support viewport units. 3220 (function() { 3221 var ua = window.navigator.userAgent; 3222 var iOSRegex = /(iPhone|iPad|iPod);[^OS]*OS (\d)/; 3223 var iOSMatches = ua.match(iOSRegex); 3224 var android = ua.indexOf('Android ') > -1 && ua.indexOf('Chrome') === -1; 3225 3226 if (!android && (!iOSMatches || iOSMatches[2] > 7)) { 3227 return; 3228 } 3229 3230 var styleNode = document.createElement('style'); 3231 document.head.appendChild(styleNode); 3232 window.addEventListener('orientationchange', refresh, true); 3233 3234 function refresh() { 3235 var vh = window.innerHeight; 3236 var vw = window.innerWidth; 3237 var content = 3238 '.w-lightbox-content, .w-lightbox-view, .w-lightbox-view:before {' + 3239 'height:' + vh + 'px' + 3240 '}' + 3241 '.w-lightbox-view {' + 3242 'width:' + vw + 'px' + 3243 '}' + 3244 '.w-lightbox-group, .w-lightbox-group .w-lightbox-view, .w-lightbox-group .w-lightbox-view:before {' + 3245 'height:' + (0.86 * vh) + 'px' + 3246 '}' + 3247 '.w-lightbox-image {' + 3248 'max-width:' + vw + 'px;' + 3249 'max-height:' + vh + 'px' + 3250 '}' + 3251 '.w-lightbox-group .w-lightbox-image {' + 3252 'max-height:' + (0.86 * vh) + 'px' + 3253 '}' + 3254 '.w-lightbox-strip {' + 3255 'padding: 0 ' + (0.01 * vh) + 'px' + 3256 '}' + 3257 '.w-lightbox-item {' + 3258 'width:' + (0.1 * vh) + 'px;' + 3259 'padding:' + (0.02 * vh) + 'px ' + (0.01 * vh) + 'px' + 3260 '}' +
3261 '.w-lightbox-thumbnail {' + 3262 'height:' + (0.1 * vh) + 'px' + 3263 '}' + 3264 '@media (min-width: 768px) {' + 3265 '.w-lightbox-content, .w-lightbox-view, .w-lightbox-view:before {' + 3266 'height:' + (0.96 * vh) + 'px' + 3267 '}' + 3268 '.w-lightbox-content {' + 3269 'margin-top:' + (0.02 * vh) + 'px' + 3270 '}' + 3271 '.w-lightbox-group, .w-lightbox-group .w-lightbox-view, .w-lightbox-group .w-lightbox-view:before {' + 3272 'height:' + (0.84 * vh) + 'px' + 3273 '}' + 3274 '.w-lightbox-image {' + 3275 'max-width:' + (0.96 * vw) + 'px;' + 3276 'max-height:' + (0.96 * vh) + 'px' + 3277 '}' + 3278 '.w-lightbox-group .w-lightbox-image {' + 3279 'max-width:' + (0.823 * vw) + 'px;' + 3280 'max-height:' + (0.84 * vh) + 'px' + 3281 '}' + 3282 '}'; 3283 3284 styleNode.textContent = content; 3285 } 3286 3287 refresh(); 3288 })(); 3289 3290 return lightbox; 3291 } 3292 3293 Webflow.define('lightbox', module.exports = function($, _) { 3294 var api = {}; 3295 var lightbox = createLightbox(window, document, $); 3296 var $doc = $(document); 3297 var $body; 3298 var $lightboxes; 3299 var designer; 3300 var inApp = Webflow.env(); 3301 var namespace = '.w-lightbox'; 3302 var groups; 3303 3304 // ----------------------------------- 3305 // Module methods 3306 3307 api.ready = api.design = api.preview = init; 3308 3309 // ----------------------------------- 3310 // Private methods 3311 3312 function init() { 3313 designer = inApp && Webflow.env('design'); 3314 $body = $(document.body); 3315 3316 // Reset Lightbox 3317 lightbox.destroy(); 3318 3319 // Reset groups 3320 groups = {}; 3321 3322 // Find all instances on the page 3323 $lightboxes = $doc.find(namespace); 3324 3325 // Instantiate all lighboxes 3326 $lightboxes.webflowLightBox(); 3327 } 3328 3329 jQuery.fn.extend({ 3330 webflowLightBox: function() { 3331 var $el = this; 3332 $.each($el, function(i, el) { 3333 // Store state in data 3334 var data = $.data(el, namespace); 3335 if (!data) { 3336 data = $.data(el, namespace, { 3337 el: $(el), 3338 mode: 'images', 3339 images: [], 3340 embed: '' 3341 }); 3342 } 3343 3344 // Remove old events 3345 data.el.off(namespace); 3346 3347 // Set config from json script tag 3348 configure(data); 3349 3350 // Add events based on mode 3351 if (designer) { 3352 data.el.on('setting' + namespace, configure.bind(null, data)); 3353 } else { 3354 data.el 3355 .on('tap' + namespace, tapHandler(data)) 3356 // Prevent page scrolling to top when clicking on lightbox triggers. 3357 .on('click' + namespace, function(e) { 3358 e.preventDefault(); 3359 }); 3360 } 3361 }); 3362 } 3363 }); 3364 3365 function configure(data) { 3366 var json = data.el.children('.w-json').html(); 3367 var groupName, groupItems; 3368 3369 if (!json) { 3370 data.items = []; 3371 return; 3372 } 3373 3374 try { 3375 json = JSON.parse(json); 3376 } catch (e) { 3377 console.error('Malformed lightbox JSON configuration.', e); 3378 } 3379 3380 supportOldLightboxJson(json); 3381 3382 groupName = json.group; 3383 3384 if (groupName) { 3385 groupItems = groups[groupName]; 3386 if (!groupItems) { 3387 groupItems = groups[groupName] = []; 3388 } 3389 3390 data.items = groupItems; 3391 3392 if (json.items.length) { 3393 data.index = groupItems.length; 3394 groupItems.push.apply(groupItems, json.items); 3395 } 3396 } else { 3397 data.items = json.items; 3398 } 3399 } 3400 3401 function tapHandler(data) { 3402 return function() { 3403 data.items.length && lightbox(data.items, data.index || 0); 3404 }; 3405 } 3406 3407 function supportOldLightboxJson(data) { 3408 if (data.images) {
3409 data.images.forEach(function(item) { 3410 item.type = 'image'; 3411 }); 3412 data.items = data.images; 3413 } 3414 3415 if (data.embed) { 3416 data.embed.type = 'video'; 3417 data.items = [data.embed]; 3418 } 3419 3420 if (data.groupId) { 3421 data.group = data.groupId; 3422 } 3423 } 3424 3425 // Export module 3426 return api; 3427 }); 3428 3429 3430 /***/ 3431 }, 3432 /* 14 */ 3433 /***/ 3434 function(module, exports, __webpack_require__) { 3435 3436 'use strict'; 3437 3438 /** 3439 * Webflow: Auto-select links to current page or section 3440 */ 3441 3442 var Webflow = __webpack_require__(1); 3443 3444 Webflow.define('links', module.exports = function($, _) { 3445 var api = {}; 3446 var $win = $(window); 3447 var designer; 3448 var inApp = Webflow.env(); 3449 var location = window.location; 3450 var tempLink = document.createElement('a'); 3451 var linkCurrent = 'w--current'; 3452 var validHash = /^#[a-zA-Z][\w:.-]*$/; 3453 var indexPage = /index\.(html|php)$/; 3454 var dirList = /\/$/; 3455 var anchors; 3456 var slug; 3457 3458 // ----------------------------------- 3459 // Module methods 3460 3461 api.ready = api.design = api.preview = init; 3462 3463 // ----------------------------------- 3464 // Private methods 3465 3466 function init() { 3467 designer = inApp && Webflow.env('design'); 3468 slug = Webflow.env('slug') || location.pathname || ''; 3469 3470 // Reset scroll listener, init anchors 3471 Webflow.scroll.off(scroll); 3472 anchors = []; 3473 3474 // Test all links for a selectable href 3475 var links = document.links; 3476 for (var i = 0; i < links.length; ++i) { 3477 select(links[i]); 3478 } 3479 3480 // Listen for scroll if any anchors exist 3481 if (anchors.length) { 3482 Webflow.scroll.on(scroll); 3483 scroll(); 3484 } 3485 } 3486 3487 function select(link) { 3488 var href = (designer && link.getAttribute('href-disabled')) || link.getAttribute('href'); 3489 tempLink.href = href; 3490 3491 // Ignore any hrefs with a colon to safely avoid all uri schemes 3492 if (href.indexOf(':') >= 0) return; 3493 3494 var $link = $(link); 3495 3496 // Check for valid hash links w/ sections and use scroll anchor 3497 if (href.indexOf('#') === 0 && validHash.test(href)) { 3498 var $section = $(href); 3499 $section.length && anchors.push({ 3500 link: $link, 3501 sec: $section, 3502 active: false 3503 }); 3504 return; 3505 } 3506 3507 // Ignore empty # links 3508 if (href === '#') return; 3509 3510 // Determine whether the link should be selected 3511 var match = (tempLink.href === location.href) || (href === slug) || (indexPage.test(href) && dirList.test(slug)); 3512 setClass($link, linkCurrent, match); 3513 } 3514 3515 function scroll() { 3516 var viewTop = $win.scrollTop(); 3517 var viewHeight = $win.height(); 3518 3519 // Check each anchor for a section in view 3520 _.each(anchors, function(anchor) { 3521 var $link = anchor.link; 3522 var $section = anchor.sec; 3523 var top = $section.offset().top; 3524 var height = $section.outerHeight(); 3525 var offset = viewHeight * 0.5; 3526 var active = ($section.is(':visible') && 3527 top + height - offset >= viewTop && 3528 top + offset <= viewTop + viewHeight); 3529 if (anchor.active === active) return; 3530 anchor.active = active; 3531 setClass($link, linkCurrent, active); 3532 if (designer) $link[0].__wf_current = active; 3533 }); 3534 } 3535 3536 function setClass($elem, className, add) { 3537 var exists = $elem.hasClass(className); 3538 if (add && exists) return; 3539 if (!add && !exists) return; 3540 add ? $elem.addClass(className) : $elem.removeClass(className); 3541 } 3542 3543 // Export module 3544 return api; 3545 }); 3546 3547 3548 /***/ 3549 }, 3550 /* 15 */ 3551 /***/ 3552 function(module, exports, __webpack_require__) { 3553 3554 'use strict'; 3555 3556 /** 3557 * Webflow: Maps widget 3558 */ 3559 3560 var Webflow = __webpack_require__(1); 3561 3562 Webflow.define('maps', module.exports = function($, _) { 3563 var api = {}; 3564 var $doc = $(document); 3565 var google = null; 3566 var $maps; 3567 var namespace = '.w-widget-map'; 3568 3569 // ----------------------------------- 3570 // Module methods 3571 3572 api.ready = function() { 3573 // Init Maps on the front-end 3574 if (!Webflow.env()) initMaps(); 3575 }; 3576 3577 api.preview = function() { 3578 // Update active map nodes 3579 $maps = $doc.find(namespace); 3580 // Listen for resize events 3581 Webflow.resize.off(triggerRedraw); 3582 if ($maps.length) { 3583 Webflow.resize.on(triggerRedraw); 3584 triggerRedraw(); 3585 } 3586 }; 3587 3588 api.design = function(evt) { 3589 // Update active map nodes 3590 $maps = $doc.find(namespace); 3591 // Stop listening for resize events 3592 Webflow.resize.off(triggerRedraw); 3593 // Redraw to account for page changes 3594 $maps.length && _.defer(triggerRedraw); 3595 }; 3596 3597 api.destroy = removeListeners; 3598 3599 // ----------------------------------- 3600 // Private methods 3601 3602 // Trigger redraw in designer or preview mode 3603 function triggerRedraw() { 3604 if ($maps.length && Webflow.app) { 3605 $maps.each(Webflow.app.redrawElement); 3606 } 3607 } 3608 3609 function initMaps() { 3610 $maps = $doc.find(namespace); 3611 if (!$maps.length) return; 3612 3613 if (google === null) {
3614 $.getScript('https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&callback=_wf_maps_loaded'); 3615 window._wf_maps_loaded = mapsLoaded; 3616 } else { 3617 mapsLoaded(); 3618 } 3619 3620 function mapsLoaded() { 3621 window._wf_maps_loaded = function() {}; 3622 google = window.google; 3623 $maps.each(renderMap); 3624 removeListeners(); 3625 addListeners(); 3626 } 3627 } 3628 3629 function removeListeners() { 3630 Webflow.resize.off(resizeMaps); 3631 Webflow.redraw.off(resizeMaps); 3632 } 3633 3634 function addListeners() { 3635 Webflow.resize.on(resizeMaps); 3636 Webflow.redraw.on(resizeMaps); 3637 } 3638 3639 // Render map onto each element 3640 function renderMap(i, el) { 3641 var data = $(el).data(); 3642 getState(el, data); 3643 } 3644 3645 function resizeMaps() { 3646 $maps.each(resizeMap); 3647 } 3648 3649 // Resize map when window changes 3650 function resizeMap(i, el) { 3651 var state = getState(el); 3652 google.maps.event.trigger(state.map, 'resize'); 3653 state.setMapPosition(); 3654 } 3655 3656 // Store state on element data 3657 var store = 'w-widget-map'; 3658 3659 function getState(el, data) { 3660 3661 var state = $.data(el, store); 3662 if (state) return state; 3663 3664 var $el = $(el); 3665 state = $.data(el, store, { 3666 // Default options 3667 latLng: '51.511214,-0.119824', 3668 tooltip: '', 3669 style: 'roadmap', 3670 zoom: 12, 3671 3672 // Marker 3673 marker: new google.maps.Marker({ 3674 draggable: false 3675 }), 3676 3677 // Tooltip infowindow 3678 infowindow: new google.maps.InfoWindow({ 3679 disableAutoPan: true 3680 }) 3681 }); 3682 3683 // LatLng center point 3684 var latLng = data.widgetLatlng || state.latLng; 3685 state.latLng = latLng; 3686 var coords = latLng.split(','); 3687 var latLngObj = new google.maps.LatLng(coords[0], coords[1]); 3688 state.latLngObj = latLngObj; 3689 3690 // Disable touch events 3691 var mapDraggable = (Webflow.env.touch && data.disableTouch) ? false : true; 3692 3693 // Map instance 3694 state.map = new google.maps.Map(el, { 3695 center: state.latLngObj, 3696 zoom: state.zoom, 3697 maxZoom: 18, 3698 mapTypeControl: false, 3699 panControl: false, 3700 streetViewControl: false, 3701 scrollwheel: !data.disableScroll, 3702 draggable: mapDraggable, 3703 zoomControl: true, 3704 zoomControlOptions: { 3705 style: google.maps.ZoomControlStyle.SMALL 3706 }, 3707 mapTypeId: state.style 3708 }); 3709 state.marker.setMap(state.map); 3710 3711 // Set map position and offset 3712 state.setMapPosition = function() { 3713 state.map.setCenter(state.latLngObj); 3714 var offsetX = 0; 3715 var offsetY = 0; 3716 var padding = $el.css(['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft']); 3717 offsetX -= parseInt(padding.paddingLeft, 10); 3718 offsetX += parseInt(padding.paddingRight, 10); 3719 offsetY -= parseInt(padding.paddingTop, 10); 3720 offsetY += parseInt(padding.paddingBottom, 10); 3721 if (offsetX || offsetY) { 3722 state.map.panBy(offsetX, offsetY); 3723 } 3724 $el.css('position', ''); // Remove injected position 3725 }; 3726 3727 // Fix position after first tiles have loaded 3728 google.maps.event.addListener(state.map, 'tilesloaded', function() { 3729 google.maps.event.clearListeners(state.map, 'tilesloaded'); 3730 state.setMapPosition(); 3731 }); 3732 3733 // Set initial position 3734 state.setMapPosition(); 3735 state.marker.setPosition(state.latLngObj); 3736 state.infowindow.setPosition(state.latLngObj); 3737 3738 // Draw tooltip 3739 var tooltip = data.widgetTooltip; 3740 if (tooltip) { 3741 state.tooltip = tooltip; 3742 state.infowindow.setContent(tooltip); 3743 if (!state.infowindowOpen) { 3744 state.infowindow.open(state.map, state.marker); 3745 state.infowindowOpen = true; 3746 } 3747 } 3748 3749 // Map style - options.style 3750 var style = data.widgetStyle; 3751 if (style) { 3752 state.map.setMapTypeId(style); 3753 } 3754 3755 // Zoom - options.zoom 3756 var zoom = data.widgetZoom; 3757 if (zoom != null) { 3758 state.zoom = zoom; 3759 state.map.setZoom(+zoom); 3760 } 3761 3762 // Click marker to open in google maps 3763 google.maps.event.addListener(state.marker, 'click', function() { 3764 window.open('https://maps.google.com/?z=' + state.zoom + '&daddr=' + state.latLng); 3765 }); 3766 3767 return state; 3768 } 3769 3770 // Export module 3771 return api; 3772 }); 3773 3774 3775 /***/ 3776 }, 3777 /* 16 */ 3778 /***/ 3779 function(module, exports, __webpack_require__) { 3780 3781 'use strict'; 3782 3783 /** 3784 * Webflow: Navbar component 3785 */ 3786 3787 var Webflow = __webpack_require__(1); 3788 var IXEvents = __webpack_require__(2); 3789 3790 Webflow.define('navbar', module.exports = function($, _) { 3791 var api = {}; 3792 var tram = $.tram; 3793 var $win = $(window); 3794 var $doc = $(document); 3795 var $body;
3796 var $navbars; 3797 var designer; 3798 var inApp = Webflow.env(); 3799 var overlay = '<div class="w-nav-overlay" data-wf-ignore />'; 3800 var namespace = '.w-nav'; 3801 var buttonOpen = 'w--open'; 3802 var menuOpen = 'w--nav-menu-open'; 3803 var linkOpen = 'w--nav-link-open'; 3804 var ix = IXEvents.triggers; 3805 var menuSibling = $(); 3806 3807 // ----------------------------------- 3808 // Module methods 3809 3810 api.ready = api.design = api.preview = init; 3811 3812 api.destroy = function() { 3813 menuSibling = $(); 3814 removeListeners(); 3815 if ($navbars && $navbars.length) { 3816 $navbars.each(teardown); 3817 } 3818 }; 3819 3820 // ----------------------------------- 3821 // Private methods 3822 3823 function init() { 3824 designer = inApp && Webflow.env('design'); 3825 $body = $(document.body); 3826 3827 // Find all instances on the page 3828 $navbars = $doc.find(namespace); 3829 if (!$navbars.length) return; 3830 $navbars.each(build); 3831
3832 // Wire events 3833 removeListeners(); 3834 addListeners(); 3835 } 3836 3837 function removeListeners() { 3838 Webflow.resize.off(resizeAll); 3839 } 3840 3841 function addListeners() { 3842 Webflow.resize.on(resizeAll); 3843 } 3844 3845 function resizeAll() { 3846 $navbars.each(resize); 3847 } 3848 3849 function build(i, el) { 3850 var $el = $(el); 3851 3852 // Store state in data 3853 var data = $.data(el, namespace); 3854 if (!data) data = $.data(el, namespace, { 3855 open: false, 3856 el: $el, 3857 config: {} 3858 }); 3859 data.menu = $el.find('.w-nav-menu'); 3860 data.links = data.menu.find('.w-nav-link'); 3861 data.dropdowns = data.menu.find('.w-dropdown'); 3862 data.button = $el.find('.w-nav-button'); 3863 data.container = $el.find('.w-container'); 3864 data.outside = outside(data); 3865 3866 // Remove old events 3867 data.el.off(namespace); 3868 data.button.off(namespace); 3869 data.menu.off(namespace); 3870 3871 // Set config from data attributes 3872 configure(data); 3873 3874 // Add events based on mode 3875 if (designer) { 3876 removeOverlay(data); 3877 data.el.on('setting' + namespace, handler(data)); 3878 } else { 3879 addOverlay(data); 3880 data.button.on('tap' + namespace, toggle(data)); 3881 data.menu.on('click' + namespace, 'a', navigate(data)); 3882 } 3883 3884 // Trigger initial resize 3885 resize(i, el); 3886 } 3887 3888 function teardown(i, el) { 3889 var data = $.data(el, namespace); 3890 if (data) { 3891 removeOverlay(data); 3892 $.removeData(el, namespace); 3893 } 3894 } 3895 3896 function removeOverlay(data) { 3897 if (!data.overlay) return; 3898 close(data, true); 3899 data.overlay.remove(); 3900 data.overlay = null; 3901 } 3902 3903 function addOverlay(data) { 3904 if (data.overlay) return; 3905 data.overlay = $(overlay).appendTo(data.el); 3906 data.parent = data.menu.parent(); 3907 close(data, true); 3908 } 3909 3910 function configure(data) { 3911 var config = {}; 3912 var old = data.config || {}; 3913 3914 // Set config options from data attributes 3915 var animation = config.animation = data.el.attr('data-animation') || 'default'; 3916 config.animOver = /^over/.test(animation); 3917 config.animDirect = /left$/.test(animation) ? -1 : 1; 3918 3919 // Re-open menu if the animation type changed 3920 if (old.animation !== animation) { 3921 data.open && _.defer(reopen, data); 3922 } 3923 3924 config.easing = data.el.attr('data-easing') || 'ease'; 3925 config.easing2 = data.el.attr('data-easing2') || 'ease'; 3926 3927 var duration = data.el.attr('data-duration'); 3928 config.duration = duration != null ? Number(duration) : 400; 3929 3930 config.docHeight = data.el.attr('data-doc-height'); 3931 3932 // Store config in data 3933 data.config = config; 3934 } 3935 3936 function handler(data) { 3937 return function(evt, options) { 3938 options = options || {}; 3939 var winWidth = $win.width(); 3940 configure(data); 3941 options.open === true && open(data, true); 3942 options.open === false && close(data, true); 3943 // Reopen if media query changed after setting 3944 data.open && _.defer(function() { 3945 if (winWidth !== $win.width()) reopen(data); 3946 }); 3947 }; 3948 } 3949 3950 function reopen(data) { 3951 if (!data.open) return; 3952 close(data, true); 3953 open(data, true); 3954 } 3955 3956 function toggle(data) { 3957 // Debounce toggle to wait for accurate open state 3958 return _.debounce(function() { 3959 data.open ? close(data) : open(data); 3960 }); 3961 } 3962 3963 function navigate(data) { 3964 return function(evt) { 3965 var link = $(this); 3966 var href = link.attr('href'); 3967 3968 // Avoid late clicks on touch devices 3969 if (!Webflow.validClick(evt.currentTarget)) { 3970 evt.preventDefault(); 3971 return; 3972 } 3973 3974 // Close when navigating to an in-page anchor 3975 if (href && href.indexOf('#') === 0 && data.open) { 3976 close(data); 3977 } 3978 }; 3979 } 3980 3981 function outside(data) { 3982 // Unbind previous tap handler if it exists 3983 if (data.outside) $doc.off('tap' + namespace, data.outside); 3984 3985 // Close menu when tapped outside, debounced to wait for state 3986 return _.debounce(function(evt) { 3987 if (!data.open) return; 3988 var menu = $(evt.target).closest('.w-nav-menu'); 3989 if (!data.menu.is(menu)) { 3990 close(data); 3991 } 3992 }); 3993 } 3994 3995 function resize(i, el) { 3996 var data = $.data(el, namespace);
3997 // Check for collapsed state based on button display 3998 var collapsed = data.collapsed = data.button.css('display') !== 'none'; 3999 // Close menu if button is no longer visible (and not in designer) 4000 if (data.open && !collapsed && !designer) close(data, true); 4001 // Set max-width of links + dropdowns to match container 4002 if (data.container.length) { 4003 var updateEachMax = updateMax(data); 4004 data.links.each(updateEachMax); 4005 data.dropdowns.each(updateEachMax); 4006 } 4007 // If currently open, update height to match body 4008 if (data.open) { 4009 setOverlayHeight(data); 4010 } 4011 } 4012 4013 var maxWidth = 'max-width'; 4014 4015 function updateMax(data) { 4016 // Set max-width of each element to match container 4017 var containMax = data.container.css(maxWidth); 4018 if (containMax === 'none') containMax = ''; 4019 return function(i, link) { 4020 link = $(link); 4021 link.css(maxWidth, ''); 4022 // Don't set the max-width if an upstream value exists 4023 if (link.css(maxWidth) === 'none') link.css(maxWidth, containMax); 4024 }; 4025 } 4026 4027 function open(data, immediate) { 4028 if (data.open) return; 4029 data.open = true; 4030 data.menu.addClass(menuOpen); 4031 data.links.addClass(linkOpen); 4032 data.button.addClass(buttonOpen); 4033 var config = data.config; 4034 var animation = config.animation; 4035 if (animation === 'none' || !tram.support.transform) immediate = true; 4036 var bodyHeight = setOverlayHeight(data); 4037 var menuHeight = data.menu.outerHeight(true); 4038 var menuWidth = data.menu.outerWidth(true); 4039 var navHeight = data.el.height(); 4040 var navbarEl = data.el[0]; 4041 resize(0, navbarEl); 4042 ix.intro(0, navbarEl); 4043 Webflow.redraw.up(); 4044 4045 // Listen for tap outside events 4046 if (!designer) $doc.on('tap' + namespace, data.outside); 4047 4048 // No transition for immediate 4049 if (immediate) return; 4050 4051 var transConfig = 'transform ' + config.duration + 'ms ' + config.easing; 4052 4053 // Add menu to overlay 4054 if (data.overlay) { 4055 menuSibling = data.menu.prev(); 4056 data.overlay.show().append(data.menu); 4057 } 4058 4059 // Over left/right 4060 if (config.animOver) { 4061 tram(data.menu) 4062 .add(transConfig) 4063 .set({ 4064 x: config.animDirect * menuWidth, 4065 height: bodyHeight 4066 }).start({ 4067 x: 0 4068 }); 4069 data.overlay && data.overlay.width(menuWidth); 4070 return; 4071 } 4072 4073 // Drop Down 4074 var offsetY = navHeight + menuHeight; 4075 tram(data.menu) 4076 .add(transConfig) 4077 .set({ 4078 y: -offsetY 4079 }).start({ 4080 y: 0 4081 }); 4082 } 4083 4084 function setOverlayHeight(data) { 4085 var config = data.config; 4086 var bodyHeight = config.docHeight ? $doc.height() : $body.height(); 4087 if (config.animOver) { 4088 data.menu.height(bodyHeight); 4089 } else if (data.el.css('position') !== 'fixed') { 4090 bodyHeight -= data.el.height(); 4091 } 4092 data.overlay && data.overlay.height(bodyHeight); 4093 return bodyHeight; 4094 } 4095 4096 function close(data, immediate) { 4097 if (!data.open) return; 4098 data.open = false;
4099 data.button.removeClass(buttonOpen); 4100 var config = data.config; 4101 if (config.animation === 'none' || !tram.support.transform) immediate = true; 4102 ix.outro(0, data.el[0]); 4103 4104 // Stop listening for tap outside events 4105 $doc.off('tap' + namespace, data.outside); 4106 4107 if (immediate) { 4108 tram(data.menu).stop(); 4109 complete(); 4110 return; 4111 } 4112 4113 var transConfig = 'transform ' + config.duration + 'ms ' + config.easing2; 4114 var menuHeight = data.menu.outerHeight(true); 4115 var menuWidth = data.menu.outerWidth(true); 4116 var navHeight = data.el.height(); 4117 4118 // Over left/right 4119 if (config.animOver) { 4120 tram(data.menu) 4121 .add(transConfig) 4122 .start({ 4123 x: menuWidth * config.animDirect 4124 }).then(complete); 4125 return; 4126 } 4127 4128 // Drop Down 4129 var offsetY = navHeight + menuHeight; 4130 tram(data.menu) 4131 .add(transConfig) 4132 .start({ 4133 y: -offsetY 4134 }).then(complete); 4135 4136 function complete() { 4137 data.menu.height(''); 4138 tram(data.menu).set({ 4139 x: 0, 4140 y: 0 4141 }); 4142 data.menu.removeClass(menuOpen); 4143 data.links.removeClass(linkOpen); 4144 if (data.overlay && data.overlay.children().length) { 4145 // Move menu back to parent at the original location 4146 menuSibling.length ? data.menu.insertAfter(menuSibling) : data.menu.prependTo(data.parent); 4147 data.overlay.attr('style', '').hide(); 4148 } 4149 4150 // Trigger event so other components can hook in (dropdown) 4151 data.el.triggerHandler('w-close'); 4152 } 4153 } 4154 4155 // Export module 4156 return api; 4157 }); 4158 4159 4160 /***/ 4161 }, 4162 /* 17 */ 4163 /***/ 4164 function(module, exports, __webpack_require__) { 4165 4166 'use strict'; 4167 4168 /** 4169 * Webflow: Smooth scroll 4170 */ 4171 4172 var Webflow = __webpack_require__(1); 4173 4174 Webflow.define('scroll', module.exports = function($, _) { 4175 var $doc = $(document); 4176 var win = window; 4177 var loc = win.location; 4178 var history = inIframe() ? null : win.history; 4179 var validHash = /^[a-zA-Z0-9][\w:.-]*$/; 4180 4181 function inIframe() { 4182 try { 4183 return !!win.frameElement; 4184 } catch (e) { 4185 return true; 4186 } 4187 } 4188 4189 function ready() { 4190 // If hash is already present on page load, scroll to it right away 4191 if (loc.hash) { 4192 findEl(loc.hash.substring(1)); 4193 } 4194 4195 // The current page url without the hash part. 4196 var locHref = loc.href.split('#')[0]; 4197 4198 // When clicking on a link, check if it links to another part of the page 4199 $doc.on('click', 'a', function(e) { 4200 if (Webflow.env('design')) { 4201 return; 4202 } 4203 4204 // Ignore links being used by jQuery mobile 4205 if (window.$.mobile && $(e.currentTarget).hasClass('ui-link')) return; 4206 4207 // Ignore empty # links 4208 if (this.getAttribute('href') === '#') { 4209 e.preventDefault(); 4210 return; 4211 } 4212 4213 // The href property always contains the full url so we can compare 4214 // with the documentâs location to only target links on this page. 4215 var parts = this.href.split('#'); 4216 var hash = parts[0] === locHref ? parts[1] : null; 4217 if (hash) { 4218 findEl(hash, e); 4219 } 4220 }); 4221 } 4222 4223 function findEl(hash, e) { 4224 if (!validHash.test(hash)) return; 4225 4226 var el = $('#' + hash); 4227 if (!el.length) { 4228 return; 4229 } 4230 4231 if (e) { 4232 e.preventDefault(); 4233 e.stopPropagation(); 4234 } 4235 4236 // Push new history state 4237 if ( 4238 loc.hash !== hash && 4239 history && history.pushState && 4240 // Navigation breaks Chrome when the protocol is `file:`. 4241 !(Webflow.env.chrome && loc.protocol === 'file:') 4242 ) { 4243 var oldHash = history.state && history.state.hash; 4244 if (oldHash !== hash) { 4245 history.pushState({ 4246 hash: hash 4247 }, '', '#' + hash); 4248 } 4249 } 4250 4251 // If a fixed header exists, offset for the height 4252 var rootTag = Webflow.env('editor') ? '.w-editor-body' : 'body'; 4253 var header = $('header, ' + rootTag + ' > .header, ' + rootTag + ' > .w-nav:not([data-no-scroll])'); 4254 var offset = header.css('position') === 'fixed' ? header.outerHeight() : 0; 4255 4256 win.setTimeout(function() { 4257 scroll(el, offset); 4258 }, e ? 0 : 300); 4259 } 4260 4261 function scroll(el, offset) { 4262 var start = $(win).scrollTop(); 4263 var end = el.offset().top - offset; 4264 4265 // If specified, scroll so that the element ends up in the middle of the viewport 4266 if (el.data('scroll') === 'mid') { 4267 var available = $(win).height() - offset; 4268 var elHeight = el.outerHeight(); 4269 if (elHeight < available) { 4270 end -= Math.round((available - elHeight) / 2); 4271 } 4272 } 4273 4274 var mult = 1; 4275 4276 // Check for custom time multiplier on the body and the element 4277 $('body').add(el).each(function(i) { 4278 var time = parseFloat($(this).attr('data-scroll-time'), 10); 4279 if (!isNaN(time) && (time === 0 || time > 0)) { 4280 mult = time; 4281 } 4282 }); 4283 4284 // Shim for IE8 and below 4285 if (!Date.now) { 4286 Date.now = function() { 4287 return new Date().getTime(); 4288 }; 4289 } 4290 4291 var clock = Date.now(); 4292 var animate = win.requestAnimationFrame || win.mozRequestAnimationFrame || win.webkitRequestAnimationFrame || function(fn) { 4293 win.setTimeout(fn, 15); 4294 }; 4295 var duration = (472.143 * Math.log(Math.abs(start - end) + 125) - 2000) * mult; 4296 4297 var step = function() {
4298 var elapsed = Date.now() - clock; 4299 win.scroll(0, getY(start, end, elapsed, duration)); 4300 4301 if (elapsed <= duration) { 4302 animate(step); 4303 } 4304 }; 4305 4306 step(); 4307 } 4308 4309 function getY(start, end, elapsed, duration) { 4310 if (elapsed > duration) { 4311 return end; 4312 } 4313 4314 return start + (end - start) * ease(elapsed / duration); 4315 } 4316 4317 function ease(t) { 4318 return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1; 4319 } 4320 4321 // Export module 4322 return { 4323 ready: ready 4324 }; 4325 }); 4326 4327 4328 /***/ 4329 }, 4330 /* 18 */ 4331 /***/ 4332 function(module, exports, __webpack_require__) { 4333 4334 'use strict'; 4335 4336 /** 4337 * Webflow: Slider component 4338 */ 4339 4340 var Webflow = __webpack_require__(1); 4341 var IXEvents = __webpack_require__(2); 4342 4343 Webflow.define('slider', module.exports = function($, _) { 4344 var api = {}; 4345 var tram = $.tram; 4346 var $doc = $(document); 4347 var $sliders; 4348 var designer; 4349 var inApp = Webflow.env(); 4350 var namespace = '.w-slider'; 4351 var dot = '<div class="w-slider-dot" data-wf-ignore />'; 4352 var ix = IXEvents.triggers; 4353 var fallback; 4354 var inRedraw; 4355 4356 // ----------------------------------- 4357 // Module methods 4358 4359 api.ready = function() { 4360 init(); 4361 }; 4362 4363 api.design = function() { 4364 designer = true; 4365 init(); 4366 }; 4367 4368 api.preview = function() { 4369 designer = false;
4370 init(); 4371 }; 4372 4373 api.redraw = function() { 4374 inRedraw = true; 4375 init(); 4376 }; 4377 4378 api.destroy = removeListeners; 4379 4380 // ----------------------------------- 4381 // Private methods 4382 4383 function init() { 4384 // Find all sliders on the page 4385 $sliders = $doc.find(namespace); 4386 if (!$sliders.length) return; 4387 $sliders.filter(':visible').each(build); 4388 inRedraw = null; 4389 if (fallback) return; 4390 4391 removeListeners(); 4392 addListeners(); 4393 } 4394 4395 function removeListeners() { 4396 Webflow.resize.off(renderAll); 4397 Webflow.redraw.off(api.redraw); 4398 } 4399 4400 function addListeners() { 4401 Webflow.resize.on(renderAll); 4402 Webflow.redraw.on(api.redraw); 4403 } 4404 4405 function renderAll() { 4406 $sliders.filter(':visible').each(render); 4407 } 4408 4409 function build(i, el) { 4410 var $el = $(el); 4411 4412 // Store slider state in data 4413 var data = $.data(el, namespace); 4414 if (!data) { 4415 data = $.data(el, namespace, { 4416 index: 0, 4417 depth: 1, 4418 el: $el, 4419 config: {} 4420 }); 4421 } 4422 data.mask = $el.children('.w-slider-mask'); 4423 data.left = $el.children('.w-slider-arrow-left'); 4424 data.right = $el.children('.w-slider-arrow-right'); 4425 data.nav = $el.children('.w-slider-nav'); 4426 data.slides = data.mask.children('.w-slide'); 4427 data.slides.each(ix.reset); 4428 if (inRedraw) data.maskWidth = 0; 4429 4430 // Disable in old browsers 4431 if (!tram.support.transform) { 4432 data.left.hide(); 4433 data.right.hide(); 4434 data.nav.hide(); 4435 fallback = true; 4436 return; 4437 } 4438 4439 // Remove old events 4440 data.el.off(namespace); 4441 data.left.off(namespace); 4442 data.right.off(namespace); 4443 data.nav.off(namespace); 4444 4445 // Set config from data attributes 4446 configure(data); 4447 4448 // Add events based on mode 4449 if (designer) { 4450 data.el.on('setting' + namespace, handler(data)); 4451 stopTimer(data); 4452 data.hasTimer = false; 4453 } else { 4454 data.el.on('swipe' + namespace, handler(data)); 4455 data.left.on('tap' + namespace, previousFunction(data)); 4456 data.right.on('tap' + namespace, next(data)); 4457 4458 // Start timer if autoplay is true, only once 4459 if (data.config.autoplay && !data.hasTimer) { 4460 data.hasTimer = true; 4461 data.timerCount = 1; 4462 startTimer(data); 4463 } 4464 } 4465 4466 // Listen to nav events 4467 data.nav.on('tap' + namespace, '> div', handler(data)); 4468 4469 // Remove gaps from formatted html (for inline-blocks) 4470 if (!inApp) { 4471 data.mask.contents().filter(function() { 4472 return this.nodeType === 3; 4473 }).remove(); 4474 } 4475 4476 // Run first render 4477 render(i, el); 4478 } 4479 4480 function configure(data) { 4481 var config = {}; 4482 4483 config.crossOver = 0; 4484 4485 // Set config options from data attributes 4486 config.animation = data.el.attr('data-animation') || 'slide'; 4487 if (config.animation === 'outin') { 4488 config.animation = 'cross'; 4489 config.crossOver = 0.5; 4490 } 4491 config.easing = data.el.attr('data-easing') || 'ease'; 4492 4493 var duration = data.el.attr('data-duration'); 4494 config.duration = duration != null ? +duration : 500; 4495 4496 if (+data.el.attr('data-infinite')) config.infinite = true; 4497 if (+data.el.attr('data-disable-swipe')) config.disableSwipe = true; 4498 4499 if (+data.el.attr('data-hide-arrows')) { 4500 config.hideArrows = true; 4501 } else if (data.config.hideArrows) { 4502 data.left.show(); 4503 data.right.show(); 4504 } 4505 4506 if (+data.el.attr('data-autoplay')) {
4507 config.autoplay = true; 4508 config.delay = +data.el.attr('data-delay') || 2000; 4509 config.timerMax = +data.el.attr('data-autoplay-limit'); 4510 // Disable timer on first touch or mouse down 4511 var touchEvents = 'mousedown' + namespace + ' touchstart' + namespace; 4512 if (!designer) { 4513 data.el.off(touchEvents).one(touchEvents, function() { 4514 stopTimer(data); 4515 }); 4516 } 4517 } 4518 4519 // Use edge buffer to help calculate page count 4520 var arrowWidth = data.right.width(); 4521 config.edge = arrowWidth ? arrowWidth + 40 : 100; 4522 4523 // Store config in data 4524 data.config = config; 4525 } 4526 4527 function previousFunction(data) { 4528 return function(evt) { 4529 change(data, { 4530 index: data.index - 1, 4531 vector: -1 4532 }); 4533 }; 4534 } 4535 4536 function next(data) { 4537 return function(evt) { 4538 change(data, { 4539 index: data.index + 1, 4540 vector: 1 4541 }); 4542 }; 4543 } 4544 4545 function select(data, value) { 4546 // Select page based on slide element index 4547 var found = null; 4548 if (value === data.slides.length) { 4549 init(); 4550 layout(data); // Rebuild and find new slides 4551 } 4552 _.each(data.anchors, function(anchor, index) { 4553 $(anchor.els).each(function(i, el) { 4554 if ($(el).index() === value) found = index; 4555 }); 4556 }); 4557 if (found != null) change(data, { 4558 index: found, 4559 immediate: true 4560 }); 4561 } 4562 4563 function startTimer(data) { 4564 stopTimer(data); 4565 var config = data.config; 4566 var timerMax = config.timerMax; 4567 if (timerMax && data.timerCount++ > timerMax) return; 4568 data.timerId = window.setTimeout(function() { 4569 if (data.timerId == null || designer) return; 4570 next(data)(); 4571 startTimer(data); 4572 }, config.delay); 4573 } 4574 4575 function stopTimer(data) { 4576 window.clearTimeout(data.timerId); 4577 data.timerId = null; 4578 } 4579 4580 function handler(data) { 4581 return function(evt, options) { 4582 options = options || {}; 4583 var config = data.config; 4584 4585 // Designer settings 4586 if (designer && evt.type === 'setting') { 4587 if (options.select === 'prev') return previousFunction(data)(); 4588 if (options.select === 'next') return next(data)(); 4589 configure(data); 4590 layout(data); 4591 if (options.select == null) return; 4592 select(data, options.select); 4593 return; 4594 } 4595 4596 // Swipe event 4597 if (evt.type === 'swipe') { 4598 if (config.disableSwipe) return; 4599 if (Webflow.env('editor')) return; 4600 if (options.direction === 'left') return next(data)(); 4601 if (options.direction === 'right') return previousFunction(data)(); 4602 return; 4603 } 4604 4605 // Page buttons 4606 if (data.nav.has(evt.target).length) { 4607 change(data, { 4608 index: $(evt.target).index() 4609 }); 4610 } 4611 }; 4612 } 4613 4614 function change(data, options) { 4615 options = options || {}; 4616 var config = data.config; 4617 var anchors = data.anchors; 4618 4619 // Set new index 4620 data.previous = data.index; 4621 var index = options.index; 4622 var shift = {}; 4623 if (index < 0) { 4624 index = anchors.length - 1; 4625 if (config.infinite) { 4626 // Shift first slide to the end 4627 shift.x = -data.endX; 4628 shift.from = 0; 4629 shift.to = anchors[0].width; 4630 } 4631 } else if (index >= anchors.length) { 4632 index = 0; 4633 if (config.infinite) { 4634 // Shift last slide to the start
4635 shift.x = anchors[anchors.length - 1].width; 4636 shift.from = -anchors[anchors.length - 1].x; 4637 shift.to = shift.from - shift.x; 4638 } 4639 } 4640 data.index = index; 4641 4642 // Select page nav 4643 var active = data.nav.children().eq(data.index).addClass('w-active'); 4644 data.nav.children().not(active).removeClass('w-active'); 4645 4646 // Hide arrows 4647 if (config.hideArrows) { 4648 data.index === anchors.length - 1 ? data.right.hide() : data.right.show(); 4649 data.index === 0 ? data.left.hide() : data.left.show(); 4650 } 4651 4652 // Get page offset from anchors 4653 var lastOffsetX = data.offsetX || 0; 4654 var offsetX = data.offsetX = -anchors[data.index].x; 4655 var resetConfig = { 4656 x: offsetX, 4657 opacity: 1, 4658 visibility: '' 4659 }; 4660 4661 // Transition slides 4662 var targets = $(anchors[data.index].els); 4663 var prevTargs = $(anchors[data.previous] && anchors[data.previous].els); 4664 var others = data.slides.not(targets); 4665 var animation = config.animation; 4666 var easing = config.easing; 4667 var duration = Math.round(config.duration); 4668 var vector = options.vector || (data.index > data.previous ? 1 : -1); 4669 var fadeRule = 'opacity ' + duration + 'ms ' + easing; 4670 var slideRule = 'transform ' + duration + 'ms ' + easing; 4671 4672 // Trigger IX events 4673 if (!designer) { 4674 targets.each(ix.intro); 4675 others.each(ix.outro); 4676 } 4677 4678 // Set immediately after layout changes (but not during redraw) 4679 if (options.immediate && !inRedraw) { 4680 tram(targets).set(resetConfig); 4681 resetOthers(); 4682 return; 4683 } 4684 4685 // Exit early if index is unchanged 4686 if (data.index === data.previous) return; 4687 4688 // Cross Fade / Out-In 4689 if (animation === 'cross') { 4690 var reduced = Math.round(duration - duration * config.crossOver); 4691 var wait = Math.round(duration - reduced); 4692 fadeRule = 'opacity ' + reduced + 'ms ' + easing; 4693 tram(prevTargs) 4694 .set({ 4695 visibility: '' 4696 }) 4697 .add(fadeRule) 4698 .start({ 4699 opacity: 0 4700 }); 4701 tram(targets) 4702 .set({ 4703 visibility: '', 4704 x: offsetX, 4705 opacity: 0, 4706 zIndex: data.depth++ 4707 }) 4708 .add(fadeRule) 4709 .wait(wait) 4710 .then({ 4711 opacity: 1 4712 }) 4713 .then(resetOthers); 4714 return; 4715 } 4716 4717 // Fade Over 4718 if (animation === 'fade') { 4719 tram(prevTargs) 4720 .set({ 4721 visibility: '' 4722 }) 4723 .stop(); 4724 tram(targets) 4725 .set({ 4726 visibility: '', 4727 x: offsetX, 4728 opacity: 0, 4729 zIndex: data.depth++ 4730 }) 4731 .add(fadeRule) 4732 .start({ 4733 opacity: 1 4734 }) 4735 .then(resetOthers); 4736 return; 4737 } 4738 4739 // Slide Over 4740 if (animation === 'over') { 4741 resetConfig = { 4742 x: data.endX 4743 }; 4744 tram(prevTargs) 4745 .set({ 4746 visibility: '' 4747 }) 4748 .stop(); 4749 tram(targets) 4750 .set({ 4751 visibility: '', 4752 zIndex: data.depth++, 4753 x: offsetX + anchors[data.index].width * vector 4754 }) 4755 .add(slideRule) 4756 .start({ 4757 x: offsetX 4758 }) 4759 .then(resetOthers); 4760 return; 4761 } 4762 4763 // Slide - infinite scroll 4764 if (config.infinite && shift.x) { 4765 tram(data.slides.not(prevTargs)) 4766 .set({ 4767 visibility: '', 4768 x: shift.x 4769 }) 4770 .add(slideRule) 4771 .start({ 4772 x: offsetX 4773 }); 4774 tram(prevTargs) 4775 .set({ 4776 visibility: '', 4777 x: shift.from 4778 }) 4779 .add(slideRule) 4780 .start({ 4781 x: shift.to 4782 }); 4783 data.shifted = prevTargs; 4784 4785 } else { 4786 if (config.infinite && data.shifted) { 4787 tram(data.shifted).set({ 4788 visibility: '', 4789 x: lastOffsetX 4790 }); 4791 data.shifted = null; 4792 } 4793 4794 // Slide - basic scroll 4795 tram(data.slides) 4796 .set({ 4797 visibility: '' 4798 }) 4799 .add(slideRule) 4800 .start({ 4801 x: offsetX 4802 }); 4803 } 4804 4805 // Helper to move others out of view 4806 function resetOthers() { 4807 targets = $(anchors[data.index].els); 4808 others = data.slides.not(targets); 4809 if (animation !== 'slide') resetConfig.visibility = 'hidden'; 4810 tram(others).set(resetConfig); 4811 } 4812 } 4813 4814 function render(i, el) { 4815 var data = $.data(el, namespace); 4816 if (maskChanged(data)) return layout(data); 4817 if (designer && slidesChanged(data)) layout(data); 4818 } 4819 4820 function layout(data) { 4821 // Determine page count from width of slides 4822 var pages = 1; 4823 var offset = 0; 4824 var anchor = 0; 4825 var width = 0; 4826 var maskWidth = data.maskWidth; 4827 var threshold = maskWidth - data.config.edge; 4828 if (threshold < 0) threshold = 0; 4829 data.anchors = [{ 4830 els: [], 4831 x: 0, 4832 width: 0 4833 }]; 4834 data.slides.each(function(i, el) { 4835 if (anchor - offset > threshold) { 4836 pages++; 4837 offset += maskWidth; 4838 // Store page anchor for transition 4839 data.anchors[pages - 1] = { 4840 els: [], 4841 x: anchor, 4842 width: 0 4843 }; 4844 } 4845 // Set next anchor using current width + margin 4846 width = $(el).outerWidth(true); 4847 anchor += width; 4848 data.anchors[pages - 1].width += width; 4849 data.anchors[pages - 1].els.push(el); 4850 }); 4851 data.endX = anchor; 4852 4853 // Build dots if nav exists and needs updating 4854 if (designer) data.pages = null; 4855 if (data.nav.length && data.pages !== pages) { 4856 data.pages = pages; 4857 buildNav(data); 4858 } 4859 4860 // Make sure index is still within range and call change handler 4861 var index = data.index; 4862 if (index >= pages) index = pages - 1; 4863 change(data, { 4864 immediate: true, 4865 index: index 4866 }); 4867 } 4868 4869 function buildNav(data) { 4870 var dots = []; 4871 var $dot; 4872 var spacing = data.el.attr('data-nav-spacing'); 4873 if (spacing) spacing = parseFloat(spacing) + 'px'; 4874 for (var i = 0; i < data.pages; i++) { 4875 $dot = $(dot); 4876 if (data.nav.hasClass('w-num')) $dot.text(i + 1); 4877 if (spacing != null) { 4878 $dot.css({ 4879 'margin-left': spacing, 4880 'margin-right': spacing 4881 }); 4882 } 4883 dots.push($dot); 4884 } 4885 data.nav.empty().append(dots); 4886 } 4887 4888 function maskChanged(data) { 4889 var maskWidth = data.mask.width(); 4890 if (data.maskWidth !== maskWidth) { 4891 data.maskWidth = maskWidth; 4892 return true; 4893 } 4894 return false;
4895 } 4896 4897 function slidesChanged(data) { 4898 var slidesWidth = 0; 4899 data.slides.each(function(i, el) { 4900 slidesWidth += $(el).outerWidth(true); 4901 }); 4902 if (data.slidesWidth !== slidesWidth) { 4903 data.slidesWidth = slidesWidth; 4904 return true; 4905 } 4906 return false; 4907 } 4908 4909 // Export module 4910 return api; 4911 }); 4912 4913 4914 /***/ 4915 }, 4916 /* 19 */ 4917 /***/ 4918 function(module, exports, __webpack_require__) { 4919 4920 'use strict'; 4921 4922 /** 4923 * Webflow: Tabs component 4924 */ 4925 4926 var Webflow = __webpack_require__(1); 4927 var IXEvents = __webpack_require__(2); 4928 4929 Webflow.define('tabs', module.exports = function($, _) { 4930 var api = {}; 4931 var tram = $.tram; 4932 var $win = $(window); 4933 var $doc = $(document); 4934 var $tabs; 4935 var design; 4936 var env = Webflow.env; 4937 var safari = env.safari; 4938 var inApp = env(); 4939 var tabAttr = 'data-w-tab'; 4940 var namespace = '.w-tabs'; 4941 var linkCurrent = 'w--current'; 4942 var tabActive = 'w--tab-active'; 4943 var ix = IXEvents.triggers; 4944 var inRedraw; 4945 4946 // ----------------------------------- 4947 // Module methods 4948 4949 api.ready = api.design = api.preview = init; 4950 4951 api.redraw = function() { 4952 inRedraw = true; 4953 init(); 4954 }; 4955 4956 api.destroy = function() { 4957 $tabs = $doc.find(namespace); 4958 if (!$tabs.length) return; 4959 $tabs.each(resetIX); 4960 removeListeners(); 4961 }; 4962 4963 // ----------------------------------- 4964 // Private methods 4965 4966 function init() { 4967 design = inApp && Webflow.env('design'); 4968 4969 // Find all instances on the page 4970 $tabs = $doc.find(namespace); 4971 if (!$tabs.length) return; 4972 $tabs.each(build); 4973 Webflow.env('preview') && $tabs.each(resetIX); 4974 inRedraw = null; 4975 4976 removeListeners(); 4977 addListeners(); 4978 } 4979 4980 function removeListeners() { 4981 Webflow.redraw.off(api.redraw); 4982 } 4983 4984 function addListeners() { 4985 Webflow.redraw.on(api.redraw); 4986 } 4987 4988 function resetIX(i, el) { 4989 var $el = $(el); 4990 var data = $.data(el, namespace); 4991 if (!data) return; 4992 data.links && data.links.each(ix.reset); 4993 data.panes && data.panes.each(ix.reset); 4994 } 4995 4996 function build(i, el) { 4997 var $el = $(el); 4998 4999 // Store state in data 5000 var data = $.data(el, namespace); 5001 if (!data) data = $.data(el, namespace, { 5002 el: $el, 5003 config: {} 5004 }); 5005 data.current = $el.attr('data-current'); // null 5006 data.menu = $el.children('.w-tab-menu'); 5007 data.links = data.menu.children('.w-tab-link'); 5008 data.content = $el.children('.w-tab-content'); 5009 data.panes = data.content.children('.w-tab-pane'); 5010 5011 // Remove old events 5012 data.el.off(namespace); 5013 data.links.off(namespace); 5014 5015 // Set config from data attributes 5016 configure(data); 5017
5018 // Wire up events when not in design mode 5019 if (!design) { 5020 data.links.on('click' + namespace, linkSelect(data)); 5021 5022 // Trigger first intro event from current tab 5023 var $link = data.links.filter('.' + linkCurrent); 5024 var tab = $link.attr(tabAttr); 5025 tab && changeTab(data, { 5026 tab: tab, 5027 immediate: true 5028 }); 5029 } 5030 } 5031 5032 function configure(data) { 5033 var config = {}; 5034 var old = data.config || {}; 5035 5036 // Set config options from data attributes 5037 config.easing = data.el.attr('data-easing') || 'ease'; 5038 5039 var intro = +data.el.attr('data-duration-in'); 5040 intro = config.intro = intro === intro ? intro : 0; 5041 5042 var outro = +data.el.attr('data-duration-out'); 5043 outro = config.outro = outro === outro ? outro : 0; 5044 5045 config.immediate = !intro && !outro; 5046 5047 // Store config in data 5048 data.config = config; 5049 } 5050 5051 function linkSelect(data) { 5052 return function(evt) { 5053 var tab = evt.currentTarget.getAttribute(tabAttr); 5054 tab && changeTab(data, { 5055 tab: tab 5056 }); 5057 return false; 5058 }; 5059 } 5060 5061 function changeTab(data, options) { 5062 options = options || {}; 5063 5064 var config = data.config; 5065 var easing = config.easing; 5066 var tab = options.tab; 5067 5068 // Don't select the same tab twice 5069 if (tab === data.current) return; 5070 data.current = tab; 5071 5072 // Select the current link 5073 data.links.each(function(i, el) { 5074 var $el = $(el); 5075 if (el.getAttribute(tabAttr) === tab) $el.addClass(linkCurrent).each(ix.intro); 5076 else if ($el.hasClass(linkCurrent)) $el.removeClass(linkCurrent).each(ix.outro); 5077 }); 5078 5079 // Find the new tab panes and keep track of previous 5080 var targets = []; 5081 var previous = []; 5082 data.panes.each(function(i, el) { 5083 var $el = $(el); 5084 if (el.getAttribute(tabAttr) === tab) { 5085 targets.push(el); 5086 } else if ($el.hasClass(tabActive)) { 5087 previous.push(el); 5088 } 5089 }); 5090 5091 var $targets = $(targets); 5092 var $previous = $(previous); 5093 5094 // Switch tabs immediately and bypass transitions 5095 if (options.immediate || config.immediate) { 5096 $targets.addClass(tabActive).each(ix.intro); 5097 $previous.removeClass(tabActive); 5098 // Redraw to benefit components in the hidden tab pane 5099 // But only if not currently in the middle of a redraw 5100 if (!inRedraw) Webflow.redraw.up(); 5101 return; 5102 } 5103 5104 // Fade out the currently active tab before intro 5105 if ($previous.length && config.outro) { 5106 $previous.each(ix.outro); 5107 tram($previous) 5108 .add('opacity ' + config.outro + 'ms ' + easing, { 5109 fallback: safari 5110 }) 5111 .start({ 5112 opacity: 0 5113 }) 5114 .then(intro); 5115 } else { 5116 // Skip the outro and play intro 5117 intro(); 5118 } 5119 5120 // Fade in the new target 5121 function intro() { 5122 // Clear previous active class + styles touched by tram 5123 // We cannot remove the whole inline style because it c
5123ould be dynamically bound 5124 $previous.removeClass(tabActive).css({ 5125 opacity: '', 5126 transition: '', 5127 transform: '', 5128 width: '', 5129 height: '' 5130 }); 5131 5132 // Add active class to new target 5133 $targets.addClass(tabActive).each(ix.intro); 5134 Webflow.redraw.up(); 5135 5136 // Set opacity immediately if intro is zero 5137 if (!config.intro) return tram($targets).set({ 5138 opacity: 1 5139 }); 5140 5141 // Otherwise fade in opacity 5142 tram($targets) 5143 .set({ 5144 opacity: 0 5145 }) 5146 .redraw() 5147 .add('opacity ' + config.intro + 'ms ' + easing, { 5148 fallback: safari 5149 }) 5150 .start({ 5151 opacity: 1 5152 }); 5153 } 5154 } 5155 5156 // Export module 5157 return api; 5158 }); 5159 5160 5161 /***/ 5162 }, 5163 /* 20 */ 5164 /***/ 5165 function(module, exports, __webpack_require__) { 5166 5167 'use strict'; 5168 5169 /** 5170 * Webflow: Touch events 5171 */ 5172 5173 var Webflow = __webpack_require__(1); 5174 5175 Webflow.define('touch', module.exports = function($, _) { 5176 var api = {}; 5177 var fallback = !document.addEventListener; 5178 var getSelection = window.getSelection; 5179 5180 // Fallback to click events in old IE 5181 if (fallback) { 5182 $.event.special.tap = { 5183 bindType: 'click', 5184 delegateType: 'click' 5185 }; 5186 } 5187 5188 api.init = function(el) { 5189 if (fallback) return null; 5190 el = typeof el === 'string' ? $(el).get(0) : el; 5191 return el ? new Touch(el) : null; 5192 }; 5193 5194 function Touch(el) { 5195 var active = false; 5196 var dirty = false; 5197 var useTouch = false; 5198 var thresholdX = Math.min(Math.round(window.innerWidth * 0.04), 40); 5199 var startX, startY, lastX; 5200 5201 el.addEventListener('touchstart', start, false); 5202 el.addEventListener('touchmove', move, false); 5203 el.addEventListener('touchend', end, false); 5204 el.addEventListener('touchcancel', cancel, false); 5205 el.addEventListener('mousedown', start, false); 5206 el.addEventListener('mousemove', move, false); 5207 el.addEventListener('mouseup', end, false); 5208 el.addEventListener('mouseout', cancel, false); 5209 5210 function start(evt) { 5211 // We donât handle multi-touch events yet. 5212 var touches = evt.touches; 5213 if (touches && touches.length > 1) { 5214 return; 5215 } 5216 5217 active = true; 5218 dirty = false; 5219 5220 if (touches) { 5221 useTouch = true; 5222 startX = touches[0].clientX; 5223 startY = touches[0].clientY; 5224 } else { 5225 startX = evt.clientX; 5226 startY = evt.clientY; 5227 } 5228 5229 lastX = startX; 5230 } 5231 5232 function move(evt) { 5233 if (!active) return; 5234 5235 if (useTouch && evt.type === 'mousemove') { 5236 evt.preventDefault(); 5237 evt.stopPropagation(); 5238 return; 5239 } 5240 5241 var touches = evt.touches; 5242 var x = touches ? touches[0].clientX : evt.clientX; 5243 var y = touches ? touches[0].clientY : evt.clientY; 5244 5245 var velocityX = x - lastX; 5246 lastX = x; 5247 5248 // Allow swipes while pointer is down, but prevent them during text selection 5249 if (Math.abs(velocityX) > thresholdX && getSelection && getSelection() + '' === '') { 5250 triggerEvent('swipe', evt, { 5251 direction: velocityX > 0 ? 'right' : 'left' 5252 }); 5253 cancel(); 5254 } 5255 5256 // If pointer moves more than 10px flag to cancel tap 5257 if (Math.abs(x - startX) > 10 || Math.abs(y - startY) > 10) { 5258 dirty = true; 5259 } 5260 } 5261 5262 function end(evt) { 5263 if (!active) return; 5264 active = false;
5265 5266 if (useTouch && evt.type === 'mouseup') { 5267 evt.preventDefault(); 5268 evt.stopPropagation(); 5269 useTouch = false; 5270 return; 5271 } 5272 5273 if (!dirty) triggerEvent('tap', evt); 5274 } 5275 5276 function cancel(evt) { 5277 active = false; 5278 } 5279 5280 function destroy() { 5281 el.removeEventListener('touchstart', start, false); 5282 el.removeEventListener('touchmove', move, false); 5283 el.removeEventListener('touchend', end, false); 5284 el.removeEventListener('touchcancel', cancel, false); 5285 el.removeEventListener('mousedown', start, false); 5286 el.removeEventListener('mousemove', move, false); 5287 el.removeEventListener('mouseup', end, false); 5288 el.removeEventListener('mouseout', cancel, false); 5289 el = null; 5290 } 5291 5292 // Public instance methods 5293 this.destroy = destroy; 5294 } 5295 5296 // Wrap native event to supoprt preventdefault + stopPropagation 5297 function triggerEvent(type, evt, data) { 5298 var newEvent = $.Event(type, { 5299 originalEvent: evt 5300 }); 5301 $(evt.target).trigger(newEvent, data); 5302 } 5303 5304 // Listen for touch events on all nodes by default. 5305 api.instance = api.init(document); 5306 5307 // Export module 5308 return api; 5309 }); 5310 5311 5312 /***/ 5313 }, 5314 /* 21 */ 5315 /***/ 5316 function(module, exports, __webpack_require__) { 5317 5318 'use strict'; 5319 5320 /*jshint -W054 */ 5321 5322 // Include tram for frame-throttling 5323 var $ = window.$; 5324 var tram = __webpack_require__(3) && $.tram; 5325 5326 /*! 5327 * Webflow._ (aka) Underscore.js 1.6.0 (custom build) 5328 * _.each 5329 * _.map 5330 * _.find 5331 * _.filter 5332 * _.any 5333 * _.contains 5334 * _.delay 5335 * _.defer 5336 * _.throttle (webflow) 5337 * _.debounce 5338 * _.keys 5339 * _.has 5340 * _.now 5341 * 5342 * http://underscorejs.org 5343 * (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 5344 * Underscore may be freely distributed under the MIT license. 5345 * @license MIT 5346 */ 5347 module.exports = (function() { 5348 var _ = {}; 5349 5350 // Current version. 5351 _.VERSION = '1.6.0-Webflow'; 5352 5353 // Establish the object that gets returned to break out of a loop iteration. 5354 var breaker = {}; 5355 5356 // Save bytes in the minified (but not gzipped) version: 5357 var ArrayProto = Array.prototype, 5358 ObjProto = Object.prototype, 5359 FuncProto = Function.prototype; 5360 5361 // Create quick reference variables for speed access to core prototypes. 5362 var 5363 push = ArrayProto.push, 5364 slice = ArrayProto.slice, 5365 concat = ArrayProto.concat, 5366 toString = ObjProto.toString, 5367 hasOwnProperty = ObjProto.hasOwnProperty; 5368 5369 // All **ECMAScript 5** native function implementations that we hope to use 5370 // are declared here. 5371 var 5372 nativeForEach = ArrayProto.forEach, 5373 nativeMap = ArrayProto.map, 5374 nativeReduce = ArrayProto.reduce, 5375 nativeReduceRight = ArrayProto.reduceRight, 5376 nativeFilter = ArrayProto.filter, 5377 nativeEvery = ArrayProto.every, 5378 nativeSome = ArrayProto.some, 5379 nativeIndexOf = ArrayProto.indexOf, 5380 nativeLastIndexOf = ArrayProto.lastIndexOf, 5381 nativeIsArray = Array.isArray, 5382 nativeKeys = Object.keys, 5383 nativeBind = FuncProto.bind; 5384 5385 // Collection Functions 5386 // -------------------- 5387 5388 // The cornerstone, an `each` implementation, aka `forEach`. 5389 // Handles objects with the built-in `forEach`, arrays, and raw objects.
5390 // Delegates to **ECMAScript 5**'s native `forEach` if available. 5391 var each = _.each = _.forEach = function(obj, iterator, context) { 5392 /* jshint shadow:true */ 5393 if (obj == null) return obj; 5394 if (nativeForEach && obj.forEach === nativeForEach) { 5395 obj.forEach(iterator, context); 5396 } else if (obj.length === +obj.length) { 5397 for (var i = 0, length = obj.length; i < length; i++) { 5398 if (iterator.call(context, obj[i], i, obj) === breaker) return; 5399 } 5400 } else { 5401 var keys = _.keys(obj); 5402 for (var i = 0, length = keys.length; i < length; i++) { 5403 if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return; 5404 } 5405 } 5406 return obj; 5407 }; 5408 5409 // Return the results of applying the iterator to each element. 5410 // Delegates to **ECMAScript 5**'s native `map` if available. 5411 _.map = _.collect = function(obj, iterator, context) { 5412 var results = []; 5413 if (obj == null) return results; 5414 if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context); 5415 each(obj, function(value, index, list) { 5416 results.push(iterator.call(context, value, index, list)); 5417 }); 5418 return results; 5419 }; 5420 5421 // Return the first value which passes a truth test. Aliased as `detect`. 5422 _.find = _.detect = function(obj, predicate, context) { 5423 var result; 5424 any(obj, function(value, index, list) { 5425 if (predicate.call(context, value, index, list)) { 5426 result = value; 5427 return true; 5428 } 5429 }); 5430 return result; 5431 }; 5432 5433 // Return all the elements that pass a truth test. 5434 // Delegates to **ECMAScript 5**'s native `filter` if available. 5435 // Aliased as `select`. 5436 _.filter = _.select = function(obj, predicate, context) { 5437 var results = []; 5438 if (obj == null) return results; 5439 if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context); 5440 each(obj, function(value, index, list) { 5441 if (predicate.call(context, value, index, list)) results.push(value); 5442 }); 5443 return results; 5444 }; 5445 5446 // Determine if at least one element in the object matches a truth test. 5447 // Delegates to **ECMAScript 5**'s native `some` if available. 5448 // Aliased as `any`. 5449 var any = _.some = _.any = function(obj, predicate, context) { 5450 predicate || (predicate = _.identity); 5451 var result = false;
5452 if (obj == null) return result; 5453 if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context); 5454 each(obj, function(value, index, list) { 5455 if (result || (result = predicate.call(context, value, index, list))) return breaker; 5456 }); 5457 return !!result; 5458 }; 5459 5460 // Determine if the array or object contains a given value (using `===`). 5461 // Aliased as `include`. 5462 _.contains = _.include = function(obj, target) { 5463 if (obj == null) return false; 5464 if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; 5465 return any(obj, function(value) { 5466 return value === target; 5467 }); 5468 }; 5469 5470 // Function (ahem) Functions 5471 // -------------------- 5472 5473 // Delays a function for the given number of milliseconds, and then calls 5474 // it with the arguments supplied. 5475 _.delay = function(func, wait) { 5476 var args = slice.call(arguments, 2); 5477 return setTimeout(function() { 5478 return func.apply(null, args); 5479 }, wait); 5480 }; 5481 5482 // Defers a function, scheduling it to run after the current call stack has 5483 // cleared. 5484 _.defer = function(func) { 5485 return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); 5486 }; 5487 5488 // Returns a function, that, when invoked, will only be triggered once every 5489 // browser animation frame - using tram's requestAnimationFrame polyfill. 5490 _.throttle = function(func) { 5491 var wait, args, context; 5492 return function() { 5493 if (wait) return; 5494 wait = true; 5495 args = arguments; 5496 context = this; 5497 tram.frame(function() { 5498 wait = false; 5499 func.apply(context, args); 5500 }); 5501 }; 5502 }; 5503 5504 // Returns a function, that, as long as it continues to be invoked, will not 5505 // be triggered. The function will be called after it stops being called for 5506 // N milliseconds. If `immediate` is passed, trigger the function on the 5507 // leading edge, instead of the trailing. 5508 _.debounce = function(func, wait, immediate) { 5509 var timeout, args, context, timestamp, result; 5510 5511 var later = function() { 5512 var last = _.now() - timestamp; 5513 if (last < wait) { 5514 timeout = setTimeout(later, wait - last); 5515 } else { 5516 timeout = null; 5517 if (!immediate) { 5518 result = func.apply(context, args); 5519 context = args = null; 5520 } 5521 } 5522 }; 5523 5524 return function() { 5525 context = this; 5526 args = arguments; 5527 timestamp = _.now(); 5528 var callNow = immediate && !timeout; 5529 if (!timeout) { 5530 timeout = setTimeout(later, wait); 5531 } 5532 if (callNow) { 5533 result = func.apply(context, args); 5534 context = args = null; 5535 } 5536 5537 return result; 5538 }; 5539 }; 5540 5541 // Object Functions 5542 // ---------------- 5543 5544 // Fill in a given object with default properties. 5545 _.defaults = function(obj) { 5546 if (!_.isObject(obj)) return obj; 5547 for (var i = 1, length = arguments.length; i < length; i++) { 5548 var source = arguments[i]; 5549 for (var prop in source) { 5550 if (obj[prop] === void 0) obj[prop] = source[prop]; 5551 } 5552 } 5553 return obj; 5554 }; 5555 5556 // Retrieve the names of an object's properties. 5557 // Delegates to **ECMAScript 5**'s native `Object.keys` 5558 _.keys = function(obj) { 5559 if (!_.isObject(obj)) return []; 5560 if (nativeKeys) return nativeKeys(obj); 5561 var keys = []; 5562 for (var key in obj) 5563 if (_.has(obj, key)) keys.push(key); 5564 return keys; 5565 }; 5566 5567 // Shortcut function for checking if an object has a given property directly 5568 // on itself (in other words, not on a prototype). 5569 _.has = function(obj, key) { 5570 return hasOwnProperty.call(obj, key); 5571 }; 5572 5573 // Is a given variable an object? 5574 _.isObject = function(obj) { 5575 return obj === Object(obj); 5576 }; 5577 5578 // Utility Functions 5579 // ----------------- 5580 5581 // A (possibly faster) way to get the current timestamp as an integer. 5582 _.now = Date.now || function() { 5583 return new Date().getTime(); 5584 }; 5585 5586 // By default, Underscore uses ERB-style template delimiters, change the 5587 // following template settings to use alternative delimiters. 5588 _.templateSettings = { 5589 evaluate: /<%([\s\S]+?)%>/g, 5590 interpolate: /<%=([\s\S]+?)%>/g, 5591 escape: /<%-([\s\S]+?)%>/g 5592 }; 5593 5594 // When customizing `templateSettings`, if you don't want to define an 5595 // interpolation, evaluation or escaping regex, we need one that is 5596 // guaranteed not to match. 5597 var noMatch = /(.)^/; 5598 5599 // Certain characters need to be escaped so that they can be put into a 5600 // string literal. 5601 var escapes = { 5602 "'": "'", 5603 '\\': '\\', 5604 '\r': 'r', 5605 '\n': 'n', 5606 '\u2028': 'u2028', 5607 '\u2029': 'u2029' 5608 }; 5609 5610 var escaper = /\\|'|\r|\n|\u2028|\u2029/g; 5611 5612 var escapeChar = function(match) { 5613 return '\\' + escapes[match]; 5614 }; 5615 5616 // JavaScript micro-templating, similar to John Resig's implementation. 5617 // Underscore templating handles arbitrary delimiters, preserves whitespace, 5618 // and correctly escapes quotes within interpolated code. 5619 // NB: `oldSettings` only exists for backwards compatibility. 5620 _.template = function(text, settings, oldSettings) { 5621 if (!settings && oldSettings) settings = oldSettings; 5622 settings = _.defaults({}, settings, _.templateSettings); 5623 5624 // Combine delimiters into one regular expression via alternation. 5625 var matcher = RegExp([
5626 (settings.escape || noMatch).source, (settings.interpolate || noMatch).source, (settings.evaluate || noMatch).source 5627 ].join('|') + '|$', 'g'); 5628 5629 // Compile the template source, escaping string literals appropriately. 5630 var index = 0; 5631 var source = "__p+='"; 5632 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { 5633 source += text.slice(index, offset).replace(escaper, escapeChar); 5634 index = offset + match.length; 5635 5636 if (escape) { 5637 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; 5638 } else if (interpolate) { 5639 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; 5640 } else if (evaluate) { 5641 source += "';\n" + evaluate + "\n__p+='"; 5642 } 5643 5644 // Adobe VMs need the match returned to produce the correct offest. 5645 return match; 5646 }); 5647 source += "';\n"; 5648 5649 // If a variable is not specified, place data values in local scope. 5650 if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; 5651 5652 source = "var __t,__p='',__j=Array.prototype.join," + 5653 "print=function(){__p+=__j.call(arguments,'');};\n" + 5654 source + 'return __p;\n'; 5655 5656 try { 5657 var render = new Function(settings.variable || 'obj', '_', source); 5658 } catch (e) { 5659 e.source = source; 5660 throw e; 5661 } 5662 5663 var template = function(data) { 5664 return render.call(this, data, _); 5665 }; 5666 5667 // Provide the compiled source as a convenience for precompilation. 5668 var argument = settings.variable || 'obj'; 5669 template.source = 'function(' + argument + '){\n' + source + '}'; 5670 5671 return template; 5672 }; 5673 5674 // Export underscore 5675 return _; 5676 }()); 5677 5678 5679 /***/ 5680 }, 5681 /* 22 */ 5682 /***/ 5683 function(module, exports) { 5684 5685 /*! 5686 * jQuery-ajaxTransport-XDomainRequest - v1.0.3 5687 * 2014-12-16 WEBFLOW - Removed UMD wrapper 5688 * https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest 5689 * Copyright (c) 2014 Jason Moon (@JSONMOON) 5690 * @license MIT (/blob/master/LICENSE.txt) 5691 */ 5692 module.exports = function($) { 5693 if ($.support.cors || !$.ajaxTransport || !window.XDomainRequest) { 5694 return 5695 } 5696 var httpRegEx = /^https?:\/\//i; 5697 var getOrPostRegEx = /^get|post$/i; 5698 var sameSchemeRegEx = new RegExp("^" + location.protocol, "i"); 5699 $.ajaxTransport("* text html xml json", function(options, userOptions, jqXHR) { 5700 if (!options.crossDomain || !options.async || !getOrPostRegEx.test(options.type) || !httpRegEx.test(options.url) || !sameSchemeRegEx.test(options.url)) { 5701 return 5702 } 5703 var xdr = null; 5704 return { 5705 send: function(headers, complete) { 5706 var postData = ""; 5707 var userType = (userOptions.dataType || "").toLowerCase(); 5708 xdr = new XDomainRequest; 5709 if (/^\d+$/.test(userOptions.timeout)) { 5710 xdr.timeout = userOptions.timeout 5711 } 5712 xdr.ontimeout = function() { 5713 complete(500, "timeout") 5714 }; 5715 xdr.onload = function() { 5716 var allResponseHeaders = "Content-Length: " + xdr.responseText.length + "\r\nContent-Type: " + xdr.contentType; 5717 var status = { 5718 code: 200, 5719 message: "success" 5720 }; 5721 var responses = { 5722 text: xdr.responseText 5723 }; 5724 try { 5725 if (userType === "html" || /text\/html/i.test(xdr.contentType)) { 5726 responses.html = xdr.responseText 5727 } else if (userType === "json" || userType !== "text" && /\/json/i.test(xdr.contentType)) { 5728 try { 5729 responses.json = $.parseJSON(xdr.responseText) 5730 } catch (e) { 5731 status.code = 500; 5732 status.message = "parseerror" 5733 } 5734 } else if (userType === "xml" || userType !== "text" && /\/xml/i.test(xdr.contentType)) { 5735 var doc = new ActiveXObject("Microsoft.XMLDOM"); 5736 doc.async = false;
5737 try { 5738 doc.loadXML(xdr.responseText) 5739 } catch (e) { 5740 doc = undefined 5741 } 5742 if (!doc || !doc.documentElement || doc.getElementsByTagName("parsererror").length) { 5743 status.code = 500; 5744 status.message = "parseerror"; 5745 throw "Invalid XML: " + xdr.responseText 5746 } 5747 responses.xml = doc 5748 } 5749 } catch (parseMessage) { 5750 throw parseMessage 5751 } finally { 5752 complete(status.code, status.message, responses, allResponseHeaders) 5753 } 5754 }; 5755 xdr.onprogress = function() {}; 5756 xdr.onerror = function() { 5757 complete(500, "error", { 5758 text: xdr.responseText 5759 }) 5760 }; 5761 if (userOptions.data) { 5762 postData = $.type(userOptions.data) === "string" ? userOptions.data : $.param(userOptions.data) 5763 } 5764 xdr.open(options.type, options.url); 5765 xdr.send(postData) 5766 }, 5767 abort: function() { 5768 if (xdr) { 5769 xdr.abort() 5770 } 5771 } 5772 } 5773 }) 5774 }(window.jQuery); 5775 5776 /***/ 5777 } 5778 /******/ 5779]); 5780/** 5781 * ---------------------------------------------------------------------- 5782 * Webflow: Interactions: Init 5783 */ 5784Webflow.require('ix').init([{ 5785 "slug": "opacity", 5786 "name": "opacity", 5787 "value": { 5788 "style": { 5789 "opacity": 0.34 5790 }, 5791 "triggers": [] 5792 } 5793}, { 5794 "slug": "show-menu", 5795 "name": "show menu", 5796 "value": { 5797 "style": {}, 5798 "triggers": [{ 5799 "type": "click", 5800 "selector": ".menu-left", 5801 "stepsA": [{ 5802 "opacity": 1, 5803 "transition": "transform 200ms ease 0ms, opacity 200ms ease 0ms", 5804 "x": "0px", 5805 "y": "0px", 5806 "z": "0px" 5807 }], 5808 "stepsB": [{ 5809 "opacity": 1, 5810 "transition": "transform 200ms ease 0ms, opacity 200ms ease 0ms", 5811 "x": "0px", 5812 "y": "0px", 5813 "z": "0px" 5814 }] 5815 }] 5816 } 5817}, { 5818 "slug": "close-menu", 5819 "name": "close menu", 5820 "value": { 5821 "style": {}, 5822 "triggers": [{ 5823 "type": "click", 5824 "selector": ".menu-left", 5825 "stepsA": [{ 5826 "opacity": 0, 5827 "transition": "transform 200ms ease 0ms, opacity 500ms ease 0ms", 5828 "x": "-100%", 5829 "y": "0px", 5830 "z": "0px" 5831 }], 5832 "stepsB": [] 5833 }] 5834 } 5835}, { 5836 "slug": "0-opacity", 5837 "name": "0 opacity", 5838 "value": { 5839 "style": { 5840 "opacity": 0 5841 }, 5842 "triggers": [] 5843 } 5844}, { 5845 "slug": "gost-show", 5846 "name": "gost show", 5847 "value": { 5848 "style": {}, 5849 "triggers": [{ 5850 "type": "hover", 5851 "selector": ".gost-menu-vse-tovari", 5852 "stepsA": [{ 5853 "display": "block" 5854 }], 5855 "stepsB": [{ 5856 "display": "none" 5857 }] 5858 }] 5859 } 5860}, 5861/*{ 5862 "slug": "show-all-catalogue", 5863 "name": "show all catalogue", 5864 "value": { 5865 "style": {}, 5866 "triggers": [{ 5867 "type": "click", 5868 "selector": ".all-catalog-block", 5869 "stepsA": [{ 5870 "display": "block" 5871 }], 5872 "stepsB": [{ 5873 "display": "none" 5874 }] 5875 }] 5876 }*/ 5877// }, {
5878// "slug": "show-all-items", 5879// "name": "show all items", 5880// "value": { 5881// "style": {}, 5882// "triggers": [{ 5883// "type": "click", 5884// "selector": ".menu-vse-tovari", 5885// "stepsA": [{ 5886// "display": "block" 5887// }], 5888// "stepsB": [{ 5889// "display": "none" 5890// }] 5891// }] 5892// } 5893//}, 5894{ 5895 "slug": "kuhnya-show", 5896 "name": "kuhnya show", 5897 "value": { 5898 "style": {}, 5899 "triggers": [{ 5900 "type": "hover", 5901 "selector": ".kuhnya-menu-vse-tovari", 5902 "stepsA": [{ 5903 "display": "block" 5904 }], 5905 "stepsB": [] 5906 }] 5907 } 5908}, { 5909 "slug": "vanna-show", 5910 "name": "vanna show", 5911 "value": { 5912 "style": {}, 5913 "triggers": [{ 5914 "type": "hover", 5915 "selector": ".vanna-menu-vse-tovari", 5916 "stepsA": [{ 5917 "display": "block" 5918 }], 5919 "stepsB": [{ 5920 "display": "none" 5921 }] 5922 }] 5923 } 5924// }, { 5925// "slug": "show-likes", 5926// "name": "show likes", 5927// "value": { 5928// "style": {}, 5929// "triggers": [{ 5930// "type": "hover", 5931// "selector": ".likes-block", 5932// "stepsA": [{ 5933// "display": "block" 5934// }], 5935// "stepsB": [{ 5936// "display": "none" 5937// }] 5938// }] 5939// } 5940// }, { 5941// "slug": "fav-menu", 5942// "name": "fav menu", 5943// "value": { 5944// "style": {}, 5945// "triggers": [{ 5946// "type": "click", 5947// "selector": ".fav-items-header", 5948// "stepsA": [{ 5949// "display": "block" 5950// }], 5951// "stepsB": [{ 5952// "display": "none" 5953// }] 5954// }] 5955// } 5956// }, { 5957// "slug": "show-contact", 5958// "name": "Show contact", 5959// "value": { 5960// "style": {}, 5961// "triggers": [{ 5962// "type": "click", 5963// "selector": ".contact-block-menu", 5964// "stepsA": [{ 5965// "display": "block" 5966// }], 5967// "stepsB": [{ 5968// "display": "none" 5969// }] 5970// }] 5971// } 5972// }, { 5973// "slug": "search-block", 5974// "name": "Search block", 5975// "value": { 5976// "style": {}, 5977// "triggers": [{ 5978// "type": "click", 5979// "selector": ".search-block", 5980// "stepsA": [{ 5981// "display": "block" 5982// }], 5983// "stepsB": [{ 5984// "display": "none" 5985// }] 5986// }] 5987// } 5988}, { 5989 "slug": "shop-menu-block", 5990 "name": "shop menu block", 5991 "value": { 5992 "style": {}, 5993 "triggers": [{ 5994 "type": "click", 5995 "selector": ".shop-menu-block", 5996 "stepsA": [{ 5997 "opacity": 1, 5998 "transition": "transform 200ms ease 0ms, opacity 200ms ease 0ms", 5999 "x": "0px", 6000 "y": "0px", 6001 "z": "0px" 6002 }], 6003 "stepsB": [{ 6004 "opacity": 0, 6005 "transition": "transform 200ms ease 0ms, opacity 200ms ease 0ms", 6006 "x": "-100%", 6007 "y": "0px", 6008 "z": "0px" 6009 }] 6010 }] 6011 } 6012}, { 6013 "slug": "shop-menu-block-2", 6014 "name": "shop menu block 2", 6015 "value": { 6016 "style": {}, 6017 "triggers": [{ 6018 "type": "click", 6019 "selector": ".shop-menu-block", 6020 "stepsA": [{ 6021 "transition": "transform 200ms ease 0ms", 6022 "x": "-100%", 6023 "y": "0px", 6024 "z": "0px" 6025 }], 6026 "stepsB": [{ 6027 "transition": "transform 200ms ease 0ms", 6028 "x": "0px", 6029 "y": "0px", 6030 "z": "0px" 6031 }] 6032 }] 6033 } 6034}, { 6035 "slug": "show-map-window", 6036 "name": "show map window", 6037 "value": { 6038 "style": {}, 6039 "triggers": [{ 6040 "type": "click", 6041 "selector": ".map-trade-center", 6042 "stepsA": [{ 6043 "display": "block" 6044 }], 6045 "stepsB": [{ 6046 "display": "none" 6047 }] 6048 }] 6049 } 6050}, { 6051 "slug": "close-map-popup", 6052 "name": "close map popup", 6053 "value": { 6054 "style": {}, 6055 "triggers": [{ 6056 "type": "click", 6057 "selector": ".map-trade-center", 6058 "stepsA": [{ 6059 "display": "none" 6060 }], 6061 "stepsB": [] 6062 }] 6063 } 6064}, /*{ 6065 "slug": "show-answer", 6066 "name": "show answer", 6067 "value": { 6068 "style": {}, 6069 "triggers": [{ 6070 "type": "click", 6071 "selector": ".open-question", 6072 "stepsA": [{ 6073 "display": "block" 6074 }], 6075 "stepsB": [{ 6076 "display": "none" 6077 }] 6078 }] 6079 } 6080},*/ { 6081 "slug": "show-map", 6082 "name": "Show map", 6083 "value": { 6084 "style": {}, 6085 "triggers": [{ 6086 "type": "click", 6087 "selector": ".close-block-map", 6088 "stepsA": [{ 6089 "display": "block" 6090 }], 6091 "stepsB": [{ 6092 "display": "none" 6093 }] 6094 }] 6095 } 6096}, { 6097 "slug": "show-action-dash", 6098 "name": "show action dash", 6099 "value": { 6100 "style": {}, 6101 "triggers": [{ 6102 "type": "click", 6103 "selector": ".row-action", 6104 "stepsA": [{ 6105 "display": "block" 6106 }], 6107 "stepsB": [{ 6108 "display": "none" 6109 }] 6110 }] 6111 } 6112}, { 6113 "slug": "new-interaction", 6114 "name": "New Interaction", 6115 "value": { 6116 "style": {}, 6117 "triggers": [{ 6118 "type": "click", 6119 "selector": ".row-statistic", 6120 "stepsA": [{ 6121 "display": "block" 6122 }], 6123 "stepsB": [{ 6124 "display": "none" 6125 }] 6126 }] 6127 } 6128}, { 6129 "slug": "show-place-2", 6130 "name": "show place 2", 6131 "value": { 6132 "style": {}, 6133 "triggers": [{ 6134 "type": "click", 6135 "selector": ".block-place-2", 6136 "stepsA": [{ 6137 "display": "block" 6138 }], 6139 "stepsB": [] 6140 }] 6141 } 6142}, { 6143 "slug": "add-phone-2", 6144 "name": "add phone 2", 6145 "value": { 6146 "style": {}, 6147 "triggers": [{ 6148 "type": "click", 6149 "selector": ".phone-user-2", 6150 "stepsA": [{ 6151 "display": "block" 6152 }], 6153 "stepsB": [] 6154 }] 6155 } 6156}, { 6157 "slug": "category-block-2", 6158 "name": "Category block 2", 6159 "value": { 6160 "style": {}, 6161 "triggers": [{ 6162 "type": "click", 6163 "selector": ".category-2-block", 6164 "stepsA": [{ 6165 "display": "block" 6166 }], 6167 "stepsB": [] 6168 }] 6169 } 6170}, { 6171 "slug": "show-info-block", 6172 "name": "show info block", 6173 "value": { 6174 "style": {}, 6175 "triggers": [{ 6176 "type": "hover", 6177 "selector": ".info-block-dashboard", 6178 "stepsA": [{ 6179 "opacity": 1, 6180 "transition": "opacity 500ms ease 0ms" 6181 }], 6182 "stepsB": [{ 6183 "wait": 3000 6184 }, { 6185 "opacity": 0, 6186 "transition": "opacity 500ms ease 0ms" 6187 }] 6188 }] 6189 } 6190}, { 6191 "slug": "load-1", 6192 "name": "Load 1", 6193 "value": { 6194 "style": { 6195 "opacity": 0 6196 // "x": "0px", 6197 // "y": "49px", 6198 // "z": "0px" 6199 }, 6200 "triggers": [{ 6201 "type": "load", 6202 "stepsA": [{ 6203 "opacity": 1, 6204 "transition": "transform 600ms ease 0ms, opacity 200ms ease 0ms" 6205 }], 6206 "stepsB": [] 6207 }] 6208 } 6209}, { 6210 "slug": "load-2", 6211 "name": "Load 2", 6212 "value": { 6213 "style": { 6214 "opacity": 0, 6215 "x": "0px", 6216 "y": "49px", 6217 "z": "0px" 6218 }, 6219 "triggers": [{ 6220 "type": "load", 6221 "stepsA": [{ 6222 "wait": 200 6223 }, { 6224 "opacity": 1, 6225 "transition": "transform 600ms ease 0ms, opacity 200ms ease 0ms", 6226 "x": "0px",
6227 "y": "0px", 6228 "z": "0px" 6229 }], 6230 "stepsB": [] 6231 }] 6232 } 6233}, { 6234 "slug": "load-on-scroll", 6235 "name": "load on scroll", 6236 "value": { 6237 "style": { 6238 "opacity": 0, 6239 "x": "0px", 6240 "y": "35px", 6241 "z": "0px" 6242 }, 6243 "triggers": [{ 6244 "type": "scroll", 6245 "offsetBot": "20%", 6246 "stepsA": [{ 6247 "opacity": 1, 6248 "transition": "transform 600ms ease 0ms, opacity 600ms ease 0ms", 6249 "x": "0px", 6250 "y": "0px", 6251 "z": "0px" 6252 }], 6253 "stepsB": [] 6254 }] 6255 } 6256}, { 6257 "slug": "load-fade", 6258 "name": "Load fade", 6259 "value": { 6260 "style": { 6261 "opacity": 0 6262 }, 6263 "triggers": [{ 6264 "type": "load", 6265 "stepsA": [{ 6266 "opacity": 1, 6267 "transition": "opacity 600ms ease 0ms" 6268 }], 6269 "stepsB": [] 6270 }] 6271 } 6272}]);
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.