github.com/rabbouni145/gg@v0.47.1/docs/themes/gohugoioTheme/static/dist/app.bundle.js (about) 1 /******/ (function(modules) { // webpackBootstrap 2 /******/ // The module cache 3 /******/ var installedModules = {}; 4 /******/ 5 /******/ // The require function 6 /******/ function __webpack_require__(moduleId) { 7 /******/ 8 /******/ // Check if module is in cache 9 /******/ if(installedModules[moduleId]) { 10 /******/ return installedModules[moduleId].exports; 11 /******/ } 12 /******/ // Create a new module (and put it into the cache) 13 /******/ var module = installedModules[moduleId] = { 14 /******/ i: moduleId, 15 /******/ l: false, 16 /******/ exports: {} 17 /******/ }; 18 /******/ 19 /******/ // Execute the module function 20 /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21 /******/ 22 /******/ // Flag the module as loaded 23 /******/ module.l = true; 24 /******/ 25 /******/ // Return the exports of the module 26 /******/ return module.exports; 27 /******/ } 28 /******/ 29 /******/ 30 /******/ // expose the modules object (__webpack_modules__) 31 /******/ __webpack_require__.m = modules; 32 /******/ 33 /******/ // expose the module cache 34 /******/ __webpack_require__.c = installedModules; 35 /******/ 36 /******/ // identity function for calling harmony imports with the correct context 37 /******/ __webpack_require__.i = function(value) { return value; }; 38 /******/ 39 /******/ // define getter function for harmony exports 40 /******/ __webpack_require__.d = function(exports, name, getter) { 41 /******/ if(!__webpack_require__.o(exports, name)) { 42 /******/ Object.defineProperty(exports, name, { 43 /******/ configurable: false, 44 /******/ enumerable: true, 45 /******/ get: getter 46 /******/ }); 47 /******/ } 48 /******/ }; 49 /******/ 50 /******/ // getDefaultExport function for compatibility with non-harmony modules 51 /******/ __webpack_require__.n = function(module) { 52 /******/ var getter = module && module.__esModule ? 53 /******/ function getDefault() { return module['default']; } : 54 /******/ function getModuleExports() { return module; }; 55 /******/ __webpack_require__.d(getter, 'a', getter); 56 /******/ return getter; 57 /******/ }; 58 /******/ 59 /******/ // Object.prototype.hasOwnProperty.call 60 /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 61 /******/ 62 /******/ // __webpack_public_path__ 63 /******/ __webpack_require__.p = ""; 64 /******/ 65 /******/ // Load entry module and return exports 66 /******/ return __webpack_require__(__webpack_require__.s = 11); 67 /******/ }) 68 /************************************************************************/ 69 /******/ ([ 70 /* 0 */ 71 /***/ (function(module, exports, __webpack_require__) { 72 73 "use strict"; 74 75 76 /** 77 * Anchor for ID BPNY 78 **/ 79 var anchorForId = function anchorForId(id) { 80 var anchor = document.createElement("a"); 81 anchor.className = "header-link"; 82 anchor.href = "#" + id; 83 anchor.innerHTML = ' <svg class="fill-current o-60 hover-accent-color-light" height="22px" viewBox="0 0 24 24" width="22px" xmlns="http://www.w3.org/2000/svg"><path d="M0 0h24v24H0z" fill="none"/><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg>'; 84 return anchor; 85 }; 86 87 var linkifyAnchors = function linkifyAnchors(level, containingElement) { 88 var headers = containingElement.getElementsByTagName("h" + level); 89 for (var h = 0; h < headers.length; h++) { 90 var header = headers[h]; 91 92 if (typeof header.id !== "undefined" && header.id !== "") { 93 header.appendChild(anchorForId(header.id)); 94 } 95 } 96 }; 97 98 document.onreadystatechange = function () { 99 if (this.readyState === "complete") { 100 var contentBlock = document.getElementsByClassName("prose")[0]; 101 if (!contentBlock) { 102 return; 103 } 104 for (var level = 2; level <= 4; level++) { 105 linkifyAnchors(level, contentBlock); 106 } 107 } 108 }; 109 110 /***/ }), 111 /* 1 */ 112 /***/ (function(module, exports, __webpack_require__) { 113 114 "use strict"; 115 116 117 var Clipboard = __webpack_require__(12); 118 new Clipboard('.copy', { 119 target: function target(trigger) { 120 if (trigger.classList.contains('copy-toggle')) { 121 return trigger.previousElementSibling; 122 } 123 return trigger.nextElementSibling; 124 } 125 }).on('success', function (e) { 126 successMessage(e.trigger, 'Copied!'); 127 e.clearSelection(); 128 }).on('error', function (e) { 129 successMessage(e.trigger, fallbackMessage(e.action)); 130 }); 131 132 function successMessage(elem, msg) { 133 elem.setAttribute('class', 'copied bg-primary-color-dark f6 absolute top-0 right-0 lh-solid hover-bg-primary-color-dark bn white ph3 pv2'); 134 elem.setAttribute('aria-label', msg); 135 } 136 137 function fallbackMessage(elem, action) { 138 var actionMsg = ''; 139 var actionKey = action === 'cut' ? 'X' : 'C'; 140 if (isMac) { 141 actionMsg = 'Press ⌘-' + actionKey; 142 } else { 143 actionMsg = 'Press Ctrl-' + actionKey; 144 } 145 return actionMsg; 146 } 147 148 /***/ }), 149 /* 2 */ 150 /***/ (function(module, exports, __webpack_require__) { 151 152 "use strict"; 153 154 155 var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); 156 157 var article = document.getElementById('prose'); 158 159 if (article) { 160 var codeBlocks = article.getElementsByTagName('code'); 161 var _iteratorNormalCompletion = true; 162 var _didIteratorError = false; 163 var _iteratorError = undefined; 164 165 try { 166 for (var _iterator = Object.entries(codeBlocks)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { 167 var _ref = _step.value; 168 169 var _ref2 = _slicedToArray(_ref, 2); 170 171 var key = _ref2[0]; 172 var codeBlock = _ref2[1]; 173 174 var widthDif = codeBlock.scrollWidth - codeBlock.clientWidth; 175 if (widthDif > 0) codeBlock.parentNode.classList.add('expand'); 176 } 177 } catch (err) { 178 _didIteratorError = true; 179 _iteratorError = err; 180 } finally { 181 try { 182 if (!_iteratorNormalCompletion && _iterator.return) { 183 _iterator.return(); 184 } 185 } finally { 186 if (_didIteratorError) { 187 throw _iteratorError; 188 } 189 } 190 } 191 } 192 193 /***/ }), 194 /* 3 */ 195 /***/ (function(module, exports, __webpack_require__) { 196 197 "use strict"; 198 199 200 var docsearch = __webpack_require__(13); 201 docsearch({ 202 apiKey: '167e7998590aebda7f9fedcf86bc4a55', 203 indexName: 'hugodocs', 204 inputSelector: '#search-input', 205 debug: true // Set debug to true if you want to inspect the dropdown 206 }); 207 208 /***/ }), 209 /* 4 */ 210 /***/ (function(module, exports, __webpack_require__) { 211 212 "use strict"; 213 214 215 var lazysizes = __webpack_require__(14); 216 // var lsnoscript = require('lazysizes/plugins/noscript/ls.noscript.js'); 217 var unveilhooks = __webpack_require__(15); 218 219 /***/ }), 220 /* 5 */ 221 /***/ (function(module, exports, __webpack_require__) { 222 223 "use strict"; 224 225 226 // Grab any element that has the 'js-toggle' class and add an event listner for the toggleClass function 227 var toggleBtns = document.getElementsByClassName('js-toggle'); 228 for (var i = 0; i < toggleBtns.length; i++) { 229 toggleBtns[i].addEventListener('click', toggleClass, false); 230 } 231 232 function toggleClass() { 233 // Define the data target via the dataset "target" (e.g. data-target=".docsmenu") 234 var content = this.dataset.target.split(' '); 235 // Find any menu items that are open 236 var mobileCurrentlyOpen = document.querySelector('.mobilemenu:not(.dn)'); 237 var desktopCurrentlyOpen = document.querySelector('.desktopmenu:not(.dn)'); 238 var desktopActive = document.querySelector('.desktopmenu:not(.dn)'); 239 240 // Loop through the targets' divs 241 for (var i = 0; i < content.length; i++) { 242 var matches = document.querySelectorAll(content[i]); 243 //for each, if the div has the 'dn' class (which is "display:none;"), remove it, otherwise, add that class 244 [].forEach.call(matches, function (dom) { 245 dom.classList.contains('dn') ? dom.classList.remove('dn') : dom.classList.add('dn'); 246 return false; 247 }); 248 // close the currently open menu items 249 if (mobileCurrentlyOpen) mobileCurrentlyOpen.classList.add('dn'); 250 if (desktopCurrentlyOpen) desktopCurrentlyOpen.classList.add('dn'); 251 if (desktopActive) desktopActive.classList.remove('db'); 252 } 253 } 254 255 /***/ }), 256 /* 6 */ 257 /***/ (function(module, exports, __webpack_require__) { 258 259 "use strict"; 260 261 262 document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/, 'js'); 263 264 /***/ }), 265 /* 7 */ 266 /***/ (function(module, exports, __webpack_require__) { 267 268 "use strict"; 269 270 271 var scrollDir = __webpack_require__(16); 272 273 /***/ }), 274 /* 8 */ 275 /***/ (function(module, exports, __webpack_require__) { 276 277 "use strict"; 278 279 280 // query selector targets Hugo TOC 281 (function () { 282 283 'use strict'; 284 285 // Feature Test 286 287 if ('querySelector' in document && 'addEventListener' in window && Array.prototype.forEach) { 288 289 // Function to animate the scroll 290 var smoothScroll = function smoothScroll(anchor, duration) { 291 292 // Calculate how far and how fast to scroll 293 var startLocation = window.pageYOffset; 294 var endLocation = anchor.offsetTop; 295 var distance = endLocation - startLocation; 296 var increments = distance / (duration / 16); 297 var stopAnimation; 298 299 // Scroll the page by an increment, and check if it's time to stop 300 var animateScroll = function animateScroll() { 301 window.scrollBy(0, increments); 302 stopAnimation(); 303 }; 304 305 // If scrolling down 306 if (increments >= 0) { 307 // Stop animation when you reach the anchor OR the bottom of the page 308 stopAnimation = function stopAnimation() { 309 var travelled = window.pageYOffset; 310 if (travelled >= endLocation - increments || window.innerHeight + travelled >= document.body.offsetHeight) { 311 clearInterval(runAnimation); 312 } 313 }; 314 } 315 // If scrolling up 316 else { 317 // Stop animation when you reach the anchor OR the top of the page 318 stopAnimation = function stopAnimation() { 319 var travelled = window.pageYOffset; 320 if (travelled <= (endLocation || 0)) { 321 clearInterval(runAnimation); 322 } 323 }; 324 } 325 326 // Loop the animation function 327 var runAnimation = setInterval(animateScroll, 16); 328 }; 329 330 // Define smooth scroll links 331 var scrollToggle = document.querySelectorAll('#TableOfContents ul li a'); 332 333 // For each smooth scroll link 334 [].forEach.call(scrollToggle, function (toggle) { 335 336 // When the smooth scroll link is clicked 337 toggle.addEventListener('click', function (e) { 338 339 // Prevent the default link behavior 340 e.preventDefault(); 341 342 // Get anchor link and calculate distance from the top 343 var dataID = toggle.getAttribute('href'); 344 var dataTarget = document.querySelector(dataID); 345 var dataSpeed = toggle.getAttribute('data-speed'); 346 347 // If the anchor exists 348 if (dataTarget) { 349 // Scroll to the anchor 350 smoothScroll(dataTarget, dataSpeed || 500); 351 } 352 }, false); 353 }); 354 } 355 })(); 356 357 /***/ }), 358 /* 9 */ 359 /***/ (function(module, exports, __webpack_require__) { 360 361 "use strict"; 362 363 364 /** 365 * Scripts which manages Code Toggle tabs. 366 */ 367 var i; 368 // store tabs variable 369 var allTabs = document.querySelectorAll("[data-toggle-tab]"); 370 var allPanes = document.querySelectorAll("[data-pane]"); 371 372 function toggleTabs(event) { 373 374 if (event.target) { 375 event.preventDefault(); 376 var clickedTab = event.currentTarget; 377 var targetKey = clickedTab.getAttribute("data-toggle-tab"); 378 } else { 379 var targetKey = event; 380 } 381 // We store the config language selected in users' localStorage 382 if (window.localStorage) { 383 window.localStorage.setItem("configLangPref", targetKey); 384 } 385 var selectedTabs = document.querySelectorAll("[data-toggle-tab='" + targetKey + "']"); 386 var selectedPanes = document.querySelectorAll("[data-pane='" + targetKey + "']"); 387 388 for (var i = 0; i < allTabs.length; i++) { 389 allTabs[i].classList.remove("active"); 390 allPanes[i].classList.remove("active"); 391 } 392 393 for (var i = 0; i < selectedTabs.length; i++) { 394 selectedTabs[i].classList.add("active"); 395 selectedPanes[i].classList.add("active"); 396 } 397 } 398 399 for (i = 0; i < allTabs.length; i++) { 400 allTabs[i].addEventListener("click", toggleTabs); 401 } 402 // Upon page load, if user has a preferred language in its localStorage, tabs are set to it. 403 if (window.localStorage.getItem('configLangPref')) { 404 toggleTabs(window.localStorage.getItem('configLangPref')); 405 } 406 407 /***/ }), 408 /* 10 */ 409 /***/ (function(module, exports) { 410 411 // removed by extract-text-webpack-plugin 412 413 /***/ }), 414 /* 11 */ 415 /***/ (function(module, exports, __webpack_require__) { 416 417 "use strict"; 418 419 420 var _main = __webpack_require__(10); 421 422 var _main2 = _interopRequireDefault(_main); 423 424 __webpack_require__(0); 425 426 __webpack_require__(1); 427 428 __webpack_require__(2); 429 430 __webpack_require__(3); 431 432 __webpack_require__(4); 433 434 __webpack_require__(5); 435 436 __webpack_require__(7); 437 438 __webpack_require__(8); 439 440 __webpack_require__(9); 441 442 __webpack_require__(6); 443 444 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 445 446 /***/ }), 447 /* 12 */ 448 /***/ (function(module, exports, __webpack_require__) { 449 450 var require;var require;/*! 451 * clipboard.js v1.7.1 452 * https://zenorocha.github.io/clipboard.js 453 * 454 * Licensed MIT © Zeno Rocha 455 */ 456 (function(f){if(true){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Clipboard = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return require(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ 457 var DOCUMENT_NODE_TYPE = 9; 458 459 /** 460 * A polyfill for Element.matches() 461 */ 462 if (typeof Element !== 'undefined' && !Element.prototype.matches) { 463 var proto = Element.prototype; 464 465 proto.matches = proto.matchesSelector || 466 proto.mozMatchesSelector || 467 proto.msMatchesSelector || 468 proto.oMatchesSelector || 469 proto.webkitMatchesSelector; 470 } 471 472 /** 473 * Finds the closest parent that matches a selector. 474 * 475 * @param {Element} element 476 * @param {String} selector 477 * @return {Function} 478 */ 479 function closest (element, selector) { 480 while (element && element.nodeType !== DOCUMENT_NODE_TYPE) { 481 if (typeof element.matches === 'function' && 482 element.matches(selector)) { 483 return element; 484 } 485 element = element.parentNode; 486 } 487 } 488 489 module.exports = closest; 490 491 },{}],2:[function(require,module,exports){ 492 var closest = require('./closest'); 493 494 /** 495 * Delegates event to a selector. 496 * 497 * @param {Element} element 498 * @param {String} selector 499 * @param {String} type 500 * @param {Function} callback 501 * @param {Boolean} useCapture 502 * @return {Object} 503 */ 504 function delegate(element, selector, type, callback, useCapture) { 505 var listenerFn = listener.apply(this, arguments); 506 507 element.addEventListener(type, listenerFn, useCapture); 508 509 return { 510 destroy: function() { 511 element.removeEventListener(type, listenerFn, useCapture); 512 } 513 } 514 } 515 516 /** 517 * Finds closest match and invokes callback. 518 * 519 * @param {Element} element 520 * @param {String} selector 521 * @param {String} type 522 * @param {Function} callback 523 * @return {Function} 524 */ 525 function listener(element, selector, type, callback) { 526 return function(e) { 527 e.delegateTarget = closest(e.target, selector); 528 529 if (e.delegateTarget) { 530 callback.call(element, e); 531 } 532 } 533 } 534 535 module.exports = delegate; 536 537 },{"./closest":1}],3:[function(require,module,exports){ 538 /** 539 * Check if argument is a HTML element. 540 * 541 * @param {Object} value 542 * @return {Boolean} 543 */ 544 exports.node = function(value) { 545 return value !== undefined 546 && value instanceof HTMLElement 547 && value.nodeType === 1; 548 }; 549 550 /** 551 * Check if argument is a list of HTML elements. 552 * 553 * @param {Object} value 554 * @return {Boolean} 555 */ 556 exports.nodeList = function(value) { 557 var type = Object.prototype.toString.call(value); 558 559 return value !== undefined 560 && (type === '[object NodeList]' || type === '[object HTMLCollection]') 561 && ('length' in value) 562 && (value.length === 0 || exports.node(value[0])); 563 }; 564 565 /** 566 * Check if argument is a string. 567 * 568 * @param {Object} value 569 * @return {Boolean} 570 */ 571 exports.string = function(value) { 572 return typeof value === 'string' 573 || value instanceof String; 574 }; 575 576 /** 577 * Check if argument is a function. 578 * 579 * @param {Object} value 580 * @return {Boolean} 581 */ 582 exports.fn = function(value) { 583 var type = Object.prototype.toString.call(value); 584 585 return type === '[object Function]'; 586 }; 587 588 },{}],4:[function(require,module,exports){ 589 var is = require('./is'); 590 var delegate = require('delegate'); 591 592 /** 593 * Validates all params and calls the right 594 * listener function based on its target type. 595 * 596 * @param {String|HTMLElement|HTMLCollection|NodeList} target 597 * @param {String} type 598 * @param {Function} callback 599 * @return {Object} 600 */ 601 function listen(target, type, callback) { 602 if (!target && !type && !callback) { 603 throw new Error('Missing required arguments'); 604 } 605 606 if (!is.string(type)) { 607 throw new TypeError('Second argument must be a String'); 608 } 609 610 if (!is.fn(callback)) { 611 throw new TypeError('Third argument must be a Function'); 612 } 613 614 if (is.node(target)) { 615 return listenNode(target, type, callback); 616 } 617 else if (is.nodeList(target)) { 618 return listenNodeList(target, type, callback); 619 } 620 else if (is.string(target)) { 621 return listenSelector(target, type, callback); 622 } 623 else { 624 throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList'); 625 } 626 } 627 628 /** 629 * Adds an event listener to a HTML element 630 * and returns a remove listener function. 631 * 632 * @param {HTMLElement} node 633 * @param {String} type 634 * @param {Function} callback 635 * @return {Object} 636 */ 637 function listenNode(node, type, callback) { 638 node.addEventListener(type, callback); 639 640 return { 641 destroy: function() { 642 node.removeEventListener(type, callback); 643 } 644 } 645 } 646 647 /** 648 * Add an event listener to a list of HTML elements 649 * and returns a remove listener function. 650 * 651 * @param {NodeList|HTMLCollection} nodeList 652 * @param {String} type 653 * @param {Function} callback 654 * @return {Object} 655 */ 656 function listenNodeList(nodeList, type, callback) { 657 Array.prototype.forEach.call(nodeList, function(node) { 658 node.addEventListener(type, callback); 659 }); 660 661 return { 662 destroy: function() { 663 Array.prototype.forEach.call(nodeList, function(node) { 664 node.removeEventListener(type, callback); 665 }); 666 } 667 } 668 } 669 670 /** 671 * Add an event listener to a selector 672 * and returns a remove listener function. 673 * 674 * @param {String} selector 675 * @param {String} type 676 * @param {Function} callback 677 * @return {Object} 678 */ 679 function listenSelector(selector, type, callback) { 680 return delegate(document.body, selector, type, callback); 681 } 682 683 module.exports = listen; 684 685 },{"./is":3,"delegate":2}],5:[function(require,module,exports){ 686 function select(element) { 687 var selectedText; 688 689 if (element.nodeName === 'SELECT') { 690 element.focus(); 691 692 selectedText = element.value; 693 } 694 else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') { 695 var isReadOnly = element.hasAttribute('readonly'); 696 697 if (!isReadOnly) { 698 element.setAttribute('readonly', ''); 699 } 700 701 element.select(); 702 element.setSelectionRange(0, element.value.length); 703 704 if (!isReadOnly) { 705 element.removeAttribute('readonly'); 706 } 707 708 selectedText = element.value; 709 } 710 else { 711 if (element.hasAttribute('contenteditable')) { 712 element.focus(); 713 } 714 715 var selection = window.getSelection(); 716 var range = document.createRange(); 717 718 range.selectNodeContents(element); 719 selection.removeAllRanges(); 720 selection.addRange(range); 721 722 selectedText = selection.toString(); 723 } 724 725 return selectedText; 726 } 727 728 module.exports = select; 729 730 },{}],6:[function(require,module,exports){ 731 function E () { 732 // Keep this empty so it's easier to inherit from 733 // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3) 734 } 735 736 E.prototype = { 737 on: function (name, callback, ctx) { 738 var e = this.e || (this.e = {}); 739 740 (e[name] || (e[name] = [])).push({ 741 fn: callback, 742 ctx: ctx 743 }); 744 745 return this; 746 }, 747 748 once: function (name, callback, ctx) { 749 var self = this; 750 function listener () { 751 self.off(name, listener); 752 callback.apply(ctx, arguments); 753 }; 754 755 listener._ = callback 756 return this.on(name, listener, ctx); 757 }, 758 759 emit: function (name) { 760 var data = [].slice.call(arguments, 1); 761 var evtArr = ((this.e || (this.e = {}))[name] || []).slice(); 762 var i = 0; 763 var len = evtArr.length; 764 765 for (i; i < len; i++) { 766 evtArr[i].fn.apply(evtArr[i].ctx, data); 767 } 768 769 return this; 770 }, 771 772 off: function (name, callback) { 773 var e = this.e || (this.e = {}); 774 var evts = e[name]; 775 var liveEvents = []; 776 777 if (evts && callback) { 778 for (var i = 0, len = evts.length; i < len; i++) { 779 if (evts[i].fn !== callback && evts[i].fn._ !== callback) 780 liveEvents.push(evts[i]); 781 } 782 } 783 784 // Remove event from queue to prevent memory leak 785 // Suggested by https://github.com/lazd 786 // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910 787 788 (liveEvents.length) 789 ? e[name] = liveEvents 790 : delete e[name]; 791 792 return this; 793 } 794 }; 795 796 module.exports = E; 797 798 },{}],7:[function(require,module,exports){ 799 (function (global, factory) { 800 if (typeof define === "function" && define.amd) { 801 define(['module', 'select'], factory); 802 } else if (typeof exports !== "undefined") { 803 factory(module, require('select')); 804 } else { 805 var mod = { 806 exports: {} 807 }; 808 factory(mod, global.select); 809 global.clipboardAction = mod.exports; 810 } 811 })(this, function (module, _select) { 812 'use strict'; 813 814 var _select2 = _interopRequireDefault(_select); 815 816 function _interopRequireDefault(obj) { 817 return obj && obj.__esModule ? obj : { 818 default: obj 819 }; 820 } 821 822 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { 823 return typeof obj; 824 } : function (obj) { 825 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 826 }; 827 828 function _classCallCheck(instance, Constructor) { 829 if (!(instance instanceof Constructor)) { 830 throw new TypeError("Cannot call a class as a function"); 831 } 832 } 833 834 var _createClass = function () { 835 function defineProperties(target, props) { 836 for (var i = 0; i < props.length; i++) { 837 var descriptor = props[i]; 838 descriptor.enumerable = descriptor.enumerable || false; 839 descriptor.configurable = true; 840 if ("value" in descriptor) descriptor.writable = true; 841 Object.defineProperty(target, descriptor.key, descriptor); 842 } 843 } 844 845 return function (Constructor, protoProps, staticProps) { 846 if (protoProps) defineProperties(Constructor.prototype, protoProps); 847 if (staticProps) defineProperties(Constructor, staticProps); 848 return Constructor; 849 }; 850 }(); 851 852 var ClipboardAction = function () { 853 /** 854 * @param {Object} options 855 */ 856 function ClipboardAction(options) { 857 _classCallCheck(this, ClipboardAction); 858 859 this.resolveOptions(options); 860 this.initSelection(); 861 } 862 863 /** 864 * Defines base properties passed from constructor. 865 * @param {Object} options 866 */ 867 868 869 _createClass(ClipboardAction, [{ 870 key: 'resolveOptions', 871 value: function resolveOptions() { 872 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 873 874 this.action = options.action; 875 this.container = options.container; 876 this.emitter = options.emitter; 877 this.target = options.target; 878 this.text = options.text; 879 this.trigger = options.trigger; 880 881 this.selectedText = ''; 882 } 883 }, { 884 key: 'initSelection', 885 value: function initSelection() { 886 if (this.text) { 887 this.selectFake(); 888 } else if (this.target) { 889 this.selectTarget(); 890 } 891 } 892 }, { 893 key: 'selectFake', 894 value: function selectFake() { 895 var _this = this; 896 897 var isRTL = document.documentElement.getAttribute('dir') == 'rtl'; 898 899 this.removeFake(); 900 901 this.fakeHandlerCallback = function () { 902 return _this.removeFake(); 903 }; 904 this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || true; 905 906 this.fakeElem = document.createElement('textarea'); 907 // Prevent zooming on iOS 908 this.fakeElem.style.fontSize = '12pt'; 909 // Reset box model 910 this.fakeElem.style.border = '0'; 911 this.fakeElem.style.padding = '0'; 912 this.fakeElem.style.margin = '0'; 913 // Move element out of screen horizontally 914 this.fakeElem.style.position = 'absolute'; 915 this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; 916 // Move element to the same position vertically 917 var yPosition = window.pageYOffset || document.documentElement.scrollTop; 918 this.fakeElem.style.top = yPosition + 'px'; 919 920 this.fakeElem.setAttribute('readonly', ''); 921 this.fakeElem.value = this.text; 922 923 this.container.appendChild(this.fakeElem); 924 925 this.selectedText = (0, _select2.default)(this.fakeElem); 926 this.copyText(); 927 } 928 }, { 929 key: 'removeFake', 930 value: function removeFake() { 931 if (this.fakeHandler) { 932 this.container.removeEventListener('click', this.fakeHandlerCallback); 933 this.fakeHandler = null; 934 this.fakeHandlerCallback = null; 935 } 936 937 if (this.fakeElem) { 938 this.container.removeChild(this.fakeElem); 939 this.fakeElem = null; 940 } 941 } 942 }, { 943 key: 'selectTarget', 944 value: function selectTarget() { 945 this.selectedText = (0, _select2.default)(this.target); 946 this.copyText(); 947 } 948 }, { 949 key: 'copyText', 950 value: function copyText() { 951 var succeeded = void 0; 952 953 try { 954 succeeded = document.execCommand(this.action); 955 } catch (err) { 956 succeeded = false; 957 } 958 959 this.handleResult(succeeded); 960 } 961 }, { 962 key: 'handleResult', 963 value: function handleResult(succeeded) { 964 this.emitter.emit(succeeded ? 'success' : 'error', { 965 action: this.action, 966 text: this.selectedText, 967 trigger: this.trigger, 968 clearSelection: this.clearSelection.bind(this) 969 }); 970 } 971 }, { 972 key: 'clearSelection', 973 value: function clearSelection() { 974 if (this.trigger) { 975 this.trigger.focus(); 976 } 977 978 window.getSelection().removeAllRanges(); 979 } 980 }, { 981 key: 'destroy', 982 value: function destroy() { 983 this.removeFake(); 984 } 985 }, { 986 key: 'action', 987 set: function set() { 988 var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy'; 989 990 this._action = action; 991 992 if (this._action !== 'copy' && this._action !== 'cut') { 993 throw new Error('Invalid "action" value, use either "copy" or "cut"'); 994 } 995 }, 996 get: function get() { 997 return this._action; 998 } 999 }, { 1000 key: 'target', 1001 set: function set(target) { 1002 if (target !== undefined) { 1003 if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) { 1004 if (this.action === 'copy' && target.hasAttribute('disabled')) { 1005 throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute'); 1006 } 1007 1008 if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) { 1009 throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes'); 1010 } 1011 1012 this._target = target; 1013 } else { 1014 throw new Error('Invalid "target" value, use a valid Element'); 1015 } 1016 } 1017 }, 1018 get: function get() { 1019 return this._target; 1020 } 1021 }]); 1022 1023 return ClipboardAction; 1024 }(); 1025 1026 module.exports = ClipboardAction; 1027 }); 1028 1029 },{"select":5}],8:[function(require,module,exports){ 1030 (function (global, factory) { 1031 if (typeof define === "function" && define.amd) { 1032 define(['module', './clipboard-action', 'tiny-emitter', 'good-listener'], factory); 1033 } else if (typeof exports !== "undefined") { 1034 factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener')); 1035 } else { 1036 var mod = { 1037 exports: {} 1038 }; 1039 factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener); 1040 global.clipboard = mod.exports; 1041 } 1042 })(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) { 1043 'use strict'; 1044 1045 var _clipboardAction2 = _interopRequireDefault(_clipboardAction); 1046 1047 var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter); 1048 1049 var _goodListener2 = _interopRequireDefault(_goodListener); 1050 1051 function _interopRequireDefault(obj) { 1052 return obj && obj.__esModule ? obj : { 1053 default: obj 1054 }; 1055 } 1056 1057 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { 1058 return typeof obj; 1059 } : function (obj) { 1060 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 1061 }; 1062 1063 function _classCallCheck(instance, Constructor) { 1064 if (!(instance instanceof Constructor)) { 1065 throw new TypeError("Cannot call a class as a function"); 1066 } 1067 } 1068 1069 var _createClass = function () { 1070 function defineProperties(target, props) { 1071 for (var i = 0; i < props.length; i++) { 1072 var descriptor = props[i]; 1073 descriptor.enumerable = descriptor.enumerable || false; 1074 descriptor.configurable = true; 1075 if ("value" in descriptor) descriptor.writable = true; 1076 Object.defineProperty(target, descriptor.key, descriptor); 1077 } 1078 } 1079 1080 return function (Constructor, protoProps, staticProps) { 1081 if (protoProps) defineProperties(Constructor.prototype, protoProps); 1082 if (staticProps) defineProperties(Constructor, staticProps); 1083 return Constructor; 1084 }; 1085 }(); 1086 1087 function _possibleConstructorReturn(self, call) { 1088 if (!self) { 1089 throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 1090 } 1091 1092 return call && (typeof call === "object" || typeof call === "function") ? call : self; 1093 } 1094 1095 function _inherits(subClass, superClass) { 1096 if (typeof superClass !== "function" && superClass !== null) { 1097 throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); 1098 } 1099 1100 subClass.prototype = Object.create(superClass && superClass.prototype, { 1101 constructor: { 1102 value: subClass, 1103 enumerable: false, 1104 writable: true, 1105 configurable: true 1106 } 1107 }); 1108 if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; 1109 } 1110 1111 var Clipboard = function (_Emitter) { 1112 _inherits(Clipboard, _Emitter); 1113 1114 /** 1115 * @param {String|HTMLElement|HTMLCollection|NodeList} trigger 1116 * @param {Object} options 1117 */ 1118 function Clipboard(trigger, options) { 1119 _classCallCheck(this, Clipboard); 1120 1121 var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this)); 1122 1123 _this.resolveOptions(options); 1124 _this.listenClick(trigger); 1125 return _this; 1126 } 1127 1128 /** 1129 * Defines if attributes would be resolved using internal setter functions 1130 * or custom functions that were passed in the constructor. 1131 * @param {Object} options 1132 */ 1133 1134 1135 _createClass(Clipboard, [{ 1136 key: 'resolveOptions', 1137 value: function resolveOptions() { 1138 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 1139 1140 this.action = typeof options.action === 'function' ? options.action : this.defaultAction; 1141 this.target = typeof options.target === 'function' ? options.target : this.defaultTarget; 1142 this.text = typeof options.text === 'function' ? options.text : this.defaultText; 1143 this.container = _typeof(options.container) === 'object' ? options.container : document.body; 1144 } 1145 }, { 1146 key: 'listenClick', 1147 value: function listenClick(trigger) { 1148 var _this2 = this; 1149 1150 this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) { 1151 return _this2.onClick(e); 1152 }); 1153 } 1154 }, { 1155 key: 'onClick', 1156 value: function onClick(e) { 1157 var trigger = e.delegateTarget || e.currentTarget; 1158 1159 if (this.clipboardAction) { 1160 this.clipboardAction = null; 1161 } 1162 1163 this.clipboardAction = new _clipboardAction2.default({ 1164 action: this.action(trigger), 1165 target: this.target(trigger), 1166 text: this.text(trigger), 1167 container: this.container, 1168 trigger: trigger, 1169 emitter: this 1170 }); 1171 } 1172 }, { 1173 key: 'defaultAction', 1174 value: function defaultAction(trigger) { 1175 return getAttributeValue('action', trigger); 1176 } 1177 }, { 1178 key: 'defaultTarget', 1179 value: function defaultTarget(trigger) { 1180 var selector = getAttributeValue('target', trigger); 1181 1182 if (selector) { 1183 return document.querySelector(selector); 1184 } 1185 } 1186 }, { 1187 key: 'defaultText', 1188 value: function defaultText(trigger) { 1189 return getAttributeValue('text', trigger); 1190 } 1191 }, { 1192 key: 'destroy', 1193 value: function destroy() { 1194 this.listener.destroy(); 1195 1196 if (this.clipboardAction) { 1197 this.clipboardAction.destroy(); 1198 this.clipboardAction = null; 1199 } 1200 } 1201 }], [{ 1202 key: 'isSupported', 1203 value: function isSupported() { 1204 var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut']; 1205 1206 var actions = typeof action === 'string' ? [action] : action; 1207 var support = !!document.queryCommandSupported; 1208 1209 actions.forEach(function (action) { 1210 support = support && !!document.queryCommandSupported(action); 1211 }); 1212 1213 return support; 1214 } 1215 }]); 1216 1217 return Clipboard; 1218 }(_tinyEmitter2.default); 1219 1220 /** 1221 * Helper function to retrieve attribute value. 1222 * @param {String} suffix 1223 * @param {Element} element 1224 */ 1225 function getAttributeValue(suffix, element) { 1226 var attribute = 'data-clipboard-' + suffix; 1227 1228 if (!element.hasAttribute(attribute)) { 1229 return; 1230 } 1231 1232 return element.getAttribute(attribute); 1233 } 1234 1235 module.exports = Clipboard; 1236 }); 1237 1238 },{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8) 1239 }); 1240 1241 /***/ }), 1242 /* 13 */ 1243 /***/ (function(module, exports, __webpack_require__) { 1244 1245 /*! docsearch 2.3.3 | © Algolia | github.com/algolia/docsearch */ 1246 (function webpackUniversalModuleDefinition(root, factory) { 1247 if(true) 1248 module.exports = factory(); 1249 else if(typeof define === 'function' && define.amd) 1250 define([], factory); 1251 else if(typeof exports === 'object') 1252 exports["docsearch"] = factory(); 1253 else 1254 root["docsearch"] = factory(); 1255 })(this, function() { 1256 return /******/ (function(modules) { // webpackBootstrap 1257 /******/ // The module cache 1258 /******/ var installedModules = {}; 1259 /******/ 1260 /******/ // The require function 1261 /******/ function __webpack_require__(moduleId) { 1262 /******/ 1263 /******/ // Check if module is in cache 1264 /******/ if(installedModules[moduleId]) 1265 /******/ return installedModules[moduleId].exports; 1266 /******/ 1267 /******/ // Create a new module (and put it into the cache) 1268 /******/ var module = installedModules[moduleId] = { 1269 /******/ i: moduleId, 1270 /******/ l: false, 1271 /******/ exports: {} 1272 /******/ }; 1273 /******/ 1274 /******/ // Execute the module function 1275 /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 1276 /******/ 1277 /******/ // Flag the module as loaded 1278 /******/ module.l = true; 1279 /******/ 1280 /******/ // Return the exports of the module 1281 /******/ return module.exports; 1282 /******/ } 1283 /******/ 1284 /******/ 1285 /******/ // expose the modules object (__webpack_modules__) 1286 /******/ __webpack_require__.m = modules; 1287 /******/ 1288 /******/ // expose the module cache 1289 /******/ __webpack_require__.c = installedModules; 1290 /******/ 1291 /******/ // identity function for calling harmony imports with the correct context 1292 /******/ __webpack_require__.i = function(value) { return value; }; 1293 /******/ 1294 /******/ // define getter function for harmony exports 1295 /******/ __webpack_require__.d = function(exports, name, getter) { 1296 /******/ if(!__webpack_require__.o(exports, name)) { 1297 /******/ Object.defineProperty(exports, name, { 1298 /******/ configurable: false, 1299 /******/ enumerable: true, 1300 /******/ get: getter 1301 /******/ }); 1302 /******/ } 1303 /******/ }; 1304 /******/ 1305 /******/ // getDefaultExport function for compatibility with non-harmony modules 1306 /******/ __webpack_require__.n = function(module) { 1307 /******/ var getter = module && module.__esModule ? 1308 /******/ function getDefault() { return module['default']; } : 1309 /******/ function getModuleExports() { return module; }; 1310 /******/ __webpack_require__.d(getter, 'a', getter); 1311 /******/ return getter; 1312 /******/ }; 1313 /******/ 1314 /******/ // Object.prototype.hasOwnProperty.call 1315 /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 1316 /******/ 1317 /******/ // __webpack_public_path__ 1318 /******/ __webpack_require__.p = ""; 1319 /******/ 1320 /******/ // Load entry module and return exports 1321 /******/ return __webpack_require__(__webpack_require__.s = 46); 1322 /******/ }) 1323 /************************************************************************/ 1324 /******/ ([ 1325 /* 0 */ 1326 /***/ (function(module, exports, __webpack_require__) { 1327 1328 "use strict"; 1329 1330 1331 var DOM = __webpack_require__(1); 1332 1333 function escapeRegExp(str) { 1334 return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); 1335 } 1336 1337 module.exports = { 1338 // those methods are implemented differently 1339 // depending on which build it is, using 1340 // $... or angular... or Zepto... or require(...) 1341 isArray: null, 1342 isFunction: null, 1343 isObject: null, 1344 bind: null, 1345 each: null, 1346 map: null, 1347 mixin: null, 1348 1349 isMsie: function() { 1350 // from https://github.com/ded/bowser/blob/master/bowser.js 1351 return (/(msie|trident)/i).test(navigator.userAgent) ? 1352 navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false; 1353 }, 1354 1355 // http://stackoverflow.com/a/6969486 1356 escapeRegExChars: function(str) { 1357 return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); 1358 }, 1359 1360 isNumber: function(obj) { return typeof obj === 'number'; }, 1361 1362 toStr: function toStr(s) { 1363 return s === undefined || s === null ? '' : s + ''; 1364 }, 1365 1366 cloneDeep: function cloneDeep(obj) { 1367 var clone = this.mixin({}, obj); 1368 var self = this; 1369 this.each(clone, function(value, key) { 1370 if (value) { 1371 if (self.isArray(value)) { 1372 clone[key] = [].concat(value); 1373 } else if (self.isObject(value)) { 1374 clone[key] = self.cloneDeep(value); 1375 } 1376 } 1377 }); 1378 return clone; 1379 }, 1380 1381 error: function(msg) { 1382 throw new Error(msg); 1383 }, 1384 1385 every: function(obj, test) { 1386 var result = true; 1387 if (!obj) { 1388 return result; 1389 } 1390 this.each(obj, function(val, key) { 1391 result = test.call(null, val, key, obj); 1392 if (!result) { 1393 return false; 1394 } 1395 }); 1396 return !!result; 1397 }, 1398 1399 any: function(obj, test) { 1400 var found = false; 1401 if (!obj) { 1402 return found; 1403 } 1404 this.each(obj, function(val, key) { 1405 if (test.call(null, val, key, obj)) { 1406 found = true; 1407 return false; 1408 } 1409 }); 1410 return found; 1411 }, 1412 1413 getUniqueId: (function() { 1414 var counter = 0; 1415 return function() { return counter++; }; 1416 })(), 1417 1418 templatify: function templatify(obj) { 1419 if (this.isFunction(obj)) { 1420 return obj; 1421 } 1422 var $template = DOM.element(obj); 1423 if ($template.prop('tagName') === 'SCRIPT') { 1424 return function template() { return $template.text(); }; 1425 } 1426 return function template() { return String(obj); }; 1427 }, 1428 1429 defer: function(fn) { setTimeout(fn, 0); }, 1430 1431 noop: function() {}, 1432 1433 formatPrefix: function(prefix, noPrefix) { 1434 return noPrefix ? '' : prefix + '-'; 1435 }, 1436 1437 className: function(prefix, clazz, skipDot) { 1438 return (skipDot ? '' : '.') + prefix + clazz; 1439 }, 1440 1441 escapeHighlightedString: function(str, highlightPreTag, highlightPostTag) { 1442 highlightPreTag = highlightPreTag || '<em>'; 1443 var pre = document.createElement('div'); 1444 pre.appendChild(document.createTextNode(highlightPreTag)); 1445 1446 highlightPostTag = highlightPostTag || '</em>'; 1447 var post = document.createElement('div'); 1448 post.appendChild(document.createTextNode(highlightPostTag)); 1449 1450 var div = document.createElement('div'); 1451 div.appendChild(document.createTextNode(str)); 1452 return div.innerHTML 1453 .replace(RegExp(escapeRegExp(pre.innerHTML), 'g'), highlightPreTag) 1454 .replace(RegExp(escapeRegExp(post.innerHTML), 'g'), highlightPostTag); 1455 } 1456 }; 1457 1458 1459 /***/ }), 1460 /* 1 */ 1461 /***/ (function(module, exports, __webpack_require__) { 1462 1463 "use strict"; 1464 1465 1466 module.exports = { 1467 element: null 1468 }; 1469 1470 1471 /***/ }), 1472 /* 2 */ 1473 /***/ (function(module, exports) { 1474 1475 1476 var hasOwn = Object.prototype.hasOwnProperty; 1477 var toString = Object.prototype.toString; 1478 1479 module.exports = function forEach (obj, fn, ctx) { 1480 if (toString.call(fn) !== '[object Function]') { 1481 throw new TypeError('iterator must be a function'); 1482 } 1483 var l = obj.length; 1484 if (l === +l) { 1485 for (var i = 0; i < l; i++) { 1486 fn.call(ctx, obj[i], i, obj); 1487 } 1488 } else { 1489 for (var k in obj) { 1490 if (hasOwn.call(obj, k)) { 1491 fn.call(ctx, obj[k], k, obj); 1492 } 1493 } 1494 } 1495 }; 1496 1497 1498 1499 /***/ }), 1500 /* 3 */ 1501 /***/ (function(module, exports) { 1502 1503 var g; 1504 1505 // This works in non-strict mode 1506 g = (function() { 1507 return this; 1508 })(); 1509 1510 try { 1511 // This works if eval is allowed (see CSP) 1512 g = g || Function("return this")() || (1,eval)("this"); 1513 } catch(e) { 1514 // This works if the window reference is available 1515 if(typeof window === "object") 1516 g = window; 1517 } 1518 1519 // g can still be undefined, but nothing to do about it... 1520 // We return undefined, instead of nothing here, so it's 1521 // easier to handle this case. if(!global) { ...} 1522 1523 module.exports = g; 1524 1525 1526 /***/ }), 1527 /* 4 */ 1528 /***/ (function(module, exports) { 1529 1530 module.exports = function clone(obj) { 1531 return JSON.parse(JSON.stringify(obj)); 1532 }; 1533 1534 1535 /***/ }), 1536 /* 5 */ 1537 /***/ (function(module, exports, __webpack_require__) { 1538 1539 "use strict"; 1540 1541 1542 // This file hosts our error definitions 1543 // We use custom error "types" so that we can act on them when we need it 1544 // e.g.: if error instanceof errors.UnparsableJSON then.. 1545 1546 var inherits = __webpack_require__(20); 1547 1548 function AlgoliaSearchError(message, extraProperties) { 1549 var forEach = __webpack_require__(2); 1550 1551 var error = this; 1552 1553 // try to get a stacktrace 1554 if (typeof Error.captureStackTrace === 'function') { 1555 Error.captureStackTrace(this, this.constructor); 1556 } else { 1557 error.stack = (new Error()).stack || 'Cannot get a stacktrace, browser is too old'; 1558 } 1559 1560 this.name = 'AlgoliaSearchError'; 1561 this.message = message || 'Unknown error'; 1562 1563 if (extraProperties) { 1564 forEach(extraProperties, function addToErrorObject(value, key) { 1565 error[key] = value; 1566 }); 1567 } 1568 } 1569 1570 inherits(AlgoliaSearchError, Error); 1571 1572 function createCustomError(name, message) { 1573 function AlgoliaSearchCustomError() { 1574 var args = Array.prototype.slice.call(arguments, 0); 1575 1576 // custom message not set, use default 1577 if (typeof args[0] !== 'string') { 1578 args.unshift(message); 1579 } 1580 1581 AlgoliaSearchError.apply(this, args); 1582 this.name = 'AlgoliaSearch' + name + 'Error'; 1583 } 1584 1585 inherits(AlgoliaSearchCustomError, AlgoliaSearchError); 1586 1587 return AlgoliaSearchCustomError; 1588 } 1589 1590 // late exports to let various fn defs and inherits take place 1591 module.exports = { 1592 AlgoliaSearchError: AlgoliaSearchError, 1593 UnparsableJSON: createCustomError( 1594 'UnparsableJSON', 1595 'Could not parse the incoming response as JSON, see err.more for details' 1596 ), 1597 RequestTimeout: createCustomError( 1598 'RequestTimeout', 1599 'Request timedout before getting a response' 1600 ), 1601 Network: createCustomError( 1602 'Network', 1603 'Network issue, see err.more for details' 1604 ), 1605 JSONPScriptFail: createCustomError( 1606 'JSONPScriptFail', 1607 '<script> was loaded but did not call our provided callback' 1608 ), 1609 JSONPScriptError: createCustomError( 1610 'JSONPScriptError', 1611 '<script> unable to load due to an `error` event on it' 1612 ), 1613 Unknown: createCustomError( 1614 'Unknown', 1615 'Unknown error occured' 1616 ) 1617 }; 1618 1619 1620 /***/ }), 1621 /* 6 */ 1622 /***/ (function(module, exports, __webpack_require__) { 1623 1624 /* WEBPACK VAR INJECTION */(function(process) { 1625 /** 1626 * This is the web browser implementation of `debug()`. 1627 * 1628 * Expose `debug()` as the module. 1629 */ 1630 1631 exports = module.exports = __webpack_require__(50); 1632 exports.log = log; 1633 exports.formatArgs = formatArgs; 1634 exports.save = save; 1635 exports.load = load; 1636 exports.useColors = useColors; 1637 exports.storage = 'undefined' != typeof chrome 1638 && 'undefined' != typeof chrome.storage 1639 ? chrome.storage.local 1640 : localstorage(); 1641 1642 /** 1643 * Colors. 1644 */ 1645 1646 exports.colors = [ 1647 'lightseagreen', 1648 'forestgreen', 1649 'goldenrod', 1650 'dodgerblue', 1651 'darkorchid', 1652 'crimson' 1653 ]; 1654 1655 /** 1656 * Currently only WebKit-based Web Inspectors, Firefox >= v31, 1657 * and the Firebug extension (any Firefox version) are known 1658 * to support "%c" CSS customizations. 1659 * 1660 * TODO: add a `localStorage` variable to explicitly enable/disable colors 1661 */ 1662 1663 function useColors() { 1664 // is webkit? http://stackoverflow.com/a/16459606/376773 1665 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 1666 return (typeof document !== 'undefined' && 'WebkitAppearance' in document.documentElement.style) || 1667 // is firebug? http://stackoverflow.com/a/398120/376773 1668 (window.console && (console.firebug || (console.exception && console.table))) || 1669 // is firefox >= v31? 1670 // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages 1671 (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); 1672 } 1673 1674 /** 1675 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. 1676 */ 1677 1678 exports.formatters.j = function(v) { 1679 try { 1680 return JSON.stringify(v); 1681 } catch (err) { 1682 return '[UnexpectedJSONParseError]: ' + err.message; 1683 } 1684 }; 1685 1686 1687 /** 1688 * Colorize log arguments if enabled. 1689 * 1690 * @api public 1691 */ 1692 1693 function formatArgs() { 1694 var args = arguments; 1695 var useColors = this.useColors; 1696 1697 args[0] = (useColors ? '%c' : '') 1698 + this.namespace 1699 + (useColors ? ' %c' : ' ') 1700 + args[0] 1701 + (useColors ? '%c ' : ' ') 1702 + '+' + exports.humanize(this.diff); 1703 1704 if (!useColors) return args; 1705 1706 var c = 'color: ' + this.color; 1707 args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); 1708 1709 // the final "%c" is somewhat tricky, because there could be other 1710 // arguments passed either before or after the %c, so we need to 1711 // figure out the correct index to insert the CSS into 1712 var index = 0; 1713 var lastC = 0; 1714 args[0].replace(/%[a-z%]/g, function(match) { 1715 if ('%%' === match) return; 1716 index++; 1717 if ('%c' === match) { 1718 // we only are interested in the *last* %c 1719 // (the user may have provided their own) 1720 lastC = index; 1721 } 1722 }); 1723 1724 args.splice(lastC, 0, c); 1725 return args; 1726 } 1727 1728 /** 1729 * Invokes `console.log()` when available. 1730 * No-op when `console.log` is not a "function". 1731 * 1732 * @api public 1733 */ 1734 1735 function log() { 1736 // this hackery is required for IE8/9, where 1737 // the `console.log` function doesn't have 'apply' 1738 return 'object' === typeof console 1739 && console.log 1740 && Function.prototype.apply.call(console.log, console, arguments); 1741 } 1742 1743 /** 1744 * Save `namespaces`. 1745 * 1746 * @param {String} namespaces 1747 * @api private 1748 */ 1749 1750 function save(namespaces) { 1751 try { 1752 if (null == namespaces) { 1753 exports.storage.removeItem('debug'); 1754 } else { 1755 exports.storage.debug = namespaces; 1756 } 1757 } catch(e) {} 1758 } 1759 1760 /** 1761 * Load `namespaces`. 1762 * 1763 * @return {String} returns the previously persisted debug modes 1764 * @api private 1765 */ 1766 1767 function load() { 1768 var r; 1769 try { 1770 return exports.storage.debug; 1771 } catch(e) {} 1772 1773 // If debug isn't set in LS, and we're in Electron, try to load $DEBUG 1774 if (typeof process !== 'undefined' && 'env' in process) { 1775 return __webpack_require__.i({"NODE_ENV":"production"}).DEBUG; 1776 } 1777 } 1778 1779 /** 1780 * Enable namespaces listed in `localStorage.debug` initially. 1781 */ 1782 1783 exports.enable(load()); 1784 1785 /** 1786 * Localstorage attempts to return the localstorage. 1787 * 1788 * This is necessary because safari throws 1789 * when a user disables cookies/localstorage 1790 * and you attempt to access it. 1791 * 1792 * @return {LocalStorage} 1793 * @api private 1794 */ 1795 1796 function localstorage(){ 1797 try { 1798 return window.localStorage; 1799 } catch (e) {} 1800 } 1801 1802 /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(11))) 1803 1804 /***/ }), 1805 /* 7 */ 1806 /***/ (function(module, exports) { 1807 1808 var toString = {}.toString; 1809 1810 module.exports = Array.isArray || function (arr) { 1811 return toString.call(arr) == '[object Array]'; 1812 }; 1813 1814 1815 /***/ }), 1816 /* 8 */ 1817 /***/ (function(module, exports, __webpack_require__) { 1818 1819 var foreach = __webpack_require__(2); 1820 1821 module.exports = function map(arr, fn) { 1822 var newArr = []; 1823 foreach(arr, function(item, itemIndex) { 1824 newArr.push(fn(item, itemIndex, arr)); 1825 }); 1826 return newArr; 1827 }; 1828 1829 1830 /***/ }), 1831 /* 9 */ 1832 /***/ (function(module, exports, __webpack_require__) { 1833 1834 "use strict"; 1835 1836 1837 var _ = __webpack_require__(0); 1838 1839 var css = { 1840 wrapper: { 1841 position: 'relative', 1842 display: 'inline-block' 1843 }, 1844 hint: { 1845 position: 'absolute', 1846 top: '0', 1847 left: '0', 1848 borderColor: 'transparent', 1849 boxShadow: 'none', 1850 // #741: fix hint opacity issue on iOS 1851 opacity: '1' 1852 }, 1853 input: { 1854 position: 'relative', 1855 verticalAlign: 'top', 1856 backgroundColor: 'transparent' 1857 }, 1858 inputWithNoHint: { 1859 position: 'relative', 1860 verticalAlign: 'top' 1861 }, 1862 dropdown: { 1863 position: 'absolute', 1864 top: '100%', 1865 left: '0', 1866 zIndex: '100', 1867 display: 'none' 1868 }, 1869 suggestions: { 1870 display: 'block' 1871 }, 1872 suggestion: { 1873 whiteSpace: 'nowrap', 1874 cursor: 'pointer' 1875 }, 1876 suggestionChild: { 1877 whiteSpace: 'normal' 1878 }, 1879 ltr: { 1880 left: '0', 1881 right: 'auto' 1882 }, 1883 rtl: { 1884 left: 'auto', 1885 right: '0' 1886 }, 1887 defaultClasses: { 1888 root: 'algolia-autocomplete', 1889 prefix: 'aa', 1890 noPrefix: false, 1891 dropdownMenu: 'dropdown-menu', 1892 input: 'input', 1893 hint: 'hint', 1894 suggestions: 'suggestions', 1895 suggestion: 'suggestion', 1896 cursor: 'cursor', 1897 dataset: 'dataset', 1898 empty: 'empty' 1899 }, 1900 // will be merged with the default ones if appendTo is used 1901 appendTo: { 1902 wrapper: { 1903 position: 'absolute', 1904 zIndex: '100', 1905 display: 'none' 1906 }, 1907 input: {}, 1908 inputWithNoHint: {}, 1909 dropdown: { 1910 display: 'block' 1911 } 1912 } 1913 }; 1914 1915 // ie specific styling 1916 if (_.isMsie()) { 1917 // ie6-8 (and 9?) doesn't fire hover and click events for elements with 1918 // transparent backgrounds, for a workaround, use 1x1 transparent gif 1919 _.mixin(css.input, { 1920 backgroundImage: 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)' 1921 }); 1922 } 1923 1924 // ie7 and under specific styling 1925 if (_.isMsie() && _.isMsie() <= 7) { 1926 // if someone can tell me why this is necessary to align 1927 // the hint with the query in ie7, i'll send you $5 - @JakeHarding 1928 _.mixin(css.input, {marginTop: '-1px'}); 1929 } 1930 1931 module.exports = css; 1932 1933 1934 /***/ }), 1935 /* 10 */ 1936 /***/ (function(module, exports, __webpack_require__) { 1937 1938 "use strict"; 1939 1940 1941 var immediate = __webpack_require__(56); 1942 var splitter = /\s+/; 1943 1944 module.exports = { 1945 onSync: onSync, 1946 onAsync: onAsync, 1947 off: off, 1948 trigger: trigger 1949 }; 1950 1951 function on(method, types, cb, context) { 1952 var type; 1953 1954 if (!cb) { 1955 return this; 1956 } 1957 1958 types = types.split(splitter); 1959 cb = context ? bindContext(cb, context) : cb; 1960 1961 this._callbacks = this._callbacks || {}; 1962 1963 while (type = types.shift()) { 1964 this._callbacks[type] = this._callbacks[type] || {sync: [], async: []}; 1965 this._callbacks[type][method].push(cb); 1966 } 1967 1968 return this; 1969 } 1970 1971 function onAsync(types, cb, context) { 1972 return on.call(this, 'async', types, cb, context); 1973 } 1974 1975 function onSync(types, cb, context) { 1976 return on.call(this, 'sync', types, cb, context); 1977 } 1978 1979 function off(types) { 1980 var type; 1981 1982 if (!this._callbacks) { 1983 return this; 1984 } 1985 1986 types = types.split(splitter); 1987 1988 while (type = types.shift()) { 1989 delete this._callbacks[type]; 1990 } 1991 1992 return this; 1993 } 1994 1995 function trigger(types) { 1996 var type; 1997 var callbacks; 1998 var args; 1999 var syncFlush; 2000 var asyncFlush; 2001 2002 if (!this._callbacks) { 2003 return this; 2004 } 2005 2006 types = types.split(splitter); 2007 args = [].slice.call(arguments, 1); 2008 2009 while ((type = types.shift()) && (callbacks = this._callbacks[type])) { // eslint-disable-line 2010 syncFlush = getFlush(callbacks.sync, this, [type].concat(args)); 2011 asyncFlush = getFlush(callbacks.async, this, [type].concat(args)); 2012 2013 if (syncFlush()) { 2014 immediate(asyncFlush); 2015 } 2016 } 2017 2018 return this; 2019 } 2020 2021 function getFlush(callbacks, context, args) { 2022 return flush; 2023 2024 function flush() { 2025 var cancelled; 2026 2027 for (var i = 0, len = callbacks.length; !cancelled && i < len; i += 1) { 2028 // only cancel if the callback explicitly returns false 2029 cancelled = callbacks[i].apply(context, args) === false; 2030 } 2031 2032 return !cancelled; 2033 } 2034 } 2035 2036 function bindContext(fn, context) { 2037 return fn.bind ? 2038 fn.bind(context) : 2039 function() { fn.apply(context, [].slice.call(arguments, 0)); }; 2040 } 2041 2042 2043 /***/ }), 2044 /* 11 */ 2045 /***/ (function(module, exports) { 2046 2047 // shim for using process in browser 2048 var process = module.exports = {}; 2049 2050 // cached from whatever global is present so that test runners that stub it 2051 // don't break things. But we need to wrap it in a try catch in case it is 2052 // wrapped in strict mode code which doesn't define any globals. It's inside a 2053 // function because try/catches deoptimize in certain engines. 2054 2055 var cachedSetTimeout; 2056 var cachedClearTimeout; 2057 2058 function defaultSetTimout() { 2059 throw new Error('setTimeout has not been defined'); 2060 } 2061 function defaultClearTimeout () { 2062 throw new Error('clearTimeout has not been defined'); 2063 } 2064 (function () { 2065 try { 2066 if (typeof setTimeout === 'function') { 2067 cachedSetTimeout = setTimeout; 2068 } else { 2069 cachedSetTimeout = defaultSetTimout; 2070 } 2071 } catch (e) { 2072 cachedSetTimeout = defaultSetTimout; 2073 } 2074 try { 2075 if (typeof clearTimeout === 'function') { 2076 cachedClearTimeout = clearTimeout; 2077 } else { 2078 cachedClearTimeout = defaultClearTimeout; 2079 } 2080 } catch (e) { 2081 cachedClearTimeout = defaultClearTimeout; 2082 } 2083 } ()) 2084 function runTimeout(fun) { 2085 if (cachedSetTimeout === setTimeout) { 2086 //normal environments in sane situations 2087 return setTimeout(fun, 0); 2088 } 2089 // if setTimeout wasn't available but was latter defined 2090 if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { 2091 cachedSetTimeout = setTimeout; 2092 return setTimeout(fun, 0); 2093 } 2094 try { 2095 // when when somebody has screwed with setTimeout but no I.E. maddness 2096 return cachedSetTimeout(fun, 0); 2097 } catch(e){ 2098 try { 2099 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 2100 return cachedSetTimeout.call(null, fun, 0); 2101 } catch(e){ 2102 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error 2103 return cachedSetTimeout.call(this, fun, 0); 2104 } 2105 } 2106 2107 2108 } 2109 function runClearTimeout(marker) { 2110 if (cachedClearTimeout === clearTimeout) { 2111 //normal environments in sane situations 2112 return clearTimeout(marker); 2113 } 2114 // if clearTimeout wasn't available but was latter defined 2115 if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { 2116 cachedClearTimeout = clearTimeout; 2117 return clearTimeout(marker); 2118 } 2119 try { 2120 // when when somebody has screwed with setTimeout but no I.E. maddness 2121 return cachedClearTimeout(marker); 2122 } catch (e){ 2123 try { 2124 // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally 2125 return cachedClearTimeout.call(null, marker); 2126 } catch (e){ 2127 // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. 2128 // Some versions of I.E. have different rules for clearTimeout vs setTimeout 2129 return cachedClearTimeout.call(this, marker); 2130 } 2131 } 2132 2133 2134 2135 } 2136 var queue = []; 2137 var draining = false; 2138 var currentQueue; 2139 var queueIndex = -1; 2140 2141 function cleanUpNextTick() { 2142 if (!draining || !currentQueue) { 2143 return; 2144 } 2145 draining = false; 2146 if (currentQueue.length) { 2147 queue = currentQueue.concat(queue); 2148 } else { 2149 queueIndex = -1; 2150 } 2151 if (queue.length) { 2152 drainQueue(); 2153 } 2154 } 2155 2156 function drainQueue() { 2157 if (draining) { 2158 return; 2159 } 2160 var timeout = runTimeout(cleanUpNextTick); 2161 draining = true; 2162 2163 var len = queue.length; 2164 while(len) { 2165 currentQueue = queue; 2166 queue = []; 2167 while (++queueIndex < len) { 2168 if (currentQueue) { 2169 currentQueue[queueIndex].run(); 2170 } 2171 } 2172 queueIndex = -1; 2173 len = queue.length; 2174 } 2175 currentQueue = null; 2176 draining = false; 2177 runClearTimeout(timeout); 2178 } 2179 2180 process.nextTick = function (fun) { 2181 var args = new Array(arguments.length - 1); 2182 if (arguments.length > 1) { 2183 for (var i = 1; i < arguments.length; i++) { 2184 args[i - 1] = arguments[i]; 2185 } 2186 } 2187 queue.push(new Item(fun, args)); 2188 if (queue.length === 1 && !draining) { 2189 runTimeout(drainQueue); 2190 } 2191 }; 2192 2193 // v8 likes predictable objects 2194 function Item(fun, array) { 2195 this.fun = fun; 2196 this.array = array; 2197 } 2198 Item.prototype.run = function () { 2199 this.fun.apply(null, this.array); 2200 }; 2201 process.title = 'browser'; 2202 process.browser = true; 2203 process.env = {}; 2204 process.argv = []; 2205 process.version = ''; // empty string to avoid regexp issues 2206 process.versions = {}; 2207 2208 function noop() {} 2209 2210 process.on = noop; 2211 process.addListener = noop; 2212 process.once = noop; 2213 process.off = noop; 2214 process.removeListener = noop; 2215 process.removeAllListeners = noop; 2216 process.emit = noop; 2217 2218 process.binding = function (name) { 2219 throw new Error('process.binding is not supported'); 2220 }; 2221 2222 process.cwd = function () { return '/' }; 2223 process.chdir = function (dir) { 2224 throw new Error('process.chdir is not supported'); 2225 }; 2226 process.umask = function() { return 0; }; 2227 2228 2229 /***/ }), 2230 /* 12 */ 2231 /***/ (function(module, exports, __webpack_require__) { 2232 2233 module.exports = buildSearchMethod; 2234 2235 var errors = __webpack_require__(5); 2236 2237 /** 2238 * Creates a search method to be used in clients 2239 * @param {string} queryParam the name of the attribute used for the query 2240 * @param {string} url the url 2241 * @return {function} the search method 2242 */ 2243 function buildSearchMethod(queryParam, url) { 2244 /** 2245 * The search method. Prepares the data and send the query to Algolia. 2246 * @param {string} query the string used for query search 2247 * @param {object} args additional parameters to send with the search 2248 * @param {function} [callback] the callback to be called with the client gets the answer 2249 * @return {undefined|Promise} If the callback is not provided then this methods returns a Promise 2250 */ 2251 return function search(query, args, callback) { 2252 // warn V2 users on how to search 2253 if (typeof query === 'function' && typeof args === 'object' || 2254 typeof callback === 'object') { 2255 // .search(query, params, cb) 2256 // .search(cb, params) 2257 throw new errors.AlgoliaSearchError('index.search usage is index.search(query, params, cb)'); 2258 } 2259 2260 // Normalizing the function signature 2261 if (arguments.length === 0 || typeof query === 'function') { 2262 // Usage : .search(), .search(cb) 2263 callback = query; 2264 query = ''; 2265 } else if (arguments.length === 1 || typeof args === 'function') { 2266 // Usage : .search(query/args), .search(query, cb) 2267 callback = args; 2268 args = undefined; 2269 } 2270 // At this point we have 3 arguments with values 2271 2272 // Usage : .search(args) // careful: typeof null === 'object' 2273 if (typeof query === 'object' && query !== null) { 2274 args = query; 2275 query = undefined; 2276 } else if (query === undefined || query === null) { // .search(undefined/null) 2277 query = ''; 2278 } 2279 2280 var params = ''; 2281 2282 if (query !== undefined) { 2283 params += queryParam + '=' + encodeURIComponent(query); 2284 } 2285 2286 var additionalUA; 2287 if (args !== undefined) { 2288 if (args.additionalUA) { 2289 additionalUA = args.additionalUA; 2290 delete args.additionalUA; 2291 } 2292 // `_getSearchParams` will augment params, do not be fooled by the = versus += from previous if 2293 params = this.as._getSearchParams(args, params); 2294 } 2295 2296 2297 return this._search(params, url, callback, additionalUA); 2298 }; 2299 } 2300 2301 2302 /***/ }), 2303 /* 13 */ 2304 /***/ (function(module, exports, __webpack_require__) { 2305 2306 "use strict"; 2307 2308 2309 var namespace = 'autocomplete:'; 2310 2311 var _ = __webpack_require__(0); 2312 var DOM = __webpack_require__(1); 2313 2314 // constructor 2315 // ----------- 2316 2317 function EventBus(o) { 2318 if (!o || !o.el) { 2319 _.error('EventBus initialized without el'); 2320 } 2321 2322 this.$el = DOM.element(o.el); 2323 } 2324 2325 // instance methods 2326 // ---------------- 2327 2328 _.mixin(EventBus.prototype, { 2329 2330 // ### public 2331 2332 trigger: function(type) { 2333 var args = [].slice.call(arguments, 1); 2334 2335 var event = _.Event(namespace + type); 2336 this.$el.trigger(event, args); 2337 return event; 2338 } 2339 }); 2340 2341 module.exports = EventBus; 2342 2343 2344 /***/ }), 2345 /* 14 */ 2346 /***/ (function(module, exports, __webpack_require__) { 2347 2348 "use strict"; 2349 2350 2351 module.exports = { 2352 wrapper: '<span class="%ROOT%"></span>', 2353 dropdown: '<span class="%PREFIX%%DROPDOWN_MENU%"></span>', 2354 dataset: '<div class="%PREFIX%%DATASET%-%CLASS%"></div>', 2355 suggestions: '<span class="%PREFIX%%SUGGESTIONS%"></span>', 2356 suggestion: '<div class="%PREFIX%%SUGGESTION%"></div>' 2357 }; 2358 2359 2360 /***/ }), 2361 /* 15 */ 2362 /***/ (function(module, exports, __webpack_require__) { 2363 2364 "use strict"; 2365 2366 module.exports = function parseAlgoliaClientVersion(agent) { 2367 var parsed = agent.match(/Algolia for vanilla JavaScript (\d+\.)(\d+\.)(\d+)/); 2368 if (parsed) return [parsed[1], parsed[2], parsed[3]]; 2369 return undefined; 2370 }; 2371 2372 2373 /***/ }), 2374 /* 16 */ 2375 /***/ (function(module, exports) { 2376 2377 module.exports = "0.28.0"; 2378 2379 2380 /***/ }), 2381 /* 17 */ 2382 /***/ (function(module, exports) { 2383 2384 /* istanbul ignore next */ 2385 /* Zepto v1.2.0 - zepto event assets data - zeptojs.com/license */ 2386 (function(global, factory) { 2387 module.exports = factory(global); 2388 }(/* this ##### UPDATED: here we want to use window/global instead of this which is the current file context ##### */ window, function(window) { 2389 var Zepto = (function() { 2390 var undefined, key, $, classList, emptyArray = [], concat = emptyArray.concat, filter = emptyArray.filter, slice = emptyArray.slice, 2391 document = window.document, 2392 elementDisplay = {}, classCache = {}, 2393 cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 }, 2394 fragmentRE = /^\s*<(\w+|!)[^>]*>/, 2395 singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, 2396 tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, 2397 rootNodeRE = /^(?:body|html)$/i, 2398 capitalRE = /([A-Z])/g, 2399 2400 // special attributes that should be get/set via method calls 2401 methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'], 2402 2403 adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ], 2404 table = document.createElement('table'), 2405 tableRow = document.createElement('tr'), 2406 containers = { 2407 'tr': document.createElement('tbody'), 2408 'tbody': table, 'thead': table, 'tfoot': table, 2409 'td': tableRow, 'th': tableRow, 2410 '*': document.createElement('div') 2411 }, 2412 readyRE = /complete|loaded|interactive/, 2413 simpleSelectorRE = /^[\w-]*$/, 2414 class2type = {}, 2415 toString = class2type.toString, 2416 zepto = {}, 2417 camelize, uniq, 2418 tempParent = document.createElement('div'), 2419 propMap = { 2420 'tabindex': 'tabIndex', 2421 'readonly': 'readOnly', 2422 'for': 'htmlFor', 2423 'class': 'className', 2424 'maxlength': 'maxLength', 2425 'cellspacing': 'cellSpacing', 2426 'cellpadding': 'cellPadding', 2427 'rowspan': 'rowSpan', 2428 'colspan': 'colSpan', 2429 'usemap': 'useMap', 2430 'frameborder': 'frameBorder', 2431 'contenteditable': 'contentEditable' 2432 }, 2433 isArray = Array.isArray || 2434 function(object){ return object instanceof Array } 2435 2436 zepto.matches = function(element, selector) { 2437 if (!selector || !element || element.nodeType !== 1) return false 2438 var matchesSelector = element.matches || element.webkitMatchesSelector || 2439 element.mozMatchesSelector || element.oMatchesSelector || 2440 element.matchesSelector 2441 if (matchesSelector) return matchesSelector.call(element, selector) 2442 // fall back to performing a selector: 2443 var match, parent = element.parentNode, temp = !parent 2444 if (temp) (parent = tempParent).appendChild(element) 2445 match = ~zepto.qsa(parent, selector).indexOf(element) 2446 temp && tempParent.removeChild(element) 2447 return match 2448 } 2449 2450 function type(obj) { 2451 return obj == null ? String(obj) : 2452 class2type[toString.call(obj)] || "object" 2453 } 2454 2455 function isFunction(value) { return type(value) == "function" } 2456 function isWindow(obj) { return obj != null && obj == obj.window } 2457 function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE } 2458 function isObject(obj) { return type(obj) == "object" } 2459 function isPlainObject(obj) { 2460 return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype 2461 } 2462 2463 function likeArray(obj) { 2464 var length = !!obj && 'length' in obj && obj.length, 2465 type = $.type(obj) 2466 2467 return 'function' != type && !isWindow(obj) && ( 2468 'array' == type || length === 0 || 2469 (typeof length == 'number' && length > 0 && (length - 1) in obj) 2470 ) 2471 } 2472 2473 function compact(array) { return filter.call(array, function(item){ return item != null }) } 2474 function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array } 2475 camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) } 2476 function dasherize(str) { 2477 return str.replace(/::/g, '/') 2478 .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') 2479 .replace(/([a-z\d])([A-Z])/g, '$1_$2') 2480 .replace(/_/g, '-') 2481 .toLowerCase() 2482 } 2483 uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) } 2484 2485 function classRE(name) { 2486 return name in classCache ? 2487 classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)')) 2488 } 2489 2490 function maybeAddPx(name, value) { 2491 return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value 2492 } 2493 2494 function defaultDisplay(nodeName) { 2495 var element, display 2496 if (!elementDisplay[nodeName]) { 2497 element = document.createElement(nodeName) 2498 document.body.appendChild(element) 2499 display = getComputedStyle(element, '').getPropertyValue("display") 2500 element.parentNode.removeChild(element) 2501 display == "none" && (display = "block") 2502 elementDisplay[nodeName] = display 2503 } 2504 return elementDisplay[nodeName] 2505 } 2506 2507 function children(element) { 2508 return 'children' in element ? 2509 slice.call(element.children) : 2510 $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node }) 2511 } 2512 2513 function Z(dom, selector) { 2514 var i, len = dom ? dom.length : 0 2515 for (i = 0; i < len; i++) this[i] = dom[i] 2516 this.length = len 2517 this.selector = selector || '' 2518 } 2519 2520 // `$.zepto.fragment` takes a html string and an optional tag name 2521 // to generate DOM nodes from the given html string. 2522 // The generated DOM nodes are returned as an array. 2523 // This function can be overridden in plugins for example to make 2524 // it compatible with browsers that don't support the DOM fully. 2525 zepto.fragment = function(html, name, properties) { 2526 var dom, nodes, container 2527 2528 // A special case optimization for a single tag 2529 if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1)) 2530 2531 if (!dom) { 2532 if (html.replace) html = html.replace(tagExpanderRE, "<$1></$2>") 2533 if (name === undefined) name = fragmentRE.test(html) && RegExp.$1 2534 if (!(name in containers)) name = '*' 2535 2536 container = containers[name] 2537 container.innerHTML = '' + html 2538 dom = $.each(slice.call(container.childNodes), function(){ 2539 container.removeChild(this) 2540 }) 2541 } 2542 2543 if (isPlainObject(properties)) { 2544 nodes = $(dom) 2545 $.each(properties, function(key, value) { 2546 if (methodAttributes.indexOf(key) > -1) nodes[key](value) 2547 else nodes.attr(key, value) 2548 }) 2549 } 2550 2551 return dom 2552 } 2553 2554 // `$.zepto.Z` swaps out the prototype of the given `dom` array 2555 // of nodes with `$.fn` and thus supplying all the Zepto functions 2556 // to the array. This method can be overridden in plugins. 2557 zepto.Z = function(dom, selector) { 2558 return new Z(dom, selector) 2559 } 2560 2561 // `$.zepto.isZ` should return `true` if the given object is a Zepto 2562 // collection. This method can be overridden in plugins. 2563 zepto.isZ = function(object) { 2564 return object instanceof zepto.Z 2565 } 2566 2567 // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and 2568 // takes a CSS selector and an optional context (and handles various 2569 // special cases). 2570 // This method can be overridden in plugins. 2571 zepto.init = function(selector, context) { 2572 var dom 2573 // If nothing given, return an empty Zepto collection 2574 if (!selector) return zepto.Z() 2575 // Optimize for string selectors 2576 else if (typeof selector == 'string') { 2577 selector = selector.trim() 2578 // If it's a html fragment, create nodes from it 2579 // Note: In both Chrome 21 and Firefox 15, DOM error 12 2580 // is thrown if the fragment doesn't begin with < 2581 if (selector[0] == '<' && fragmentRE.test(selector)) 2582 dom = zepto.fragment(selector, RegExp.$1, context), selector = null 2583 // If there's a context, create a collection on that context first, and select 2584 // nodes from there 2585 else if (context !== undefined) return $(context).find(selector) 2586 // If it's a CSS selector, use it to select nodes. 2587 else dom = zepto.qsa(document, selector) 2588 } 2589 // If a function is given, call it when the DOM is ready 2590 else if (isFunction(selector)) return $(document).ready(selector) 2591 // If a Zepto collection is given, just return it 2592 else if (zepto.isZ(selector)) return selector 2593 else { 2594 // normalize array if an array of nodes is given 2595 if (isArray(selector)) dom = compact(selector) 2596 // Wrap DOM nodes. 2597 else if (isObject(selector)) 2598 dom = [selector], selector = null 2599 // If it's a html fragment, create nodes from it 2600 else if (fragmentRE.test(selector)) 2601 dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null 2602 // If there's a context, create a collection on that context first, and select 2603 // nodes from there 2604 else if (context !== undefined) return $(context).find(selector) 2605 // And last but no least, if it's a CSS selector, use it to select nodes. 2606 else dom = zepto.qsa(document, selector) 2607 } 2608 // create a new Zepto collection from the nodes found 2609 return zepto.Z(dom, selector) 2610 } 2611 2612 // `$` will be the base `Zepto` object. When calling this 2613 // function just call `$.zepto.init, which makes the implementation 2614 // details of selecting nodes and creating Zepto collections 2615 // patchable in plugins. 2616 $ = function(selector, context){ 2617 return zepto.init(selector, context) 2618 } 2619 2620 function extend(target, source, deep) { 2621 for (key in source) 2622 if (deep && (isPlainObject(source[key]) || isArray(source[key]))) { 2623 if (isPlainObject(source[key]) && !isPlainObject(target[key])) 2624 target[key] = {} 2625 if (isArray(source[key]) && !isArray(target[key])) 2626 target[key] = [] 2627 extend(target[key], source[key], deep) 2628 } 2629 else if (source[key] !== undefined) target[key] = source[key] 2630 } 2631 2632 // Copy all but undefined properties from one or more 2633 // objects to the `target` object. 2634 $.extend = function(target){ 2635 var deep, args = slice.call(arguments, 1) 2636 if (typeof target == 'boolean') { 2637 deep = target 2638 target = args.shift() 2639 } 2640 args.forEach(function(arg){ extend(target, arg, deep) }) 2641 return target 2642 } 2643 2644 // `$.zepto.qsa` is Zepto's CSS selector implementation which 2645 // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`. 2646 // This method can be overridden in plugins. 2647 zepto.qsa = function(element, selector){ 2648 var found, 2649 maybeID = selector[0] == '#', 2650 maybeClass = !maybeID && selector[0] == '.', 2651 nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked 2652 isSimple = simpleSelectorRE.test(nameOnly) 2653 return (element.getElementById && isSimple && maybeID) ? // Safari DocumentFragment doesn't have getElementById 2654 ( (found = element.getElementById(nameOnly)) ? [found] : [] ) : 2655 (element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11) ? [] : 2656 slice.call( 2657 isSimple && !maybeID && element.getElementsByClassName ? // DocumentFragment doesn't have getElementsByClassName/TagName 2658 maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class 2659 element.getElementsByTagName(selector) : // Or a tag 2660 element.querySelectorAll(selector) // Or it's not simple, and we need to query all 2661 ) 2662 } 2663 2664 function filtered(nodes, selector) { 2665 return selector == null ? $(nodes) : $(nodes).filter(selector) 2666 } 2667 2668 $.contains = document.documentElement.contains ? 2669 function(parent, node) { 2670 return parent !== node && parent.contains(node) 2671 } : 2672 function(parent, node) { 2673 while (node && (node = node.parentNode)) 2674 if (node === parent) return true 2675 return false 2676 } 2677 2678 function funcArg(context, arg, idx, payload) { 2679 return isFunction(arg) ? arg.call(context, idx, payload) : arg 2680 } 2681 2682 function setAttribute(node, name, value) { 2683 value == null ? node.removeAttribute(name) : node.setAttribute(name, value) 2684 } 2685 2686 // access className property while respecting SVGAnimatedString 2687 function className(node, value){ 2688 var klass = node.className || '', 2689 svg = klass && klass.baseVal !== undefined 2690 2691 if (value === undefined) return svg ? klass.baseVal : klass 2692 svg ? (klass.baseVal = value) : (node.className = value) 2693 } 2694 2695 // "true" => true 2696 // "false" => false 2697 // "null" => null 2698 // "42" => 42 2699 // "42.5" => 42.5 2700 // "08" => "08" 2701 // JSON => parse if valid 2702 // String => self 2703 function deserializeValue(value) { 2704 try { 2705 return value ? 2706 value == "true" || 2707 ( value == "false" ? false : 2708 value == "null" ? null : 2709 +value + "" == value ? +value : 2710 /^[\[\{]/.test(value) ? $.parseJSON(value) : 2711 value ) 2712 : value 2713 } catch(e) { 2714 return value 2715 } 2716 } 2717 2718 $.type = type 2719 $.isFunction = isFunction 2720 $.isWindow = isWindow 2721 $.isArray = isArray 2722 $.isPlainObject = isPlainObject 2723 2724 $.isEmptyObject = function(obj) { 2725 var name 2726 for (name in obj) return false 2727 return true 2728 } 2729 2730 $.isNumeric = function(val) { 2731 var num = Number(val), type = typeof val 2732 return val != null && type != 'boolean' && 2733 (type != 'string' || val.length) && 2734 !isNaN(num) && isFinite(num) || false 2735 } 2736 2737 $.inArray = function(elem, array, i){ 2738 return emptyArray.indexOf.call(array, elem, i) 2739 } 2740 2741 $.camelCase = camelize 2742 $.trim = function(str) { 2743 return str == null ? "" : String.prototype.trim.call(str) 2744 } 2745 2746 // plugin compatibility 2747 $.uuid = 0 2748 $.support = { } 2749 $.expr = { } 2750 $.noop = function() {} 2751 2752 $.map = function(elements, callback){ 2753 var value, values = [], i, key 2754 if (likeArray(elements)) 2755 for (i = 0; i < elements.length; i++) { 2756 value = callback(elements[i], i) 2757 if (value != null) values.push(value) 2758 } 2759 else 2760 for (key in elements) { 2761 value = callback(elements[key], key) 2762 if (value != null) values.push(value) 2763 } 2764 return flatten(values) 2765 } 2766 2767 $.each = function(elements, callback){ 2768 var i, key 2769 if (likeArray(elements)) { 2770 for (i = 0; i < elements.length; i++) 2771 if (callback.call(elements[i], i, elements[i]) === false) return elements 2772 } else { 2773 for (key in elements) 2774 if (callback.call(elements[key], key, elements[key]) === false) return elements 2775 } 2776 2777 return elements 2778 } 2779 2780 $.grep = function(elements, callback){ 2781 return filter.call(elements, callback) 2782 } 2783 2784 if (window.JSON) $.parseJSON = JSON.parse 2785 2786 // Populate the class2type map 2787 $.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { 2788 class2type[ "[object " + name + "]" ] = name.toLowerCase() 2789 }) 2790 2791 // Define methods that will be available on all 2792 // Zepto collections 2793 $.fn = { 2794 constructor: zepto.Z, 2795 length: 0, 2796 2797 // Because a collection acts like an array 2798 // copy over these useful array functions. 2799 forEach: emptyArray.forEach, 2800 reduce: emptyArray.reduce, 2801 push: emptyArray.push, 2802 sort: emptyArray.sort, 2803 splice: emptyArray.splice, 2804 indexOf: emptyArray.indexOf, 2805 concat: function(){ 2806 var i, value, args = [] 2807 for (i = 0; i < arguments.length; i++) { 2808 value = arguments[i] 2809 args[i] = zepto.isZ(value) ? value.toArray() : value 2810 } 2811 return concat.apply(zepto.isZ(this) ? this.toArray() : this, args) 2812 }, 2813 2814 // `map` and `slice` in the jQuery API work differently 2815 // from their array counterparts 2816 map: function(fn){ 2817 return $($.map(this, function(el, i){ return fn.call(el, i, el) })) 2818 }, 2819 slice: function(){ 2820 return $(slice.apply(this, arguments)) 2821 }, 2822 2823 ready: function(callback){ 2824 // need to check if document.body exists for IE as that browser reports 2825 // document ready when it hasn't yet created the body element 2826 if (readyRE.test(document.readyState) && document.body) callback($) 2827 else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false) 2828 return this 2829 }, 2830 get: function(idx){ 2831 return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length] 2832 }, 2833 toArray: function(){ return this.get() }, 2834 size: function(){ 2835 return this.length 2836 }, 2837 remove: function(){ 2838 return this.each(function(){ 2839 if (this.parentNode != null) 2840 this.parentNode.removeChild(this) 2841 }) 2842 }, 2843 each: function(callback){ 2844 emptyArray.every.call(this, function(el, idx){ 2845 return callback.call(el, idx, el) !== false 2846 }) 2847 return this 2848 }, 2849 filter: function(selector){ 2850 if (isFunction(selector)) return this.not(this.not(selector)) 2851 return $(filter.call(this, function(element){ 2852 return zepto.matches(element, selector) 2853 })) 2854 }, 2855 add: function(selector,context){ 2856 return $(uniq(this.concat($(selector,context)))) 2857 }, 2858 is: function(selector){ 2859 return this.length > 0 && zepto.matches(this[0], selector) 2860 }, 2861 not: function(selector){ 2862 var nodes=[] 2863 if (isFunction(selector) && selector.call !== undefined) 2864 this.each(function(idx){ 2865 if (!selector.call(this,idx)) nodes.push(this) 2866 }) 2867 else { 2868 var excludes = typeof selector == 'string' ? this.filter(selector) : 2869 (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector) 2870 this.forEach(function(el){ 2871 if (excludes.indexOf(el) < 0) nodes.push(el) 2872 }) 2873 } 2874 return $(nodes) 2875 }, 2876 has: function(selector){ 2877 return this.filter(function(){ 2878 return isObject(selector) ? 2879 $.contains(this, selector) : 2880 $(this).find(selector).size() 2881 }) 2882 }, 2883 eq: function(idx){ 2884 return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1) 2885 }, 2886 first: function(){ 2887 var el = this[0] 2888 return el && !isObject(el) ? el : $(el) 2889 }, 2890 last: function(){ 2891 var el = this[this.length - 1] 2892 return el && !isObject(el) ? el : $(el) 2893 }, 2894 find: function(selector){ 2895 var result, $this = this 2896 if (!selector) result = $() 2897 else if (typeof selector == 'object') 2898 result = $(selector).filter(function(){ 2899 var node = this 2900 return emptyArray.some.call($this, function(parent){ 2901 return $.contains(parent, node) 2902 }) 2903 }) 2904 else if (this.length == 1) result = $(zepto.qsa(this[0], selector)) 2905 else result = this.map(function(){ return zepto.qsa(this, selector) }) 2906 return result 2907 }, 2908 closest: function(selector, context){ 2909 var nodes = [], collection = typeof selector == 'object' && $(selector) 2910 this.each(function(_, node){ 2911 while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector))) 2912 node = node !== context && !isDocument(node) && node.parentNode 2913 if (node && nodes.indexOf(node) < 0) nodes.push(node) 2914 }) 2915 return $(nodes) 2916 }, 2917 parents: function(selector){ 2918 var ancestors = [], nodes = this 2919 while (nodes.length > 0) 2920 nodes = $.map(nodes, function(node){ 2921 if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) { 2922 ancestors.push(node) 2923 return node 2924 } 2925 }) 2926 return filtered(ancestors, selector) 2927 }, 2928 parent: function(selector){ 2929 return filtered(uniq(this.pluck('parentNode')), selector) 2930 }, 2931 children: function(selector){ 2932 return filtered(this.map(function(){ return children(this) }), selector) 2933 }, 2934 contents: function() { 2935 return this.map(function() { return this.contentDocument || slice.call(this.childNodes) }) 2936 }, 2937 siblings: function(selector){ 2938 return filtered(this.map(function(i, el){ 2939 return filter.call(children(el.parentNode), function(child){ return child!==el }) 2940 }), selector) 2941 }, 2942 empty: function(){ 2943 return this.each(function(){ this.innerHTML = '' }) 2944 }, 2945 // `pluck` is borrowed from Prototype.js 2946 pluck: function(property){ 2947 return $.map(this, function(el){ return el[property] }) 2948 }, 2949 show: function(){ 2950 return this.each(function(){ 2951 this.style.display == "none" && (this.style.display = '') 2952 if (getComputedStyle(this, '').getPropertyValue("display") == "none") 2953 this.style.display = defaultDisplay(this.nodeName) 2954 }) 2955 }, 2956 replaceWith: function(newContent){ 2957 return this.before(newContent).remove() 2958 }, 2959 wrap: function(structure){ 2960 var func = isFunction(structure) 2961 if (this[0] && !func) 2962 var dom = $(structure).get(0), 2963 clone = dom.parentNode || this.length > 1 2964 2965 return this.each(function(index){ 2966 $(this).wrapAll( 2967 func ? structure.call(this, index) : 2968 clone ? dom.cloneNode(true) : dom 2969 ) 2970 }) 2971 }, 2972 wrapAll: function(structure){ 2973 if (this[0]) { 2974 $(this[0]).before(structure = $(structure)) 2975 var children 2976 // drill down to the inmost element 2977 while ((children = structure.children()).length) structure = children.first() 2978 $(structure).append(this) 2979 } 2980 return this 2981 }, 2982 wrapInner: function(structure){ 2983 var func = isFunction(structure) 2984 return this.each(function(index){ 2985 var self = $(this), contents = self.contents(), 2986 dom = func ? structure.call(this, index) : structure 2987 contents.length ? contents.wrapAll(dom) : self.append(dom) 2988 }) 2989 }, 2990 unwrap: function(){ 2991 this.parent().each(function(){ 2992 $(this).replaceWith($(this).children()) 2993 }) 2994 return this 2995 }, 2996 clone: function(){ 2997 return this.map(function(){ return this.cloneNode(true) }) 2998 }, 2999 hide: function(){ 3000 return this.css("display", "none") 3001 }, 3002 toggle: function(setting){ 3003 return this.each(function(){ 3004 var el = $(this) 3005 ;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide() 3006 }) 3007 }, 3008 prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') }, 3009 next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') }, 3010 html: function(html){ 3011 return 0 in arguments ? 3012 this.each(function(idx){ 3013 var originHtml = this.innerHTML 3014 $(this).empty().append( funcArg(this, html, idx, originHtml) ) 3015 }) : 3016 (0 in this ? this[0].innerHTML : null) 3017 }, 3018 text: function(text){ 3019 return 0 in arguments ? 3020 this.each(function(idx){ 3021 var newText = funcArg(this, text, idx, this.textContent) 3022 this.textContent = newText == null ? '' : ''+newText 3023 }) : 3024 (0 in this ? this.pluck('textContent').join("") : null) 3025 }, 3026 attr: function(name, value){ 3027 var result 3028 return (typeof name == 'string' && !(1 in arguments)) ? 3029 (0 in this && this[0].nodeType == 1 && (result = this[0].getAttribute(name)) != null ? result : undefined) : 3030 this.each(function(idx){ 3031 if (this.nodeType !== 1) return 3032 if (isObject(name)) for (key in name) setAttribute(this, key, name[key]) 3033 else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name))) 3034 }) 3035 }, 3036 removeAttr: function(name){ 3037 return this.each(function(){ this.nodeType === 1 && name.split(' ').forEach(function(attribute){ 3038 setAttribute(this, attribute) 3039 }, this)}) 3040 }, 3041 prop: function(name, value){ 3042 name = propMap[name] || name 3043 return (1 in arguments) ? 3044 this.each(function(idx){ 3045 this[name] = funcArg(this, value, idx, this[name]) 3046 }) : 3047 (this[0] && this[0][name]) 3048 }, 3049 removeProp: function(name){ 3050 name = propMap[name] || name 3051 return this.each(function(){ delete this[name] }) 3052 }, 3053 data: function(name, value){ 3054 var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase() 3055 3056 var data = (1 in arguments) ? 3057 this.attr(attrName, value) : 3058 this.attr(attrName) 3059 3060 return data !== null ? deserializeValue(data) : undefined 3061 }, 3062 val: function(value){ 3063 if (0 in arguments) { 3064 if (value == null) value = "" 3065 return this.each(function(idx){ 3066 this.value = funcArg(this, value, idx, this.value) 3067 }) 3068 } else { 3069 return this[0] && (this[0].multiple ? 3070 $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') : 3071 this[0].value) 3072 } 3073 }, 3074 offset: function(coordinates){ 3075 if (coordinates) return this.each(function(index){ 3076 var $this = $(this), 3077 coords = funcArg(this, coordinates, index, $this.offset()), 3078 parentOffset = $this.offsetParent().offset(), 3079 props = { 3080 top: coords.top - parentOffset.top, 3081 left: coords.left - parentOffset.left 3082 } 3083 3084 if ($this.css('position') == 'static') props['position'] = 'relative' 3085 $this.css(props) 3086 }) 3087 if (!this.length) return null 3088 if (document.documentElement !== this[0] && !$.contains(document.documentElement, this[0])) 3089 return {top: 0, left: 0} 3090 var obj = this[0].getBoundingClientRect() 3091 return { 3092 left: obj.left + window.pageXOffset, 3093 top: obj.top + window.pageYOffset, 3094 width: Math.round(obj.width), 3095 height: Math.round(obj.height) 3096 } 3097 }, 3098 css: function(property, value){ 3099 if (arguments.length < 2) { 3100 var element = this[0] 3101 if (typeof property == 'string') { 3102 if (!element) return 3103 return element.style[camelize(property)] || getComputedStyle(element, '').getPropertyValue(property) 3104 } else if (isArray(property)) { 3105 if (!element) return 3106 var props = {} 3107 var computedStyle = getComputedStyle(element, '') 3108 $.each(property, function(_, prop){ 3109 props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop)) 3110 }) 3111 return props 3112 } 3113 } 3114 3115 var css = '' 3116 if (type(property) == 'string') { 3117 if (!value && value !== 0) 3118 this.each(function(){ this.style.removeProperty(dasherize(property)) }) 3119 else 3120 css = dasherize(property) + ":" + maybeAddPx(property, value) 3121 } else { 3122 for (key in property) 3123 if (!property[key] && property[key] !== 0) 3124 this.each(function(){ this.style.removeProperty(dasherize(key)) }) 3125 else 3126 css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';' 3127 } 3128 3129 return this.each(function(){ this.style.cssText += ';' + css }) 3130 }, 3131 index: function(element){ 3132 return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0]) 3133 }, 3134 hasClass: function(name){ 3135 if (!name) return false 3136 return emptyArray.some.call(this, function(el){ 3137 return this.test(className(el)) 3138 }, classRE(name)) 3139 }, 3140 addClass: function(name){ 3141 if (!name) return this 3142 return this.each(function(idx){ 3143 if (!('className' in this)) return 3144 classList = [] 3145 var cls = className(this), newName = funcArg(this, name, idx, cls) 3146 newName.split(/\s+/g).forEach(function(klass){ 3147 if (!$(this).hasClass(klass)) classList.push(klass) 3148 }, this) 3149 classList.length && className(this, cls + (cls ? " " : "") + classList.join(" ")) 3150 }) 3151 }, 3152 removeClass: function(name){ 3153 return this.each(function(idx){ 3154 if (!('className' in this)) return 3155 if (name === undefined) return className(this, '') 3156 classList = className(this) 3157 funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){ 3158 classList = classList.replace(classRE(klass), " ") 3159 }) 3160 className(this, classList.trim()) 3161 }) 3162 }, 3163 toggleClass: function(name, when){ 3164 if (!name) return this 3165 return this.each(function(idx){ 3166 var $this = $(this), names = funcArg(this, name, idx, className(this)) 3167 names.split(/\s+/g).forEach(function(klass){ 3168 (when === undefined ? !$this.hasClass(klass) : when) ? 3169 $this.addClass(klass) : $this.removeClass(klass) 3170 }) 3171 }) 3172 }, 3173 scrollTop: function(value){ 3174 if (!this.length) return 3175 var hasScrollTop = 'scrollTop' in this[0] 3176 if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset 3177 return this.each(hasScrollTop ? 3178 function(){ this.scrollTop = value } : 3179 function(){ this.scrollTo(this.scrollX, value) }) 3180 }, 3181 scrollLeft: function(value){ 3182 if (!this.length) return 3183 var hasScrollLeft = 'scrollLeft' in this[0] 3184 if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset 3185 return this.each(hasScrollLeft ? 3186 function(){ this.scrollLeft = value } : 3187 function(){ this.scrollTo(value, this.scrollY) }) 3188 }, 3189 position: function() { 3190 if (!this.length) return 3191 3192 var elem = this[0], 3193 // Get *real* offsetParent 3194 offsetParent = this.offsetParent(), 3195 // Get correct offsets 3196 offset = this.offset(), 3197 parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset() 3198 3199 // Subtract element margins 3200 // note: when an element has margin: auto the offsetLeft and marginLeft 3201 // are the same in Safari causing offset.left to incorrectly be 0 3202 offset.top -= parseFloat( $(elem).css('margin-top') ) || 0 3203 offset.left -= parseFloat( $(elem).css('margin-left') ) || 0 3204 3205 // Add offsetParent borders 3206 parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0 3207 parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0 3208 3209 // Subtract the two offsets 3210 return { 3211 top: offset.top - parentOffset.top, 3212 left: offset.left - parentOffset.left 3213 } 3214 }, 3215 offsetParent: function() { 3216 return this.map(function(){ 3217 var parent = this.offsetParent || document.body 3218 while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static") 3219 parent = parent.offsetParent 3220 return parent 3221 }) 3222 } 3223 } 3224 3225 // for now 3226 $.fn.detach = $.fn.remove 3227 3228 // Generate the `width` and `height` functions 3229 ;['width', 'height'].forEach(function(dimension){ 3230 var dimensionProperty = 3231 dimension.replace(/./, function(m){ return m[0].toUpperCase() }) 3232 3233 $.fn[dimension] = function(value){ 3234 var offset, el = this[0] 3235 if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] : 3236 isDocument(el) ? el.documentElement['scroll' + dimensionProperty] : 3237 (offset = this.offset()) && offset[dimension] 3238 else return this.each(function(idx){ 3239 el = $(this) 3240 el.css(dimension, funcArg(this, value, idx, el[dimension]())) 3241 }) 3242 } 3243 }) 3244 3245 function traverseNode(node, fun) { 3246 fun(node) 3247 for (var i = 0, len = node.childNodes.length; i < len; i++) 3248 traverseNode(node.childNodes[i], fun) 3249 } 3250 3251 // Generate the `after`, `prepend`, `before`, `append`, 3252 // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods. 3253 adjacencyOperators.forEach(function(operator, operatorIndex) { 3254 var inside = operatorIndex % 2 //=> prepend, append 3255 3256 $.fn[operator] = function(){ 3257 // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings 3258 var argType, nodes = $.map(arguments, function(arg) { 3259 var arr = [] 3260 argType = type(arg) 3261 if (argType == "array") { 3262 arg.forEach(function(el) { 3263 if (el.nodeType !== undefined) return arr.push(el) 3264 else if ($.zepto.isZ(el)) return arr = arr.concat(el.get()) 3265 arr = arr.concat(zepto.fragment(el)) 3266 }) 3267 return arr 3268 } 3269 return argType == "object" || arg == null ? 3270 arg : zepto.fragment(arg) 3271 }), 3272 parent, copyByClone = this.length > 1 3273 if (nodes.length < 1) return this 3274 3275 return this.each(function(_, target){ 3276 parent = inside ? target : target.parentNode 3277 3278 // convert all methods to a "before" operation 3279 target = operatorIndex == 0 ? target.nextSibling : 3280 operatorIndex == 1 ? target.firstChild : 3281 operatorIndex == 2 ? target : 3282 null 3283 3284 var parentInDocument = $.contains(document.documentElement, parent) 3285 3286 nodes.forEach(function(node){ 3287 if (copyByClone) node = node.cloneNode(true) 3288 else if (!parent) return $(node).remove() 3289 3290 parent.insertBefore(node, target) 3291 if (parentInDocument) traverseNode(node, function(el){ 3292 if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' && 3293 (!el.type || el.type === 'text/javascript') && !el.src){ 3294 var target = el.ownerDocument ? el.ownerDocument.defaultView : window 3295 target['eval'].call(target, el.innerHTML) 3296 } 3297 }) 3298 }) 3299 }) 3300 } 3301 3302 // after => insertAfter 3303 // prepend => prependTo 3304 // before => insertBefore 3305 // append => appendTo 3306 $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){ 3307 $(html)[operator](this) 3308 return this 3309 } 3310 }) 3311 3312 zepto.Z.prototype = Z.prototype = $.fn 3313 3314 // Export internal API functions in the `$.zepto` namespace 3315 zepto.uniq = uniq 3316 zepto.deserializeValue = deserializeValue 3317 $.zepto = zepto 3318 3319 return $ 3320 })() 3321 3322 ;(function($){ 3323 var _zid = 1, undefined, 3324 slice = Array.prototype.slice, 3325 isFunction = $.isFunction, 3326 isString = function(obj){ return typeof obj == 'string' }, 3327 handlers = {}, 3328 specialEvents={}, 3329 focusinSupported = 'onfocusin' in window, 3330 focus = { focus: 'focusin', blur: 'focusout' }, 3331 hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' } 3332 3333 specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents' 3334 3335 function zid(element) { 3336 return element._zid || (element._zid = _zid++) 3337 } 3338 function findHandlers(element, event, fn, selector) { 3339 event = parse(event) 3340 if (event.ns) var matcher = matcherFor(event.ns) 3341 return (handlers[zid(element)] || []).filter(function(handler) { 3342 return handler 3343 && (!event.e || handler.e == event.e) 3344 && (!event.ns || matcher.test(handler.ns)) 3345 && (!fn || zid(handler.fn) === zid(fn)) 3346 && (!selector || handler.sel == selector) 3347 }) 3348 } 3349 function parse(event) { 3350 var parts = ('' + event).split('.') 3351 return {e: parts[0], ns: parts.slice(1).sort().join(' ')} 3352 } 3353 function matcherFor(ns) { 3354 return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)') 3355 } 3356 3357 function eventCapture(handler, captureSetting) { 3358 return handler.del && 3359 (!focusinSupported && (handler.e in focus)) || 3360 !!captureSetting 3361 } 3362 3363 function realEvent(type) { 3364 return hover[type] || (focusinSupported && focus[type]) || type 3365 } 3366 3367 function add(element, events, fn, data, selector, delegator, capture){ 3368 var id = zid(element), set = (handlers[id] || (handlers[id] = [])) 3369 events.split(/\s/).forEach(function(event){ 3370 if (event == 'ready') return $(document).ready(fn) 3371 var handler = parse(event) 3372 handler.fn = fn 3373 handler.sel = selector 3374 // emulate mouseenter, mouseleave 3375 if (handler.e in hover) fn = function(e){ 3376 var related = e.relatedTarget 3377 if (!related || (related !== this && !$.contains(this, related))) 3378 return handler.fn.apply(this, arguments) 3379 } 3380 handler.del = delegator 3381 var callback = delegator || fn 3382 handler.proxy = function(e){ 3383 e = compatible(e) 3384 if (e.isImmediatePropagationStopped()) return 3385 e.data = data 3386 var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args)) 3387 if (result === false) e.preventDefault(), e.stopPropagation() 3388 return result 3389 } 3390 handler.i = set.length 3391 set.push(handler) 3392 if ('addEventListener' in element) 3393 element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) 3394 }) 3395 } 3396 function remove(element, events, fn, selector, capture){ 3397 var id = zid(element) 3398 ;(events || '').split(/\s/).forEach(function(event){ 3399 findHandlers(element, event, fn, selector).forEach(function(handler){ 3400 delete handlers[id][handler.i] 3401 if ('removeEventListener' in element) 3402 element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) 3403 }) 3404 }) 3405 } 3406 3407 $.event = { add: add, remove: remove } 3408 3409 $.proxy = function(fn, context) { 3410 var args = (2 in arguments) && slice.call(arguments, 2) 3411 if (isFunction(fn)) { 3412 var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) } 3413 proxyFn._zid = zid(fn) 3414 return proxyFn 3415 } else if (isString(context)) { 3416 if (args) { 3417 args.unshift(fn[context], fn) 3418 return $.proxy.apply(null, args) 3419 } else { 3420 return $.proxy(fn[context], fn) 3421 } 3422 } else { 3423 throw new TypeError("expected function") 3424 } 3425 } 3426 3427 $.fn.bind = function(event, data, callback){ 3428 return this.on(event, data, callback) 3429 } 3430 $.fn.unbind = function(event, callback){ 3431 return this.off(event, callback) 3432 } 3433 $.fn.one = function(event, selector, data, callback){ 3434 return this.on(event, selector, data, callback, 1) 3435 } 3436 3437 var returnTrue = function(){return true}, 3438 returnFalse = function(){return false}, 3439 ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$|webkitMovement[XY]$)/, 3440 eventMethods = { 3441 preventDefault: 'isDefaultPrevented', 3442 stopImmediatePropagation: 'isImmediatePropagationStopped', 3443 stopPropagation: 'isPropagationStopped' 3444 } 3445 3446 function compatible(event, source) { 3447 if (source || !event.isDefaultPrevented) { 3448 source || (source = event) 3449 3450 $.each(eventMethods, function(name, predicate) { 3451 var sourceMethod = source[name] 3452 event[name] = function(){ 3453 this[predicate] = returnTrue 3454 return sourceMethod && sourceMethod.apply(source, arguments) 3455 } 3456 event[predicate] = returnFalse 3457 }) 3458 3459 event.timeStamp || (event.timeStamp = Date.now()) 3460 3461 if (source.defaultPrevented !== undefined ? source.defaultPrevented : 3462 'returnValue' in source ? source.returnValue === false : 3463 source.getPreventDefault && source.getPreventDefault()) 3464 event.isDefaultPrevented = returnTrue 3465 } 3466 return event 3467 } 3468 3469 function createProxy(event) { 3470 var key, proxy = { originalEvent: event } 3471 for (key in event) 3472 if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key] 3473 3474 return compatible(proxy, event) 3475 } 3476 3477 $.fn.delegate = function(selector, event, callback){ 3478 return this.on(event, selector, callback) 3479 } 3480 $.fn.undelegate = function(selector, event, callback){ 3481 return this.off(event, selector, callback) 3482 } 3483 3484 $.fn.live = function(event, callback){ 3485 $(document.body).delegate(this.selector, event, callback) 3486 return this 3487 } 3488 $.fn.die = function(event, callback){ 3489 $(document.body).undelegate(this.selector, event, callback) 3490 return this 3491 } 3492 3493 $.fn.on = function(event, selector, data, callback, one){ 3494 var autoRemove, delegator, $this = this 3495 if (event && !isString(event)) { 3496 $.each(event, function(type, fn){ 3497 $this.on(type, selector, data, fn, one) 3498 }) 3499 return $this 3500 } 3501 3502 if (!isString(selector) && !isFunction(callback) && callback !== false) 3503 callback = data, data = selector, selector = undefined 3504 if (callback === undefined || data === false) 3505 callback = data, data = undefined 3506 3507 if (callback === false) callback = returnFalse 3508 3509 return $this.each(function(_, element){ 3510 if (one) autoRemove = function(e){ 3511 remove(element, e.type, callback) 3512 return callback.apply(this, arguments) 3513 } 3514 3515 if (selector) delegator = function(e){ 3516 var evt, match = $(e.target).closest(selector, element).get(0) 3517 if (match && match !== element) { 3518 evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element}) 3519 return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1))) 3520 } 3521 } 3522 3523 add(element, event, callback, data, selector, delegator || autoRemove) 3524 }) 3525 } 3526 $.fn.off = function(event, selector, callback){ 3527 var $this = this 3528 if (event && !isString(event)) { 3529 $.each(event, function(type, fn){ 3530 $this.off(type, selector, fn) 3531 }) 3532 return $this 3533 } 3534 3535 if (!isString(selector) && !isFunction(callback) && callback !== false) 3536 callback = selector, selector = undefined 3537 3538 if (callback === false) callback = returnFalse 3539 3540 return $this.each(function(){ 3541 remove(this, event, callback, selector) 3542 }) 3543 } 3544 3545 $.fn.trigger = function(event, args){ 3546 event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event) 3547 event._args = args 3548 return this.each(function(){ 3549 // handle focus(), blur() by calling them directly 3550 if (event.type in focus && typeof this[event.type] == "function") this[event.type]() 3551 // items in the collection might not be DOM elements 3552 else if ('dispatchEvent' in this) this.dispatchEvent(event) 3553 else $(this).triggerHandler(event, args) 3554 }) 3555 } 3556 3557 // triggers event handlers on current element just as if an event occurred, 3558 // doesn't trigger an actual event, doesn't bubble 3559 $.fn.triggerHandler = function(event, args){ 3560 var e, result 3561 this.each(function(i, element){ 3562 e = createProxy(isString(event) ? $.Event(event) : event) 3563 e._args = args 3564 e.target = element 3565 $.each(findHandlers(element, event.type || event), function(i, handler){ 3566 result = handler.proxy(e) 3567 if (e.isImmediatePropagationStopped()) return false 3568 }) 3569 }) 3570 return result 3571 } 3572 3573 // shortcut methods for `.bind(event, fn)` for each event type 3574 ;('focusin focusout focus blur load resize scroll unload click dblclick '+ 3575 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+ 3576 'change select keydown keypress keyup error').split(' ').forEach(function(event) { 3577 $.fn[event] = function(callback) { 3578 return (0 in arguments) ? 3579 this.bind(event, callback) : 3580 this.trigger(event) 3581 } 3582 }) 3583 3584 $.Event = function(type, props) { 3585 if (!isString(type)) props = type, type = props.type 3586 var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true 3587 if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name]) 3588 event.initEvent(type, bubbles, true) 3589 return compatible(event) 3590 } 3591 3592 })(Zepto) 3593 3594 ;(function($){ 3595 var cache = [], timeout 3596 3597 $.fn.remove = function(){ 3598 return this.each(function(){ 3599 if(this.parentNode){ 3600 if(this.tagName === 'IMG'){ 3601 cache.push(this) 3602 this.src = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=' 3603 if (timeout) clearTimeout(timeout) 3604 timeout = setTimeout(function(){ cache = [] }, 60000) 3605 } 3606 this.parentNode.removeChild(this) 3607 } 3608 }) 3609 } 3610 })(Zepto) 3611 3612 ;(function($){ 3613 var data = {}, dataAttr = $.fn.data, camelize = $.camelCase, 3614 exp = $.expando = 'Zepto' + (+new Date()), emptyArray = [] 3615 3616 // Get value from node: 3617 // 1. first try key as given, 3618 // 2. then try camelized key, 3619 // 3. fall back to reading "data-*" attribute. 3620 function getData(node, name) { 3621 var id = node[exp], store = id && data[id] 3622 if (name === undefined) return store || setData(node) 3623 else { 3624 if (store) { 3625 if (name in store) return store[name] 3626 var camelName = camelize(name) 3627 if (camelName in store) return store[camelName] 3628 } 3629 return dataAttr.call($(node), name) 3630 } 3631 } 3632 3633 // Store value under camelized key on node 3634 function setData(node, name, value) { 3635 var id = node[exp] || (node[exp] = ++$.uuid), 3636 store = data[id] || (data[id] = attributeData(node)) 3637 if (name !== undefined) store[camelize(name)] = value 3638 return store 3639 } 3640 3641 // Read all "data-*" attributes from a node 3642 function attributeData(node) { 3643 var store = {} 3644 $.each(node.attributes || emptyArray, function(i, attr){ 3645 if (attr.name.indexOf('data-') == 0) 3646 store[camelize(attr.name.replace('data-', ''))] = 3647 $.zepto.deserializeValue(attr.value) 3648 }) 3649 return store 3650 } 3651 3652 $.fn.data = function(name, value) { 3653 return value === undefined ? 3654 // set multiple values via object 3655 $.isPlainObject(name) ? 3656 this.each(function(i, node){ 3657 $.each(name, function(key, value){ setData(node, key, value) }) 3658 }) : 3659 // get value from first element 3660 (0 in this ? getData(this[0], name) : undefined) : 3661 // set value on all elements 3662 this.each(function(){ setData(this, name, value) }) 3663 } 3664 3665 $.data = function(elem, name, value) { 3666 return $(elem).data(name, value) 3667 } 3668 3669 $.hasData = function(elem) { 3670 var id = elem[exp], store = id && data[id] 3671 return store ? !$.isEmptyObject(store) : false 3672 } 3673 3674 $.fn.removeData = function(names) { 3675 if (typeof names == 'string') names = names.split(/\s+/) 3676 return this.each(function(){ 3677 var id = this[exp], store = id && data[id] 3678 if (store) $.each(names || store, function(key){ 3679 delete store[names ? camelize(this) : key] 3680 }) 3681 }) 3682 } 3683 3684 // Generate extended `remove` and `empty` functions 3685 ;['remove', 'empty'].forEach(function(methodName){ 3686 var origFn = $.fn[methodName] 3687 $.fn[methodName] = function() { 3688 var elements = this.find('*') 3689 if (methodName === 'remove') elements = elements.add(this) 3690 elements.removeData() 3691 return origFn.call(this) 3692 } 3693 }) 3694 })(Zepto) 3695 return Zepto 3696 })) 3697 3698 3699 /***/ }), 3700 /* 18 */ 3701 /***/ (function(module, exports, __webpack_require__) { 3702 3703 "use strict"; 3704 3705 3706 Object.defineProperty(exports, "__esModule", { 3707 value: true 3708 }); 3709 exports.default = '2.3.3'; 3710 3711 /***/ }), 3712 /* 19 */ 3713 /***/ (function(module, exports, __webpack_require__) { 3714 3715 "use strict"; 3716 3717 3718 Object.defineProperty(exports, "__esModule", { 3719 value: true 3720 }); 3721 3722 var _zepto = __webpack_require__(17); 3723 3724 var _zepto2 = _interopRequireDefault(_zepto); 3725 3726 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3727 3728 exports.default = _zepto2.default; 3729 3730 /***/ }), 3731 /* 20 */ 3732 /***/ (function(module, exports) { 3733 3734 if (typeof Object.create === 'function') { 3735 // implementation from standard node.js 'util' module 3736 module.exports = function inherits(ctor, superCtor) { 3737 ctor.super_ = superCtor 3738 ctor.prototype = Object.create(superCtor.prototype, { 3739 constructor: { 3740 value: ctor, 3741 enumerable: false, 3742 writable: true, 3743 configurable: true 3744 } 3745 }); 3746 }; 3747 } else { 3748 // old school shim for old browsers 3749 module.exports = function inherits(ctor, superCtor) { 3750 ctor.super_ = superCtor 3751 var TempCtor = function () {} 3752 TempCtor.prototype = superCtor.prototype 3753 ctor.prototype = new TempCtor() 3754 ctor.prototype.constructor = ctor 3755 } 3756 } 3757 3758 3759 /***/ }), 3760 /* 21 */ 3761 /***/ (function(module, exports, __webpack_require__) { 3762 3763 "use strict"; 3764 3765 3766 Object.defineProperty(exports, "__esModule", { 3767 value: true 3768 }); 3769 3770 var _toFactory = __webpack_require__(66); 3771 3772 var _toFactory2 = _interopRequireDefault(_toFactory); 3773 3774 var _DocSearch = __webpack_require__(47); 3775 3776 var _DocSearch2 = _interopRequireDefault(_DocSearch); 3777 3778 var _version = __webpack_require__(18); 3779 3780 var _version2 = _interopRequireDefault(_version); 3781 3782 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 3783 3784 var docsearch = (0, _toFactory2.default)(_DocSearch2.default); 3785 docsearch.version = _version2.default; 3786 3787 exports.default = docsearch; 3788 3789 /***/ }), 3790 /* 22 */ 3791 /***/ (function(module, exports, __webpack_require__) { 3792 3793 module.exports = AlgoliaSearchCore; 3794 3795 var errors = __webpack_require__(5); 3796 var exitPromise = __webpack_require__(31); 3797 var IndexCore = __webpack_require__(23); 3798 var store = __webpack_require__(35); 3799 3800 // We will always put the API KEY in the JSON body in case of too long API KEY, 3801 // to avoid query string being too long and failing in various conditions (our server limit, browser limit, 3802 // proxies limit) 3803 var MAX_API_KEY_LENGTH = 500; 3804 var RESET_APP_DATA_TIMER = 3805 __webpack_require__.i({"NODE_ENV":"production"}).RESET_APP_DATA_TIMER && parseInt(__webpack_require__.i({"NODE_ENV":"production"}).RESET_APP_DATA_TIMER, 10) || 3806 60 * 2 * 1000; // after 2 minutes reset to first host 3807 3808 /* 3809 * Algolia Search library initialization 3810 * https://www.algolia.com/ 3811 * 3812 * @param {string} applicationID - Your applicationID, found in your dashboard 3813 * @param {string} apiKey - Your API key, found in your dashboard 3814 * @param {Object} [opts] 3815 * @param {number} [opts.timeout=2000] - The request timeout set in milliseconds, 3816 * another request will be issued after this timeout 3817 * @param {string} [opts.protocol='http:'] - The protocol used to query Algolia Search API. 3818 * Set to 'https:' to force using https. 3819 * Default to document.location.protocol in browsers 3820 * @param {Object|Array} [opts.hosts={ 3821 * read: [this.applicationID + '-dsn.algolia.net'].concat([ 3822 * this.applicationID + '-1.algolianet.com', 3823 * this.applicationID + '-2.algolianet.com', 3824 * this.applicationID + '-3.algolianet.com'] 3825 * ]), 3826 * write: [this.applicationID + '.algolia.net'].concat([ 3827 * this.applicationID + '-1.algolianet.com', 3828 * this.applicationID + '-2.algolianet.com', 3829 * this.applicationID + '-3.algolianet.com'] 3830 * ]) - The hosts to use for Algolia Search API. 3831 * If you provide them, you will less benefit from our HA implementation 3832 */ 3833 function AlgoliaSearchCore(applicationID, apiKey, opts) { 3834 var debug = __webpack_require__(6)('algoliasearch'); 3835 3836 var clone = __webpack_require__(4); 3837 var isArray = __webpack_require__(7); 3838 var map = __webpack_require__(8); 3839 3840 var usage = 'Usage: algoliasearch(applicationID, apiKey, opts)'; 3841 3842 if (opts._allowEmptyCredentials !== true && !applicationID) { 3843 throw new errors.AlgoliaSearchError('Please provide an application ID. ' + usage); 3844 } 3845 3846 if (opts._allowEmptyCredentials !== true && !apiKey) { 3847 throw new errors.AlgoliaSearchError('Please provide an API key. ' + usage); 3848 } 3849 3850 this.applicationID = applicationID; 3851 this.apiKey = apiKey; 3852 3853 this.hosts = { 3854 read: [], 3855 write: [] 3856 }; 3857 3858 opts = opts || {}; 3859 3860 var protocol = opts.protocol || 'https:'; 3861 this._timeouts = opts.timeouts || { 3862 connect: 1 * 1000, // 500ms connect is GPRS latency 3863 read: 2 * 1000, 3864 write: 30 * 1000 3865 }; 3866 3867 // backward compat, if opts.timeout is passed, we use it to configure all timeouts like before 3868 if (opts.timeout) { 3869 this._timeouts.connect = this._timeouts.read = this._timeouts.write = opts.timeout; 3870 } 3871 3872 // while we advocate for colon-at-the-end values: 'http:' for `opts.protocol` 3873 // we also accept `http` and `https`. It's a common error. 3874 if (!/:$/.test(protocol)) { 3875 protocol = protocol + ':'; 3876 } 3877 3878 if (opts.protocol !== 'http:' && opts.protocol !== 'https:') { 3879 throw new errors.AlgoliaSearchError('protocol must be `http:` or `https:` (was `' + opts.protocol + '`)'); 3880 } 3881 3882 this._checkAppIdData(); 3883 3884 if (!opts.hosts) { 3885 var defaultHosts = map(this._shuffleResult, function(hostNumber) { 3886 return applicationID + '-' + hostNumber + '.algolianet.com'; 3887 }); 3888 3889 // no hosts given, compute defaults 3890 this.hosts.read = [this.applicationID + '-dsn.algolia.net'].concat(defaultHosts); 3891 this.hosts.write = [this.applicationID + '.algolia.net'].concat(defaultHosts); 3892 } else if (isArray(opts.hosts)) { 3893 // when passing custom hosts, we need to have a different host index if the number 3894 // of write/read hosts are different. 3895 this.hosts.read = clone(opts.hosts); 3896 this.hosts.write = clone(opts.hosts); 3897 } else { 3898 this.hosts.read = clone(opts.hosts.read); 3899 this.hosts.write = clone(opts.hosts.write); 3900 } 3901 3902 // add protocol and lowercase hosts 3903 this.hosts.read = map(this.hosts.read, prepareHost(protocol)); 3904 this.hosts.write = map(this.hosts.write, prepareHost(protocol)); 3905 3906 this.extraHeaders = []; 3907 3908 // In some situations you might want to warm the cache 3909 this.cache = opts._cache || {}; 3910 3911 this._ua = opts._ua; 3912 this._useCache = opts._useCache === undefined || opts._cache ? true : opts._useCache; 3913 this._useFallback = opts.useFallback === undefined ? true : opts.useFallback; 3914 3915 this._setTimeout = opts._setTimeout; 3916 3917 debug('init done, %j', this); 3918 } 3919 3920 /* 3921 * Get the index object initialized 3922 * 3923 * @param indexName the name of index 3924 * @param callback the result callback with one argument (the Index instance) 3925 */ 3926 AlgoliaSearchCore.prototype.initIndex = function(indexName) { 3927 return new IndexCore(this, indexName); 3928 }; 3929 3930 /** 3931 * Add an extra field to the HTTP request 3932 * 3933 * @param name the header field name 3934 * @param value the header field value 3935 */ 3936 AlgoliaSearchCore.prototype.setExtraHeader = function(name, value) { 3937 this.extraHeaders.push({ 3938 name: name.toLowerCase(), value: value 3939 }); 3940 }; 3941 3942 /** 3943 * Augment sent x-algolia-agent with more data, each agent part 3944 * is automatically separated from the others by a semicolon; 3945 * 3946 * @param algoliaAgent the agent to add 3947 */ 3948 AlgoliaSearchCore.prototype.addAlgoliaAgent = function(algoliaAgent) { 3949 if (this._ua.indexOf(';' + algoliaAgent) === -1) { 3950 this._ua += ';' + algoliaAgent; 3951 } 3952 }; 3953 3954 /* 3955 * Wrapper that try all hosts to maximize the quality of service 3956 */ 3957 AlgoliaSearchCore.prototype._jsonRequest = function(initialOpts) { 3958 this._checkAppIdData(); 3959 3960 var requestDebug = __webpack_require__(6)('algoliasearch:' + initialOpts.url); 3961 3962 var body; 3963 var additionalUA = initialOpts.additionalUA || ''; 3964 var cache = initialOpts.cache; 3965 var client = this; 3966 var tries = 0; 3967 var usingFallback = false; 3968 var hasFallback = client._useFallback && client._request.fallback && initialOpts.fallback; 3969 var headers; 3970 3971 if ( 3972 this.apiKey.length > MAX_API_KEY_LENGTH && 3973 initialOpts.body !== undefined && 3974 (initialOpts.body.params !== undefined || // index.search() 3975 initialOpts.body.requests !== undefined) // client.search() 3976 ) { 3977 initialOpts.body.apiKey = this.apiKey; 3978 headers = this._computeRequestHeaders(additionalUA, false); 3979 } else { 3980 headers = this._computeRequestHeaders(additionalUA); 3981 } 3982 3983 if (initialOpts.body !== undefined) { 3984 body = safeJSONStringify(initialOpts.body); 3985 } 3986 3987 requestDebug('request start'); 3988 var debugData = []; 3989 3990 function doRequest(requester, reqOpts) { 3991 client._checkAppIdData(); 3992 3993 var startTime = new Date(); 3994 var cacheID; 3995 3996 if (client._useCache) { 3997 cacheID = initialOpts.url; 3998 } 3999 4000 // as we sometime use POST requests to pass parameters (like query='aa'), 4001 // the cacheID must also include the body to be different between calls 4002 if (client._useCache && body) { 4003 cacheID += '_body_' + reqOpts.body; 4004 } 4005 4006 // handle cache existence 4007 if (client._useCache && cache && cache[cacheID] !== undefined) { 4008 requestDebug('serving response from cache'); 4009 return client._promise.resolve(JSON.parse(cache[cacheID])); 4010 } 4011 4012 // if we reached max tries 4013 if (tries >= client.hosts[initialOpts.hostType].length) { 4014 if (!hasFallback || usingFallback) { 4015 requestDebug('could not get any response'); 4016 // then stop 4017 return client._promise.reject(new errors.AlgoliaSearchError( 4018 'Cannot connect to the AlgoliaSearch API.' + 4019 ' Send an email to support@algolia.com to report and resolve the issue.' + 4020 ' Application id was: ' + client.applicationID, {debugData: debugData} 4021 )); 4022 } 4023 4024 requestDebug('switching to fallback'); 4025 4026 // let's try the fallback starting from here 4027 tries = 0; 4028 4029 // method, url and body are fallback dependent 4030 reqOpts.method = initialOpts.fallback.method; 4031 reqOpts.url = initialOpts.fallback.url; 4032 reqOpts.jsonBody = initialOpts.fallback.body; 4033 if (reqOpts.jsonBody) { 4034 reqOpts.body = safeJSONStringify(reqOpts.jsonBody); 4035 } 4036 // re-compute headers, they could be omitting the API KEY 4037 headers = client._computeRequestHeaders(additionalUA); 4038 4039 reqOpts.timeouts = client._getTimeoutsForRequest(initialOpts.hostType); 4040 client._setHostIndexByType(0, initialOpts.hostType); 4041 usingFallback = true; // the current request is now using fallback 4042 return doRequest(client._request.fallback, reqOpts); 4043 } 4044 4045 var currentHost = client._getHostByType(initialOpts.hostType); 4046 4047 var url = currentHost + reqOpts.url; 4048 var options = { 4049 body: reqOpts.body, 4050 jsonBody: reqOpts.jsonBody, 4051 method: reqOpts.method, 4052 headers: headers, 4053 timeouts: reqOpts.timeouts, 4054 debug: requestDebug 4055 }; 4056 4057 requestDebug('method: %s, url: %s, headers: %j, timeouts: %d', 4058 options.method, url, options.headers, options.timeouts); 4059 4060 if (requester === client._request.fallback) { 4061 requestDebug('using fallback'); 4062 } 4063 4064 // `requester` is any of this._request or this._request.fallback 4065 // thus it needs to be called using the client as context 4066 return requester.call(client, url, options).then(success, tryFallback); 4067 4068 function success(httpResponse) { 4069 // compute the status of the response, 4070 // 4071 // When in browser mode, using XDR or JSONP, we have no statusCode available 4072 // So we rely on our API response `status` property. 4073 // But `waitTask` can set a `status` property which is not the statusCode (it's the task status) 4074 // So we check if there's a `message` along `status` and it means it's an error 4075 // 4076 // That's the only case where we have a response.status that's not the http statusCode 4077 var status = httpResponse && httpResponse.body && httpResponse.body.message && httpResponse.body.status || 4078 4079 // this is important to check the request statusCode AFTER the body eventual 4080 // statusCode because some implementations (jQuery XDomainRequest transport) may 4081 // send statusCode 200 while we had an error 4082 httpResponse.statusCode || 4083 4084 // When in browser mode, using XDR or JSONP 4085 // we default to success when no error (no response.status && response.message) 4086 // If there was a JSON.parse() error then body is null and it fails 4087 httpResponse && httpResponse.body && 200; 4088 4089 requestDebug('received response: statusCode: %s, computed statusCode: %d, headers: %j', 4090 httpResponse.statusCode, status, httpResponse.headers); 4091 4092 var httpResponseOk = Math.floor(status / 100) === 2; 4093 4094 var endTime = new Date(); 4095 debugData.push({ 4096 currentHost: currentHost, 4097 headers: removeCredentials(headers), 4098 content: body || null, 4099 contentLength: body !== undefined ? body.length : null, 4100 method: reqOpts.method, 4101 timeouts: reqOpts.timeouts, 4102 url: reqOpts.url, 4103 startTime: startTime, 4104 endTime: endTime, 4105 duration: endTime - startTime, 4106 statusCode: status 4107 }); 4108 4109 if (httpResponseOk) { 4110 if (client._useCache && cache) { 4111 cache[cacheID] = httpResponse.responseText; 4112 } 4113 4114 return httpResponse.body; 4115 } 4116 4117 var shouldRetry = Math.floor(status / 100) !== 4; 4118 4119 if (shouldRetry) { 4120 tries += 1; 4121 return retryRequest(); 4122 } 4123 4124 requestDebug('unrecoverable error'); 4125 4126 // no success and no retry => fail 4127 var unrecoverableError = new errors.AlgoliaSearchError( 4128 httpResponse.body && httpResponse.body.message, {debugData: debugData, statusCode: status} 4129 ); 4130 4131 return client._promise.reject(unrecoverableError); 4132 } 4133 4134 function tryFallback(err) { 4135 // error cases: 4136 // While not in fallback mode: 4137 // - CORS not supported 4138 // - network error 4139 // While in fallback mode: 4140 // - timeout 4141 // - network error 4142 // - badly formatted JSONP (script loaded, did not call our callback) 4143 // In both cases: 4144 // - uncaught exception occurs (TypeError) 4145 requestDebug('error: %s, stack: %s', err.message, err.stack); 4146 4147 var endTime = new Date(); 4148 debugData.push({ 4149 currentHost: currentHost, 4150 headers: removeCredentials(headers), 4151 content: body || null, 4152 contentLength: body !== undefined ? body.length : null, 4153 method: reqOpts.method, 4154 timeouts: reqOpts.timeouts, 4155 url: reqOpts.url, 4156 startTime: startTime, 4157 endTime: endTime, 4158 duration: endTime - startTime 4159 }); 4160 4161 if (!(err instanceof errors.AlgoliaSearchError)) { 4162 err = new errors.Unknown(err && err.message, err); 4163 } 4164 4165 tries += 1; 4166 4167 // stop the request implementation when: 4168 if ( 4169 // we did not generate this error, 4170 // it comes from a throw in some other piece of code 4171 err instanceof errors.Unknown || 4172 4173 // server sent unparsable JSON 4174 err instanceof errors.UnparsableJSON || 4175 4176 // max tries and already using fallback or no fallback 4177 tries >= client.hosts[initialOpts.hostType].length && 4178 (usingFallback || !hasFallback)) { 4179 // stop request implementation for this command 4180 err.debugData = debugData; 4181 return client._promise.reject(err); 4182 } 4183 4184 // When a timeout occurred, retry by raising timeout 4185 if (err instanceof errors.RequestTimeout) { 4186 return retryRequestWithHigherTimeout(); 4187 } 4188 4189 return retryRequest(); 4190 } 4191 4192 function retryRequest() { 4193 requestDebug('retrying request'); 4194 client._incrementHostIndex(initialOpts.hostType); 4195 return doRequest(requester, reqOpts); 4196 } 4197 4198 function retryRequestWithHigherTimeout() { 4199 requestDebug('retrying request with higher timeout'); 4200 client._incrementHostIndex(initialOpts.hostType); 4201 client._incrementTimeoutMultipler(); 4202 reqOpts.timeouts = client._getTimeoutsForRequest(initialOpts.hostType); 4203 return doRequest(requester, reqOpts); 4204 } 4205 } 4206 4207 var promise = doRequest( 4208 client._request, { 4209 url: initialOpts.url, 4210 method: initialOpts.method, 4211 body: body, 4212 jsonBody: initialOpts.body, 4213 timeouts: client._getTimeoutsForRequest(initialOpts.hostType) 4214 } 4215 ); 4216 4217 // either we have a callback 4218 // either we are using promises 4219 if (initialOpts.callback) { 4220 promise.then(function okCb(content) { 4221 exitPromise(function() { 4222 initialOpts.callback(null, content); 4223 }, client._setTimeout || setTimeout); 4224 }, function nookCb(err) { 4225 exitPromise(function() { 4226 initialOpts.callback(err); 4227 }, client._setTimeout || setTimeout); 4228 }); 4229 } else { 4230 return promise; 4231 } 4232 }; 4233 4234 /* 4235 * Transform search param object in query string 4236 * @param {object} args arguments to add to the current query string 4237 * @param {string} params current query string 4238 * @return {string} the final query string 4239 */ 4240 AlgoliaSearchCore.prototype._getSearchParams = function(args, params) { 4241 if (args === undefined || args === null) { 4242 return params; 4243 } 4244 for (var key in args) { 4245 if (key !== null && args[key] !== undefined && args.hasOwnProperty(key)) { 4246 params += params === '' ? '' : '&'; 4247 params += key + '=' + encodeURIComponent(Object.prototype.toString.call(args[key]) === '[object Array]' ? safeJSONStringify(args[key]) : args[key]); 4248 } 4249 } 4250 return params; 4251 }; 4252 4253 AlgoliaSearchCore.prototype._computeRequestHeaders = function(additionalUA, withAPIKey) { 4254 var forEach = __webpack_require__(2); 4255 4256 var ua = additionalUA ? 4257 this._ua + ';' + additionalUA : 4258 this._ua; 4259 4260 var requestHeaders = { 4261 'x-algolia-agent': ua, 4262 'x-algolia-application-id': this.applicationID 4263 }; 4264 4265 // browser will inline headers in the url, node.js will use http headers 4266 // but in some situations, the API KEY will be too long (big secured API keys) 4267 // so if the request is a POST and the KEY is very long, we will be asked to not put 4268 // it into headers but in the JSON body 4269 if (withAPIKey !== false) { 4270 requestHeaders['x-algolia-api-key'] = this.apiKey; 4271 } 4272 4273 if (this.userToken) { 4274 requestHeaders['x-algolia-usertoken'] = this.userToken; 4275 } 4276 4277 if (this.securityTags) { 4278 requestHeaders['x-algolia-tagfilters'] = this.securityTags; 4279 } 4280 4281 if (this.extraHeaders) { 4282 forEach(this.extraHeaders, function addToRequestHeaders(header) { 4283 requestHeaders[header.name] = header.value; 4284 }); 4285 } 4286 4287 return requestHeaders; 4288 }; 4289 4290 /** 4291 * Search through multiple indices at the same time 4292 * @param {Object[]} queries An array of queries you want to run. 4293 * @param {string} queries[].indexName The index name you want to target 4294 * @param {string} [queries[].query] The query to issue on this index. Can also be passed into `params` 4295 * @param {Object} queries[].params Any search param like hitsPerPage, .. 4296 * @param {Function} callback Callback to be called 4297 * @return {Promise|undefined} Returns a promise if no callback given 4298 */ 4299 AlgoliaSearchCore.prototype.search = function(queries, opts, callback) { 4300 var isArray = __webpack_require__(7); 4301 var map = __webpack_require__(8); 4302 4303 var usage = 'Usage: client.search(arrayOfQueries[, callback])'; 4304 4305 if (!isArray(queries)) { 4306 throw new Error(usage); 4307 } 4308 4309 if (typeof opts === 'function') { 4310 callback = opts; 4311 opts = {}; 4312 } else if (opts === undefined) { 4313 opts = {}; 4314 } 4315 4316 var client = this; 4317 4318 var postObj = { 4319 requests: map(queries, function prepareRequest(query) { 4320 var params = ''; 4321 4322 // allow query.query 4323 // so we are mimicing the index.search(query, params) method 4324 // {indexName:, query:, params:} 4325 if (query.query !== undefined) { 4326 params += 'query=' + encodeURIComponent(query.query); 4327 } 4328 4329 return { 4330 indexName: query.indexName, 4331 params: client._getSearchParams(query.params, params) 4332 }; 4333 }) 4334 }; 4335 4336 var JSONPParams = map(postObj.requests, function prepareJSONPParams(request, requestId) { 4337 return requestId + '=' + 4338 encodeURIComponent( 4339 '/1/indexes/' + encodeURIComponent(request.indexName) + '?' + 4340 request.params 4341 ); 4342 }).join('&'); 4343 4344 var url = '/1/indexes/*/queries'; 4345 4346 if (opts.strategy !== undefined) { 4347 url += '?strategy=' + opts.strategy; 4348 } 4349 4350 return this._jsonRequest({ 4351 cache: this.cache, 4352 method: 'POST', 4353 url: url, 4354 body: postObj, 4355 hostType: 'read', 4356 fallback: { 4357 method: 'GET', 4358 url: '/1/indexes/*', 4359 body: { 4360 params: JSONPParams 4361 } 4362 }, 4363 callback: callback 4364 }); 4365 }; 4366 4367 /** 4368 * Set the extra security tagFilters header 4369 * @param {string|array} tags The list of tags defining the current security filters 4370 */ 4371 AlgoliaSearchCore.prototype.setSecurityTags = function(tags) { 4372 if (Object.prototype.toString.call(tags) === '[object Array]') { 4373 var strTags = []; 4374 for (var i = 0; i < tags.length; ++i) { 4375 if (Object.prototype.toString.call(tags[i]) === '[object Array]') { 4376 var oredTags = []; 4377 for (var j = 0; j < tags[i].length; ++j) { 4378 oredTags.push(tags[i][j]); 4379 } 4380 strTags.push('(' + oredTags.join(',') + ')'); 4381 } else { 4382 strTags.push(tags[i]); 4383 } 4384 } 4385 tags = strTags.join(','); 4386 } 4387 4388 this.securityTags = tags; 4389 }; 4390 4391 /** 4392 * Set the extra user token header 4393 * @param {string} userToken The token identifying a uniq user (used to apply rate limits) 4394 */ 4395 AlgoliaSearchCore.prototype.setUserToken = function(userToken) { 4396 this.userToken = userToken; 4397 }; 4398 4399 /** 4400 * Clear all queries in client's cache 4401 * @return undefined 4402 */ 4403 AlgoliaSearchCore.prototype.clearCache = function() { 4404 this.cache = {}; 4405 }; 4406 4407 /** 4408 * Set the number of milliseconds a request can take before automatically being terminated. 4409 * @deprecated 4410 * @param {Number} milliseconds 4411 */ 4412 AlgoliaSearchCore.prototype.setRequestTimeout = function(milliseconds) { 4413 if (milliseconds) { 4414 this._timeouts.connect = this._timeouts.read = this._timeouts.write = milliseconds; 4415 } 4416 }; 4417 4418 /** 4419 * Set the three different (connect, read, write) timeouts to be used when requesting 4420 * @param {Object} timeouts 4421 */ 4422 AlgoliaSearchCore.prototype.setTimeouts = function(timeouts) { 4423 this._timeouts = timeouts; 4424 }; 4425 4426 /** 4427 * Get the three different (connect, read, write) timeouts to be used when requesting 4428 * @param {Object} timeouts 4429 */ 4430 AlgoliaSearchCore.prototype.getTimeouts = function() { 4431 return this._timeouts; 4432 }; 4433 4434 AlgoliaSearchCore.prototype._getAppIdData = function() { 4435 var data = store.get(this.applicationID); 4436 if (data !== null) this._cacheAppIdData(data); 4437 return data; 4438 }; 4439 4440 AlgoliaSearchCore.prototype._setAppIdData = function(data) { 4441 data.lastChange = (new Date()).getTime(); 4442 this._cacheAppIdData(data); 4443 return store.set(this.applicationID, data); 4444 }; 4445 4446 AlgoliaSearchCore.prototype._checkAppIdData = function() { 4447 var data = this._getAppIdData(); 4448 var now = (new Date()).getTime(); 4449 if (data === null || now - data.lastChange > RESET_APP_DATA_TIMER) { 4450 return this._resetInitialAppIdData(data); 4451 } 4452 4453 return data; 4454 }; 4455 4456 AlgoliaSearchCore.prototype._resetInitialAppIdData = function(data) { 4457 var newData = data || {}; 4458 newData.hostIndexes = {read: 0, write: 0}; 4459 newData.timeoutMultiplier = 1; 4460 newData.shuffleResult = newData.shuffleResult || shuffle([1, 2, 3]); 4461 return this._setAppIdData(newData); 4462 }; 4463 4464 AlgoliaSearchCore.prototype._cacheAppIdData = function(data) { 4465 this._hostIndexes = data.hostIndexes; 4466 this._timeoutMultiplier = data.timeoutMultiplier; 4467 this._shuffleResult = data.shuffleResult; 4468 }; 4469 4470 AlgoliaSearchCore.prototype._partialAppIdDataUpdate = function(newData) { 4471 var foreach = __webpack_require__(2); 4472 var currentData = this._getAppIdData(); 4473 foreach(newData, function(value, key) { 4474 currentData[key] = value; 4475 }); 4476 4477 return this._setAppIdData(currentData); 4478 }; 4479 4480 AlgoliaSearchCore.prototype._getHostByType = function(hostType) { 4481 return this.hosts[hostType][this._getHostIndexByType(hostType)]; 4482 }; 4483 4484 AlgoliaSearchCore.prototype._getTimeoutMultiplier = function() { 4485 return this._timeoutMultiplier; 4486 }; 4487 4488 AlgoliaSearchCore.prototype._getHostIndexByType = function(hostType) { 4489 return this._hostIndexes[hostType]; 4490 }; 4491 4492 AlgoliaSearchCore.prototype._setHostIndexByType = function(hostIndex, hostType) { 4493 var clone = __webpack_require__(4); 4494 var newHostIndexes = clone(this._hostIndexes); 4495 newHostIndexes[hostType] = hostIndex; 4496 this._partialAppIdDataUpdate({hostIndexes: newHostIndexes}); 4497 return hostIndex; 4498 }; 4499 4500 AlgoliaSearchCore.prototype._incrementHostIndex = function(hostType) { 4501 return this._setHostIndexByType( 4502 (this._getHostIndexByType(hostType) + 1) % this.hosts[hostType].length, hostType 4503 ); 4504 }; 4505 4506 AlgoliaSearchCore.prototype._incrementTimeoutMultipler = function() { 4507 var timeoutMultiplier = Math.max(this._timeoutMultiplier + 1, 4); 4508 return this._partialAppIdDataUpdate({timeoutMultiplier: timeoutMultiplier}); 4509 }; 4510 4511 AlgoliaSearchCore.prototype._getTimeoutsForRequest = function(hostType) { 4512 return { 4513 connect: this._timeouts.connect * this._timeoutMultiplier, 4514 complete: this._timeouts[hostType] * this._timeoutMultiplier 4515 }; 4516 }; 4517 4518 function prepareHost(protocol) { 4519 return function prepare(host) { 4520 return protocol + '//' + host.toLowerCase(); 4521 }; 4522 } 4523 4524 // Prototype.js < 1.7, a widely used library, defines a weird 4525 // Array.prototype.toJSON function that will fail to stringify our content 4526 // appropriately 4527 // refs: 4528 // - https://groups.google.com/forum/#!topic/prototype-core/E-SAVvV_V9Q 4529 // - https://github.com/sstephenson/prototype/commit/038a2985a70593c1a86c230fadbdfe2e4898a48c 4530 // - http://stackoverflow.com/a/3148441/147079 4531 function safeJSONStringify(obj) { 4532 /* eslint no-extend-native:0 */ 4533 4534 if (Array.prototype.toJSON === undefined) { 4535 return JSON.stringify(obj); 4536 } 4537 4538 var toJSON = Array.prototype.toJSON; 4539 delete Array.prototype.toJSON; 4540 var out = JSON.stringify(obj); 4541 Array.prototype.toJSON = toJSON; 4542 4543 return out; 4544 } 4545 4546 function shuffle(array) { 4547 var currentIndex = array.length; 4548 var temporaryValue; 4549 var randomIndex; 4550 4551 // While there remain elements to shuffle... 4552 while (currentIndex !== 0) { 4553 // Pick a remaining element... 4554 randomIndex = Math.floor(Math.random() * currentIndex); 4555 currentIndex -= 1; 4556 4557 // And swap it with the current element. 4558 temporaryValue = array[currentIndex]; 4559 array[currentIndex] = array[randomIndex]; 4560 array[randomIndex] = temporaryValue; 4561 } 4562 4563 return array; 4564 } 4565 4566 function removeCredentials(headers) { 4567 var newHeaders = {}; 4568 4569 for (var headerName in headers) { 4570 if (Object.prototype.hasOwnProperty.call(headers, headerName)) { 4571 var value; 4572 4573 if (headerName === 'x-algolia-api-key' || headerName === 'x-algolia-application-id') { 4574 value = '**hidden for security purposes**'; 4575 } else { 4576 value = headers[headerName]; 4577 } 4578 4579 newHeaders[headerName] = value; 4580 } 4581 } 4582 4583 return newHeaders; 4584 } 4585 4586 4587 /***/ }), 4588 /* 23 */ 4589 /***/ (function(module, exports, __webpack_require__) { 4590 4591 var buildSearchMethod = __webpack_require__(12); 4592 var deprecate = __webpack_require__(29); 4593 var deprecatedMessage = __webpack_require__(30); 4594 4595 module.exports = IndexCore; 4596 4597 /* 4598 * Index class constructor. 4599 * You should not use this method directly but use initIndex() function 4600 */ 4601 function IndexCore(algoliasearch, indexName) { 4602 this.indexName = indexName; 4603 this.as = algoliasearch; 4604 this.typeAheadArgs = null; 4605 this.typeAheadValueOption = null; 4606 4607 // make sure every index instance has it's own cache 4608 this.cache = {}; 4609 } 4610 4611 /* 4612 * Clear all queries in cache 4613 */ 4614 IndexCore.prototype.clearCache = function() { 4615 this.cache = {}; 4616 }; 4617 4618 /* 4619 * Search inside the index using XMLHttpRequest request (Using a POST query to 4620 * minimize number of OPTIONS queries: Cross-Origin Resource Sharing). 4621 * 4622 * @param {string} [query] the full text query 4623 * @param {object} [args] (optional) if set, contains an object with query parameters: 4624 * - page: (integer) Pagination parameter used to select the page to retrieve. 4625 * Page is zero-based and defaults to 0. Thus, 4626 * to retrieve the 10th page you need to set page=9 4627 * - hitsPerPage: (integer) Pagination parameter used to select the number of hits per page. Defaults to 20. 4628 * - attributesToRetrieve: a string that contains the list of object attributes 4629 * you want to retrieve (let you minimize the answer size). 4630 * Attributes are separated with a comma (for example "name,address"). 4631 * You can also use an array (for example ["name","address"]). 4632 * By default, all attributes are retrieved. You can also use '*' to retrieve all 4633 * values when an attributesToRetrieve setting is specified for your index. 4634 * - attributesToHighlight: a string that contains the list of attributes you 4635 * want to highlight according to the query. 4636 * Attributes are separated by a comma. You can also use an array (for example ["name","address"]). 4637 * If an attribute has no match for the query, the raw value is returned. 4638 * By default all indexed text attributes are highlighted. 4639 * You can use `*` if you want to highlight all textual attributes. 4640 * Numerical attributes are not highlighted. 4641 * A matchLevel is returned for each highlighted attribute and can contain: 4642 * - full: if all the query terms were found in the attribute, 4643 * - partial: if only some of the query terms were found, 4644 * - none: if none of the query terms were found. 4645 * - attributesToSnippet: a string that contains the list of attributes to snippet alongside 4646 * the number of words to return (syntax is `attributeName:nbWords`). 4647 * Attributes are separated by a comma (Example: attributesToSnippet=name:10,content:10). 4648 * You can also use an array (Example: attributesToSnippet: ['name:10','content:10']). 4649 * By default no snippet is computed. 4650 * - minWordSizefor1Typo: the minimum number of characters in a query word to accept one typo in this word. 4651 * Defaults to 3. 4652 * - minWordSizefor2Typos: the minimum number of characters in a query word 4653 * to accept two typos in this word. Defaults to 7. 4654 * - getRankingInfo: if set to 1, the result hits will contain ranking 4655 * information in _rankingInfo attribute. 4656 * - aroundLatLng: search for entries around a given 4657 * latitude/longitude (specified as two floats separated by a comma). 4658 * For example aroundLatLng=47.316669,5.016670). 4659 * You can specify the maximum distance in meters with the aroundRadius parameter (in meters) 4660 * and the precision for ranking with aroundPrecision 4661 * (for example if you set aroundPrecision=100, two objects that are distant of 4662 * less than 100m will be considered as identical for "geo" ranking parameter). 4663 * At indexing, you should specify geoloc of an object with the _geoloc attribute 4664 * (in the form {"_geoloc":{"lat":48.853409, "lng":2.348800}}) 4665 * - insideBoundingBox: search entries inside a given area defined by the two extreme points 4666 * of a rectangle (defined by 4 floats: p1Lat,p1Lng,p2Lat,p2Lng). 4667 * For example insideBoundingBox=47.3165,4.9665,47.3424,5.0201). 4668 * At indexing, you should specify geoloc of an object with the _geoloc attribute 4669 * (in the form {"_geoloc":{"lat":48.853409, "lng":2.348800}}) 4670 * - numericFilters: a string that contains the list of numeric filters you want to 4671 * apply separated by a comma. 4672 * The syntax of one filter is `attributeName` followed by `operand` followed by `value`. 4673 * Supported operands are `<`, `<=`, `=`, `>` and `>=`. 4674 * You can have multiple conditions on one attribute like for example numericFilters=price>100,price<1000. 4675 * You can also use an array (for example numericFilters: ["price>100","price<1000"]). 4676 * - tagFilters: filter the query by a set of tags. You can AND tags by separating them by commas. 4677 * To OR tags, you must add parentheses. For example, tags=tag1,(tag2,tag3) means tag1 AND (tag2 OR tag3). 4678 * You can also use an array, for example tagFilters: ["tag1",["tag2","tag3"]] 4679 * means tag1 AND (tag2 OR tag3). 4680 * At indexing, tags should be added in the _tags** attribute 4681 * of objects (for example {"_tags":["tag1","tag2"]}). 4682 * - facetFilters: filter the query by a list of facets. 4683 * Facets are separated by commas and each facet is encoded as `attributeName:value`. 4684 * For example: `facetFilters=category:Book,author:John%20Doe`. 4685 * You can also use an array (for example `["category:Book","author:John%20Doe"]`). 4686 * - facets: List of object attributes that you want to use for faceting. 4687 * Comma separated list: `"category,author"` or array `['category','author']` 4688 * Only attributes that have been added in **attributesForFaceting** index setting 4689 * can be used in this parameter. 4690 * You can also use `*` to perform faceting on all attributes specified in **attributesForFaceting**. 4691 * - queryType: select how the query words are interpreted, it can be one of the following value: 4692 * - prefixAll: all query words are interpreted as prefixes, 4693 * - prefixLast: only the last word is interpreted as a prefix (default behavior), 4694 * - prefixNone: no query word is interpreted as a prefix. This option is not recommended. 4695 * - optionalWords: a string that contains the list of words that should 4696 * be considered as optional when found in the query. 4697 * Comma separated and array are accepted. 4698 * - distinct: If set to 1, enable the distinct feature (disabled by default) 4699 * if the attributeForDistinct index setting is set. 4700 * This feature is similar to the SQL "distinct" keyword: when enabled 4701 * in a query with the distinct=1 parameter, 4702 * all hits containing a duplicate value for the attributeForDistinct attribute are removed from results. 4703 * For example, if the chosen attribute is show_name and several hits have 4704 * the same value for show_name, then only the best 4705 * one is kept and others are removed. 4706 * - restrictSearchableAttributes: List of attributes you want to use for 4707 * textual search (must be a subset of the attributesToIndex index setting) 4708 * either comma separated or as an array 4709 * @param {function} [callback] the result callback called with two arguments: 4710 * error: null or Error('message'). If false, the content contains the error. 4711 * content: the server answer that contains the list of results. 4712 */ 4713 IndexCore.prototype.search = buildSearchMethod('query'); 4714 4715 /* 4716 * -- BETA -- 4717 * Search a record similar to the query inside the index using XMLHttpRequest request (Using a POST query to 4718 * minimize number of OPTIONS queries: Cross-Origin Resource Sharing). 4719 * 4720 * @param {string} [query] the similar query 4721 * @param {object} [args] (optional) if set, contains an object with query parameters. 4722 * All search parameters are supported (see search function), restrictSearchableAttributes and facetFilters 4723 * are the two most useful to restrict the similar results and get more relevant content 4724 */ 4725 IndexCore.prototype.similarSearch = buildSearchMethod('similarQuery'); 4726 4727 /* 4728 * Browse index content. The response content will have a `cursor` property that you can use 4729 * to browse subsequent pages for this query. Use `index.browseFrom(cursor)` when you want. 4730 * 4731 * @param {string} query - The full text query 4732 * @param {Object} [queryParameters] - Any search query parameter 4733 * @param {Function} [callback] - The result callback called with two arguments 4734 * error: null or Error('message') 4735 * content: the server answer with the browse result 4736 * @return {Promise|undefined} Returns a promise if no callback given 4737 * @example 4738 * index.browse('cool songs', { 4739 * tagFilters: 'public,comments', 4740 * hitsPerPage: 500 4741 * }, callback); 4742 * @see {@link https://www.algolia.com/doc/rest_api#Browse|Algolia REST API Documentation} 4743 */ 4744 IndexCore.prototype.browse = function(query, queryParameters, callback) { 4745 var merge = __webpack_require__(32); 4746 4747 var indexObj = this; 4748 4749 var page; 4750 var hitsPerPage; 4751 4752 // we check variadic calls that are not the one defined 4753 // .browse()/.browse(fn) 4754 // => page = 0 4755 if (arguments.length === 0 || arguments.length === 1 && typeof arguments[0] === 'function') { 4756 page = 0; 4757 callback = arguments[0]; 4758 query = undefined; 4759 } else if (typeof arguments[0] === 'number') { 4760 // .browse(2)/.browse(2, 10)/.browse(2, fn)/.browse(2, 10, fn) 4761 page = arguments[0]; 4762 if (typeof arguments[1] === 'number') { 4763 hitsPerPage = arguments[1]; 4764 } else if (typeof arguments[1] === 'function') { 4765 callback = arguments[1]; 4766 hitsPerPage = undefined; 4767 } 4768 query = undefined; 4769 queryParameters = undefined; 4770 } else if (typeof arguments[0] === 'object') { 4771 // .browse(queryParameters)/.browse(queryParameters, cb) 4772 if (typeof arguments[1] === 'function') { 4773 callback = arguments[1]; 4774 } 4775 queryParameters = arguments[0]; 4776 query = undefined; 4777 } else if (typeof arguments[0] === 'string' && typeof arguments[1] === 'function') { 4778 // .browse(query, cb) 4779 callback = arguments[1]; 4780 queryParameters = undefined; 4781 } 4782 4783 // otherwise it's a .browse(query)/.browse(query, queryParameters)/.browse(query, queryParameters, cb) 4784 4785 // get search query parameters combining various possible calls 4786 // to .browse(); 4787 queryParameters = merge({}, queryParameters || {}, { 4788 page: page, 4789 hitsPerPage: hitsPerPage, 4790 query: query 4791 }); 4792 4793 var params = this.as._getSearchParams(queryParameters, ''); 4794 4795 return this.as._jsonRequest({ 4796 method: 'POST', 4797 url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/browse', 4798 body: {params: params}, 4799 hostType: 'read', 4800 callback: callback 4801 }); 4802 }; 4803 4804 /* 4805 * Continue browsing from a previous position (cursor), obtained via a call to `.browse()`. 4806 * 4807 * @param {string} query - The full text query 4808 * @param {Object} [queryParameters] - Any search query parameter 4809 * @param {Function} [callback] - The result callback called with two arguments 4810 * error: null or Error('message') 4811 * content: the server answer with the browse result 4812 * @return {Promise|undefined} Returns a promise if no callback given 4813 * @example 4814 * index.browseFrom('14lkfsakl32', callback); 4815 * @see {@link https://www.algolia.com/doc/rest_api#Browse|Algolia REST API Documentation} 4816 */ 4817 IndexCore.prototype.browseFrom = function(cursor, callback) { 4818 return this.as._jsonRequest({ 4819 method: 'POST', 4820 url: '/1/indexes/' + encodeURIComponent(this.indexName) + '/browse', 4821 body: {cursor: cursor}, 4822 hostType: 'read', 4823 callback: callback 4824 }); 4825 }; 4826 4827 /* 4828 * Search for facet values 4829 * https://www.algolia.com/doc/rest-api/search#search-for-facet-values 4830 * 4831 * @param {string} params.facetName Facet name, name of the attribute to search for values in. 4832 * Must be declared as a facet 4833 * @param {string} params.facetQuery Query for the facet search 4834 * @param {string} [params.*] Any search parameter of Algolia, 4835 * see https://www.algolia.com/doc/api-client/javascript/search#search-parameters 4836 * Pagination is not supported. The page and hitsPerPage parameters will be ignored. 4837 * @param callback (optional) 4838 */ 4839 IndexCore.prototype.searchForFacetValues = function(params, callback) { 4840 var clone = __webpack_require__(4); 4841 var omit = __webpack_require__(33); 4842 var usage = 'Usage: index.searchForFacetValues({facetName, facetQuery, ...params}[, callback])'; 4843 4844 if (params.facetName === undefined || params.facetQuery === undefined) { 4845 throw new Error(usage); 4846 } 4847 4848 var facetName = params.facetName; 4849 var filteredParams = omit(clone(params), function(keyName) { 4850 return keyName === 'facetName'; 4851 }); 4852 var searchParameters = this.as._getSearchParams(filteredParams, ''); 4853 4854 return this.as._jsonRequest({ 4855 method: 'POST', 4856 url: '/1/indexes/' + 4857 encodeURIComponent(this.indexName) + '/facets/' + encodeURIComponent(facetName) + '/query', 4858 hostType: 'read', 4859 body: {params: searchParameters}, 4860 callback: callback 4861 }); 4862 }; 4863 4864 IndexCore.prototype.searchFacet = deprecate(function(params, callback) { 4865 return this.searchForFacetValues(params, callback); 4866 }, deprecatedMessage( 4867 'index.searchFacet(params[, callback])', 4868 'index.searchForFacetValues(params[, callback])' 4869 )); 4870 4871 IndexCore.prototype._search = function(params, url, callback, additionalUA) { 4872 return this.as._jsonRequest({ 4873 cache: this.cache, 4874 method: 'POST', 4875 url: url || '/1/indexes/' + encodeURIComponent(this.indexName) + '/query', 4876 body: {params: params}, 4877 hostType: 'read', 4878 fallback: { 4879 method: 'GET', 4880 url: '/1/indexes/' + encodeURIComponent(this.indexName), 4881 body: {params: params} 4882 }, 4883 callback: callback, 4884 additionalUA: additionalUA 4885 }); 4886 }; 4887 4888 /* 4889 * Get an object from this index 4890 * 4891 * @param objectID the unique identifier of the object to retrieve 4892 * @param attrs (optional) if set, contains the array of attribute names to retrieve 4893 * @param callback (optional) the result callback called with two arguments 4894 * error: null or Error('message') 4895 * content: the object to retrieve or the error message if a failure occurred 4896 */ 4897 IndexCore.prototype.getObject = function(objectID, attrs, callback) { 4898 var indexObj = this; 4899 4900 if (arguments.length === 1 || typeof attrs === 'function') { 4901 callback = attrs; 4902 attrs = undefined; 4903 } 4904 4905 var params = ''; 4906 if (attrs !== undefined) { 4907 params = '?attributes='; 4908 for (var i = 0; i < attrs.length; ++i) { 4909 if (i !== 0) { 4910 params += ','; 4911 } 4912 params += attrs[i]; 4913 } 4914 } 4915 4916 return this.as._jsonRequest({ 4917 method: 'GET', 4918 url: '/1/indexes/' + encodeURIComponent(indexObj.indexName) + '/' + encodeURIComponent(objectID) + params, 4919 hostType: 'read', 4920 callback: callback 4921 }); 4922 }; 4923 4924 /* 4925 * Get several objects from this index 4926 * 4927 * @param objectIDs the array of unique identifier of objects to retrieve 4928 */ 4929 IndexCore.prototype.getObjects = function(objectIDs, attributesToRetrieve, callback) { 4930 var isArray = __webpack_require__(7); 4931 var map = __webpack_require__(8); 4932 4933 var usage = 'Usage: index.getObjects(arrayOfObjectIDs[, callback])'; 4934 4935 if (!isArray(objectIDs)) { 4936 throw new Error(usage); 4937 } 4938 4939 var indexObj = this; 4940 4941 if (arguments.length === 1 || typeof attributesToRetrieve === 'function') { 4942 callback = attributesToRetrieve; 4943 attributesToRetrieve = undefined; 4944 } 4945 4946 var body = { 4947 requests: map(objectIDs, function prepareRequest(objectID) { 4948 var request = { 4949 indexName: indexObj.indexName, 4950 objectID: objectID 4951 }; 4952 4953 if (attributesToRetrieve) { 4954 request.attributesToRetrieve = attributesToRetrieve.join(','); 4955 } 4956 4957 return request; 4958 }) 4959 }; 4960 4961 return this.as._jsonRequest({ 4962 method: 'POST', 4963 url: '/1/indexes/*/objects', 4964 hostType: 'read', 4965 body: body, 4966 callback: callback 4967 }); 4968 }; 4969 4970 IndexCore.prototype.as = null; 4971 IndexCore.prototype.indexName = null; 4972 IndexCore.prototype.typeAheadArgs = null; 4973 IndexCore.prototype.typeAheadValueOption = null; 4974 4975 4976 /***/ }), 4977 /* 24 */ 4978 /***/ (function(module, exports, __webpack_require__) { 4979 4980 "use strict"; 4981 4982 4983 var AlgoliaSearchCore = __webpack_require__(22); 4984 var createAlgoliasearch = __webpack_require__(25); 4985 4986 module.exports = createAlgoliasearch(AlgoliaSearchCore, '(lite) '); 4987 4988 4989 /***/ }), 4990 /* 25 */ 4991 /***/ (function(module, exports, __webpack_require__) { 4992 4993 "use strict"; 4994 4995 4996 var global = __webpack_require__(52); 4997 var Promise = global.Promise || __webpack_require__(51).Promise; 4998 4999 // This is the standalone browser build entry point 5000 // Browser implementation of the Algolia Search JavaScript client, 5001 // using XMLHttpRequest, XDomainRequest and JSONP as fallback 5002 module.exports = function createAlgoliasearch(AlgoliaSearch, uaSuffix) { 5003 var inherits = __webpack_require__(20); 5004 var errors = __webpack_require__(5); 5005 var inlineHeaders = __webpack_require__(27); 5006 var jsonpRequest = __webpack_require__(28); 5007 var places = __webpack_require__(34); 5008 uaSuffix = uaSuffix || ''; 5009 5010 if (false) { 5011 require('debug').enable('algoliasearch*'); 5012 } 5013 5014 function algoliasearch(applicationID, apiKey, opts) { 5015 var cloneDeep = __webpack_require__(4); 5016 5017 var getDocumentProtocol = __webpack_require__(26); 5018 5019 opts = cloneDeep(opts || {}); 5020 5021 if (opts.protocol === undefined) { 5022 opts.protocol = getDocumentProtocol(); 5023 } 5024 5025 opts._ua = opts._ua || algoliasearch.ua; 5026 5027 return new AlgoliaSearchBrowser(applicationID, apiKey, opts); 5028 } 5029 5030 algoliasearch.version = __webpack_require__(36); 5031 algoliasearch.ua = 'Algolia for vanilla JavaScript ' + uaSuffix + algoliasearch.version; 5032 algoliasearch.initPlaces = places(algoliasearch); 5033 5034 // we expose into window no matter how we are used, this will allow 5035 // us to easily debug any website running algolia 5036 global.__algolia = { 5037 debug: __webpack_require__(6), 5038 algoliasearch: algoliasearch 5039 }; 5040 5041 var support = { 5042 hasXMLHttpRequest: 'XMLHttpRequest' in global, 5043 hasXDomainRequest: 'XDomainRequest' in global 5044 }; 5045 5046 if (support.hasXMLHttpRequest) { 5047 support.cors = 'withCredentials' in new XMLHttpRequest(); 5048 } 5049 5050 function AlgoliaSearchBrowser() { 5051 // call AlgoliaSearch constructor 5052 AlgoliaSearch.apply(this, arguments); 5053 } 5054 5055 inherits(AlgoliaSearchBrowser, AlgoliaSearch); 5056 5057 AlgoliaSearchBrowser.prototype._request = function request(url, opts) { 5058 return new Promise(function wrapRequest(resolve, reject) { 5059 // no cors or XDomainRequest, no request 5060 if (!support.cors && !support.hasXDomainRequest) { 5061 // very old browser, not supported 5062 reject(new errors.Network('CORS not supported')); 5063 return; 5064 } 5065 5066 url = inlineHeaders(url, opts.headers); 5067 5068 var body = opts.body; 5069 var req = support.cors ? new XMLHttpRequest() : new XDomainRequest(); 5070 var reqTimeout; 5071 var timedOut; 5072 var connected = false; 5073 5074 reqTimeout = setTimeout(onTimeout, opts.timeouts.connect); 5075 // we set an empty onprogress listener 5076 // so that XDomainRequest on IE9 is not aborted 5077 // refs: 5078 // - https://github.com/algolia/algoliasearch-client-js/issues/76 5079 // - https://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified?forum=iewebdevelopment 5080 req.onprogress = onProgress; 5081 if ('onreadystatechange' in req) req.onreadystatechange = onReadyStateChange; 5082 req.onload = onLoad; 5083 req.onerror = onError; 5084 5085 // do not rely on default XHR async flag, as some analytics code like hotjar 5086 // breaks it and set it to false by default 5087 if (req instanceof XMLHttpRequest) { 5088 req.open(opts.method, url, true); 5089 } else { 5090 req.open(opts.method, url); 5091 } 5092 5093 // headers are meant to be sent after open 5094 if (support.cors) { 5095 if (body) { 5096 if (opts.method === 'POST') { 5097 // https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Simple_requests 5098 req.setRequestHeader('content-type', 'application/x-www-form-urlencoded'); 5099 } else { 5100 req.setRequestHeader('content-type', 'application/json'); 5101 } 5102 } 5103 req.setRequestHeader('accept', 'application/json'); 5104 } 5105 5106 req.send(body); 5107 5108 // event object not received in IE8, at least 5109 // but we do not use it, still important to note 5110 function onLoad(/* event */) { 5111 // When browser does not supports req.timeout, we can 5112 // have both a load and timeout event, since handled by a dumb setTimeout 5113 if (timedOut) { 5114 return; 5115 } 5116 5117 clearTimeout(reqTimeout); 5118 5119 var out; 5120 5121 try { 5122 out = { 5123 body: JSON.parse(req.responseText), 5124 responseText: req.responseText, 5125 statusCode: req.status, 5126 // XDomainRequest does not have any response headers 5127 headers: req.getAllResponseHeaders && req.getAllResponseHeaders() || {} 5128 }; 5129 } catch (e) { 5130 out = new errors.UnparsableJSON({ 5131 more: req.responseText 5132 }); 5133 } 5134 5135 if (out instanceof errors.UnparsableJSON) { 5136 reject(out); 5137 } else { 5138 resolve(out); 5139 } 5140 } 5141 5142 function onError(event) { 5143 if (timedOut) { 5144 return; 5145 } 5146 5147 clearTimeout(reqTimeout); 5148 5149 // error event is trigerred both with XDR/XHR on: 5150 // - DNS error 5151 // - unallowed cross domain request 5152 reject( 5153 new errors.Network({ 5154 more: event 5155 }) 5156 ); 5157 } 5158 5159 function onTimeout() { 5160 timedOut = true; 5161 req.abort(); 5162 5163 reject(new errors.RequestTimeout()); 5164 } 5165 5166 function onConnect() { 5167 connected = true; 5168 clearTimeout(reqTimeout); 5169 reqTimeout = setTimeout(onTimeout, opts.timeouts.complete); 5170 } 5171 5172 function onProgress() { 5173 if (!connected) onConnect(); 5174 } 5175 5176 function onReadyStateChange() { 5177 if (!connected && req.readyState > 1) onConnect(); 5178 } 5179 }); 5180 }; 5181 5182 AlgoliaSearchBrowser.prototype._request.fallback = function requestFallback(url, opts) { 5183 url = inlineHeaders(url, opts.headers); 5184 5185 return new Promise(function wrapJsonpRequest(resolve, reject) { 5186 jsonpRequest(url, opts, function jsonpRequestDone(err, content) { 5187 if (err) { 5188 reject(err); 5189 return; 5190 } 5191 5192 resolve(content); 5193 }); 5194 }); 5195 }; 5196 5197 AlgoliaSearchBrowser.prototype._promise = { 5198 reject: function rejectPromise(val) { 5199 return Promise.reject(val); 5200 }, 5201 resolve: function resolvePromise(val) { 5202 return Promise.resolve(val); 5203 }, 5204 delay: function delayPromise(ms) { 5205 return new Promise(function resolveOnTimeout(resolve/* , reject*/) { 5206 setTimeout(resolve, ms); 5207 }); 5208 } 5209 }; 5210 5211 return algoliasearch; 5212 }; 5213 5214 5215 /***/ }), 5216 /* 26 */ 5217 /***/ (function(module, exports, __webpack_require__) { 5218 5219 "use strict"; 5220 5221 5222 module.exports = getDocumentProtocol; 5223 5224 function getDocumentProtocol() { 5225 var protocol = window.document.location.protocol; 5226 5227 // when in `file:` mode (local html file), default to `http:` 5228 if (protocol !== 'http:' && protocol !== 'https:') { 5229 protocol = 'http:'; 5230 } 5231 5232 return protocol; 5233 } 5234 5235 5236 /***/ }), 5237 /* 27 */ 5238 /***/ (function(module, exports, __webpack_require__) { 5239 5240 "use strict"; 5241 5242 5243 module.exports = inlineHeaders; 5244 5245 var encode = __webpack_require__(65); 5246 5247 function inlineHeaders(url, headers) { 5248 if (/\?/.test(url)) { 5249 url += '&'; 5250 } else { 5251 url += '?'; 5252 } 5253 5254 return url + encode(headers); 5255 } 5256 5257 5258 /***/ }), 5259 /* 28 */ 5260 /***/ (function(module, exports, __webpack_require__) { 5261 5262 "use strict"; 5263 5264 5265 module.exports = jsonpRequest; 5266 5267 var errors = __webpack_require__(5); 5268 5269 var JSONPCounter = 0; 5270 5271 function jsonpRequest(url, opts, cb) { 5272 if (opts.method !== 'GET') { 5273 cb(new Error('Method ' + opts.method + ' ' + url + ' is not supported by JSONP.')); 5274 return; 5275 } 5276 5277 opts.debug('JSONP: start'); 5278 5279 var cbCalled = false; 5280 var timedOut = false; 5281 5282 JSONPCounter += 1; 5283 var head = document.getElementsByTagName('head')[0]; 5284 var script = document.createElement('script'); 5285 var cbName = 'algoliaJSONP_' + JSONPCounter; 5286 var done = false; 5287 5288 window[cbName] = function(data) { 5289 removeGlobals(); 5290 5291 if (timedOut) { 5292 opts.debug('JSONP: Late answer, ignoring'); 5293 return; 5294 } 5295 5296 cbCalled = true; 5297 5298 clean(); 5299 5300 cb(null, { 5301 body: data/* , 5302 // We do not send the statusCode, there's no statusCode in JSONP, it will be 5303 // computed using data.status && data.message like with XDR 5304 statusCode*/ 5305 }); 5306 }; 5307 5308 // add callback by hand 5309 url += '&callback=' + cbName; 5310 5311 // add body params manually 5312 if (opts.jsonBody && opts.jsonBody.params) { 5313 url += '&' + opts.jsonBody.params; 5314 } 5315 5316 var ontimeout = setTimeout(timeout, opts.timeouts.complete); 5317 5318 // script onreadystatechange needed only for 5319 // <= IE8 5320 // https://github.com/angular/angular.js/issues/4523 5321 script.onreadystatechange = readystatechange; 5322 script.onload = success; 5323 script.onerror = error; 5324 5325 script.async = true; 5326 script.defer = true; 5327 script.src = url; 5328 head.appendChild(script); 5329 5330 function success() { 5331 opts.debug('JSONP: success'); 5332 5333 if (done || timedOut) { 5334 return; 5335 } 5336 5337 done = true; 5338 5339 // script loaded but did not call the fn => script loading error 5340 if (!cbCalled) { 5341 opts.debug('JSONP: Fail. Script loaded but did not call the callback'); 5342 clean(); 5343 cb(new errors.JSONPScriptFail()); 5344 } 5345 } 5346 5347 function readystatechange() { 5348 if (this.readyState === 'loaded' || this.readyState === 'complete') { 5349 success(); 5350 } 5351 } 5352 5353 function clean() { 5354 clearTimeout(ontimeout); 5355 script.onload = null; 5356 script.onreadystatechange = null; 5357 script.onerror = null; 5358 head.removeChild(script); 5359 } 5360 5361 function removeGlobals() { 5362 try { 5363 delete window[cbName]; 5364 delete window[cbName + '_loaded']; 5365 } catch (e) { 5366 window[cbName] = window[cbName + '_loaded'] = undefined; 5367 } 5368 } 5369 5370 function timeout() { 5371 opts.debug('JSONP: Script timeout'); 5372 timedOut = true; 5373 clean(); 5374 cb(new errors.RequestTimeout()); 5375 } 5376 5377 function error() { 5378 opts.debug('JSONP: Script error'); 5379 5380 if (done || timedOut) { 5381 return; 5382 } 5383 5384 clean(); 5385 cb(new errors.JSONPScriptError()); 5386 } 5387 } 5388 5389 5390 /***/ }), 5391 /* 29 */ 5392 /***/ (function(module, exports) { 5393 5394 module.exports = function deprecate(fn, message) { 5395 var warned = false; 5396 5397 function deprecated() { 5398 if (!warned) { 5399 /* eslint no-console:0 */ 5400 console.log(message); 5401 warned = true; 5402 } 5403 5404 return fn.apply(this, arguments); 5405 } 5406 5407 return deprecated; 5408 }; 5409 5410 5411 /***/ }), 5412 /* 30 */ 5413 /***/ (function(module, exports) { 5414 5415 module.exports = function deprecatedMessage(previousUsage, newUsage) { 5416 var githubAnchorLink = previousUsage.toLowerCase() 5417 .replace('.', '') 5418 .replace('()', ''); 5419 5420 return 'algoliasearch: `' + previousUsage + '` was replaced by `' + newUsage + 5421 '`. Please see https://github.com/algolia/algoliasearch-client-js/wiki/Deprecated#' + githubAnchorLink; 5422 }; 5423 5424 5425 /***/ }), 5426 /* 31 */ 5427 /***/ (function(module, exports) { 5428 5429 // Parse cloud does not supports setTimeout 5430 // We do not store a setTimeout reference in the client everytime 5431 // We only fallback to a fake setTimeout when not available 5432 // setTimeout cannot be override globally sadly 5433 module.exports = function exitPromise(fn, _setTimeout) { 5434 _setTimeout(fn, 0); 5435 }; 5436 5437 5438 /***/ }), 5439 /* 32 */ 5440 /***/ (function(module, exports, __webpack_require__) { 5441 5442 var foreach = __webpack_require__(2); 5443 5444 module.exports = function merge(destination/* , sources */) { 5445 var sources = Array.prototype.slice.call(arguments); 5446 5447 foreach(sources, function(source) { 5448 for (var keyName in source) { 5449 if (source.hasOwnProperty(keyName)) { 5450 if (typeof destination[keyName] === 'object' && typeof source[keyName] === 'object') { 5451 destination[keyName] = merge({}, destination[keyName], source[keyName]); 5452 } else if (source[keyName] !== undefined) { 5453 destination[keyName] = source[keyName]; 5454 } 5455 } 5456 } 5457 }); 5458 5459 return destination; 5460 }; 5461 5462 5463 /***/ }), 5464 /* 33 */ 5465 /***/ (function(module, exports, __webpack_require__) { 5466 5467 module.exports = function omit(obj, test) { 5468 var keys = __webpack_require__(63); 5469 var foreach = __webpack_require__(2); 5470 5471 var filtered = {}; 5472 5473 foreach(keys(obj), function doFilter(keyName) { 5474 if (test(keyName) !== true) { 5475 filtered[keyName] = obj[keyName]; 5476 } 5477 }); 5478 5479 return filtered; 5480 }; 5481 5482 5483 /***/ }), 5484 /* 34 */ 5485 /***/ (function(module, exports, __webpack_require__) { 5486 5487 module.exports = createPlacesClient; 5488 5489 var buildSearchMethod = __webpack_require__(12); 5490 5491 function createPlacesClient(algoliasearch) { 5492 return function places(appID, apiKey, opts) { 5493 var cloneDeep = __webpack_require__(4); 5494 5495 opts = opts && cloneDeep(opts) || {}; 5496 opts.hosts = opts.hosts || [ 5497 'places-dsn.algolia.net', 5498 'places-1.algolianet.com', 5499 'places-2.algolianet.com', 5500 'places-3.algolianet.com' 5501 ]; 5502 5503 // allow initPlaces() no arguments => community rate limited 5504 if (arguments.length === 0 || typeof appID === 'object' || appID === undefined) { 5505 appID = ''; 5506 apiKey = ''; 5507 opts._allowEmptyCredentials = true; 5508 } 5509 5510 var client = algoliasearch(appID, apiKey, opts); 5511 var index = client.initIndex('places'); 5512 index.search = buildSearchMethod('query', '/1/places/query'); 5513 return index; 5514 }; 5515 } 5516 5517 5518 /***/ }), 5519 /* 35 */ 5520 /***/ (function(module, exports, __webpack_require__) { 5521 5522 /* WEBPACK VAR INJECTION */(function(global) {var debug = __webpack_require__(6)('algoliasearch:src/hostIndexState.js'); 5523 var localStorageNamespace = 'algoliasearch-client-js'; 5524 5525 var store; 5526 var moduleStore = { 5527 state: {}, 5528 set: function(key, data) { 5529 this.state[key] = data; 5530 return this.state[key]; 5531 }, 5532 get: function(key) { 5533 return this.state[key] || null; 5534 } 5535 }; 5536 5537 var localStorageStore = { 5538 set: function(key, data) { 5539 moduleStore.set(key, data); // always replicate localStorageStore to moduleStore in case of failure 5540 5541 try { 5542 var namespace = JSON.parse(global.localStorage[localStorageNamespace]); 5543 namespace[key] = data; 5544 global.localStorage[localStorageNamespace] = JSON.stringify(namespace); 5545 return namespace[key]; 5546 } catch (e) { 5547 return localStorageFailure(key, e); 5548 } 5549 }, 5550 get: function(key) { 5551 try { 5552 return JSON.parse(global.localStorage[localStorageNamespace])[key] || null; 5553 } catch (e) { 5554 return localStorageFailure(key, e); 5555 } 5556 } 5557 }; 5558 5559 function localStorageFailure(key, e) { 5560 debug('localStorage failed with', e); 5561 cleanup(); 5562 store = moduleStore; 5563 return store.get(key); 5564 } 5565 5566 store = supportsLocalStorage() ? localStorageStore : moduleStore; 5567 5568 module.exports = { 5569 get: getOrSet, 5570 set: getOrSet, 5571 supportsLocalStorage: supportsLocalStorage 5572 }; 5573 5574 function getOrSet(key, data) { 5575 if (arguments.length === 1) { 5576 return store.get(key); 5577 } 5578 5579 return store.set(key, data); 5580 } 5581 5582 function supportsLocalStorage() { 5583 try { 5584 if ('localStorage' in global && 5585 global.localStorage !== null) { 5586 if (!global.localStorage[localStorageNamespace]) { 5587 // actual creation of the namespace 5588 global.localStorage.setItem(localStorageNamespace, JSON.stringify({})); 5589 } 5590 return true; 5591 } 5592 5593 return false; 5594 } catch (_) { 5595 return false; 5596 } 5597 } 5598 5599 // In case of any error on localStorage, we clean our own namespace, this should handle 5600 // quota errors when a lot of keys + data are used 5601 function cleanup() { 5602 try { 5603 global.localStorage.removeItem(localStorageNamespace); 5604 } catch (_) { 5605 // nothing to do 5606 } 5607 } 5608 5609 /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) 5610 5611 /***/ }), 5612 /* 36 */ 5613 /***/ (function(module, exports, __webpack_require__) { 5614 5615 "use strict"; 5616 5617 5618 module.exports = '3.22.1'; 5619 5620 5621 /***/ }), 5622 /* 37 */ 5623 /***/ (function(module, exports, __webpack_require__) { 5624 5625 "use strict"; 5626 5627 5628 module.exports = __webpack_require__(45); 5629 5630 5631 /***/ }), 5632 /* 38 */ 5633 /***/ (function(module, exports, __webpack_require__) { 5634 5635 "use strict"; 5636 5637 5638 var datasetKey = 'aaDataset'; 5639 var valueKey = 'aaValue'; 5640 var datumKey = 'aaDatum'; 5641 5642 var _ = __webpack_require__(0); 5643 var DOM = __webpack_require__(1); 5644 var html = __webpack_require__(14); 5645 var css = __webpack_require__(9); 5646 var EventEmitter = __webpack_require__(10); 5647 5648 // constructor 5649 // ----------- 5650 5651 function Dataset(o) { 5652 o = o || {}; 5653 o.templates = o.templates || {}; 5654 5655 if (!o.source) { 5656 _.error('missing source'); 5657 } 5658 5659 if (o.name && !isValidName(o.name)) { 5660 _.error('invalid dataset name: ' + o.name); 5661 } 5662 5663 // tracks the last query the dataset was updated for 5664 this.query = null; 5665 this._isEmpty = true; 5666 5667 this.highlight = !!o.highlight; 5668 this.name = typeof o.name === 'undefined' || o.name === null ? _.getUniqueId() : o.name; 5669 5670 this.source = o.source; 5671 this.displayFn = getDisplayFn(o.display || o.displayKey); 5672 5673 this.templates = getTemplates(o.templates, this.displayFn); 5674 5675 this.css = _.mixin({}, css, o.appendTo ? css.appendTo : {}); 5676 this.cssClasses = o.cssClasses = _.mixin({}, css.defaultClasses, o.cssClasses || {}); 5677 this.cssClasses.prefix = 5678 o.cssClasses.formattedPrefix || _.formatPrefix(this.cssClasses.prefix, this.cssClasses.noPrefix); 5679 5680 var clazz = _.className(this.cssClasses.prefix, this.cssClasses.dataset); 5681 this.$el = o.$menu && o.$menu.find(clazz + '-' + this.name).length > 0 ? 5682 DOM.element(o.$menu.find(clazz + '-' + this.name)[0]) : 5683 DOM.element( 5684 html.dataset.replace('%CLASS%', this.name) 5685 .replace('%PREFIX%', this.cssClasses.prefix) 5686 .replace('%DATASET%', this.cssClasses.dataset) 5687 ); 5688 5689 this.$menu = o.$menu; 5690 } 5691 5692 // static methods 5693 // -------------- 5694 5695 Dataset.extractDatasetName = function extractDatasetName(el) { 5696 return DOM.element(el).data(datasetKey); 5697 }; 5698 5699 Dataset.extractValue = function extractValue(el) { 5700 return DOM.element(el).data(valueKey); 5701 }; 5702 5703 Dataset.extractDatum = function extractDatum(el) { 5704 var datum = DOM.element(el).data(datumKey); 5705 if (typeof datum === 'string') { 5706 // Zepto has an automatic deserialization of the 5707 // JSON encoded data attribute 5708 datum = JSON.parse(datum); 5709 } 5710 return datum; 5711 }; 5712 5713 // instance methods 5714 // ---------------- 5715 5716 _.mixin(Dataset.prototype, EventEmitter, { 5717 5718 // ### private 5719 5720 _render: function render(query, suggestions) { 5721 if (!this.$el) { 5722 return; 5723 } 5724 var that = this; 5725 5726 var hasSuggestions; 5727 var renderArgs = [].slice.call(arguments, 2); 5728 this.$el.empty(); 5729 5730 hasSuggestions = suggestions && suggestions.length; 5731 this._isEmpty = !hasSuggestions; 5732 5733 if (!hasSuggestions && this.templates.empty) { 5734 this.$el 5735 .html(getEmptyHtml.apply(this, renderArgs)) 5736 .prepend(that.templates.header ? getHeaderHtml.apply(this, renderArgs) : null) 5737 .append(that.templates.footer ? getFooterHtml.apply(this, renderArgs) : null); 5738 } else if (hasSuggestions) { 5739 this.$el 5740 .html(getSuggestionsHtml.apply(this, renderArgs)) 5741 .prepend(that.templates.header ? getHeaderHtml.apply(this, renderArgs) : null) 5742 .append(that.templates.footer ? getFooterHtml.apply(this, renderArgs) : null); 5743 } 5744 5745 if (this.$menu) { 5746 this.$menu.addClass( 5747 this.cssClasses.prefix + (hasSuggestions ? 'with' : 'without') + '-' + this.name 5748 ).removeClass( 5749 this.cssClasses.prefix + (hasSuggestions ? 'without' : 'with') + '-' + this.name 5750 ); 5751 } 5752 5753 this.trigger('rendered', query); 5754 5755 function getEmptyHtml() { 5756 var args = [].slice.call(arguments, 0); 5757 args = [{query: query, isEmpty: true}].concat(args); 5758 return that.templates.empty.apply(this, args); 5759 } 5760 5761 function getSuggestionsHtml() { 5762 var args = [].slice.call(arguments, 0); 5763 var $suggestions; 5764 var nodes; 5765 var self = this; 5766 5767 var suggestionsHtml = html.suggestions. 5768 replace('%PREFIX%', this.cssClasses.prefix). 5769 replace('%SUGGESTIONS%', this.cssClasses.suggestions); 5770 $suggestions = DOM 5771 .element(suggestionsHtml) 5772 .css(this.css.suggestions); 5773 5774 // jQuery#append doesn't support arrays as the first argument 5775 // until version 1.8, see http://bugs.jquery.com/ticket/11231 5776 nodes = _.map(suggestions, getSuggestionNode); 5777 $suggestions.append.apply($suggestions, nodes); 5778 5779 return $suggestions; 5780 5781 function getSuggestionNode(suggestion) { 5782 var $el; 5783 5784 var suggestionHtml = html.suggestion. 5785 replace('%PREFIX%', self.cssClasses.prefix). 5786 replace('%SUGGESTION%', self.cssClasses.suggestion); 5787 $el = DOM.element(suggestionHtml) 5788 .attr({ 5789 role: 'option', 5790 id: ['option', Math.floor(Math.random() * 100000000)].join('-') 5791 }) 5792 .append(that.templates.suggestion.apply(this, [suggestion].concat(args))); 5793 5794 $el.data(datasetKey, that.name); 5795 $el.data(valueKey, that.displayFn(suggestion) || undefined); // this led to undefined return value 5796 $el.data(datumKey, JSON.stringify(suggestion)); 5797 $el.children().each(function() { DOM.element(this).css(self.css.suggestionChild); }); 5798 5799 return $el; 5800 } 5801 } 5802 5803 function getHeaderHtml() { 5804 var args = [].slice.call(arguments, 0); 5805 args = [{query: query, isEmpty: !hasSuggestions}].concat(args); 5806 return that.templates.header.apply(this, args); 5807 } 5808 5809 function getFooterHtml() { 5810 var args = [].slice.call(arguments, 0); 5811 args = [{query: query, isEmpty: !hasSuggestions}].concat(args); 5812 return that.templates.footer.apply(this, args); 5813 } 5814 }, 5815 5816 // ### public 5817 5818 getRoot: function getRoot() { 5819 return this.$el; 5820 }, 5821 5822 update: function update(query) { 5823 var that = this; 5824 5825 this.query = query; 5826 this.canceled = false; 5827 this.source(query, render); 5828 5829 function render(suggestions) { 5830 // if the update has been canceled or if the query has changed 5831 // do not render the suggestions as they've become outdated 5832 if (!that.canceled && query === that.query) { 5833 // concat all the other arguments that could have been passed 5834 // to the render function, and forward them to _render 5835 var args = [].slice.call(arguments, 1); 5836 args = [query, suggestions].concat(args); 5837 that._render.apply(that, args); 5838 } 5839 } 5840 }, 5841 5842 cancel: function cancel() { 5843 this.canceled = true; 5844 }, 5845 5846 clear: function clear() { 5847 this.cancel(); 5848 this.$el.empty(); 5849 this.trigger('rendered', ''); 5850 }, 5851 5852 isEmpty: function isEmpty() { 5853 return this._isEmpty; 5854 }, 5855 5856 destroy: function destroy() { 5857 this.$el = null; 5858 } 5859 }); 5860 5861 // helper functions 5862 // ---------------- 5863 5864 function getDisplayFn(display) { 5865 display = display || 'value'; 5866 5867 return _.isFunction(display) ? display : displayFn; 5868 5869 function displayFn(obj) { 5870 return obj[display]; 5871 } 5872 } 5873 5874 function getTemplates(templates, displayFn) { 5875 return { 5876 empty: templates.empty && _.templatify(templates.empty), 5877 header: templates.header && _.templatify(templates.header), 5878 footer: templates.footer && _.templatify(templates.footer), 5879 suggestion: templates.suggestion || suggestionTemplate 5880 }; 5881 5882 function suggestionTemplate(context) { 5883 return '<p>' + displayFn(context) + '</p>'; 5884 } 5885 } 5886 5887 function isValidName(str) { 5888 // dashes, underscores, letters, and numbers 5889 return (/^[_a-zA-Z0-9-]+$/).test(str); 5890 } 5891 5892 module.exports = Dataset; 5893 5894 5895 /***/ }), 5896 /* 39 */ 5897 /***/ (function(module, exports, __webpack_require__) { 5898 5899 "use strict"; 5900 5901 5902 var _ = __webpack_require__(0); 5903 var DOM = __webpack_require__(1); 5904 var EventEmitter = __webpack_require__(10); 5905 var Dataset = __webpack_require__(38); 5906 var css = __webpack_require__(9); 5907 5908 // constructor 5909 // ----------- 5910 5911 function Dropdown(o) { 5912 var that = this; 5913 var onSuggestionClick; 5914 var onSuggestionMouseEnter; 5915 var onSuggestionMouseLeave; 5916 5917 o = o || {}; 5918 5919 if (!o.menu) { 5920 _.error('menu is required'); 5921 } 5922 5923 if (!_.isArray(o.datasets) && !_.isObject(o.datasets)) { 5924 _.error('1 or more datasets required'); 5925 } 5926 if (!o.datasets) { 5927 _.error('datasets is required'); 5928 } 5929 5930 this.isOpen = false; 5931 this.isEmpty = true; 5932 this.minLength = o.minLength || 0; 5933 this.templates = {}; 5934 this.appendTo = o.appendTo || false; 5935 this.css = _.mixin({}, css, o.appendTo ? css.appendTo : {}); 5936 this.cssClasses = o.cssClasses = _.mixin({}, css.defaultClasses, o.cssClasses || {}); 5937 this.cssClasses.prefix = 5938 o.cssClasses.formattedPrefix || _.formatPrefix(this.cssClasses.prefix, this.cssClasses.noPrefix); 5939 5940 // bound functions 5941 onSuggestionClick = _.bind(this._onSuggestionClick, this); 5942 onSuggestionMouseEnter = _.bind(this._onSuggestionMouseEnter, this); 5943 onSuggestionMouseLeave = _.bind(this._onSuggestionMouseLeave, this); 5944 5945 var cssClass = _.className(this.cssClasses.prefix, this.cssClasses.suggestion); 5946 this.$menu = DOM.element(o.menu) 5947 .on('click.aa', cssClass, onSuggestionClick) 5948 .on('mouseenter.aa', cssClass, onSuggestionMouseEnter) 5949 .on('mouseleave.aa', cssClass, onSuggestionMouseLeave); 5950 5951 this.$container = o.appendTo ? o.wrapper : this.$menu; 5952 5953 if (o.templates && o.templates.header) { 5954 this.templates.header = _.templatify(o.templates.header); 5955 this.$menu.prepend(this.templates.header()); 5956 } 5957 5958 if (o.templates && o.templates.empty) { 5959 this.templates.empty = _.templatify(o.templates.empty); 5960 this.$empty = DOM.element('<div class="' + 5961 _.className(this.cssClasses.prefix, this.cssClasses.empty, true) + '">' + 5962 '</div>'); 5963 this.$menu.append(this.$empty); 5964 } 5965 5966 this.datasets = _.map(o.datasets, function(oDataset) { 5967 return initializeDataset(that.$menu, oDataset, o.cssClasses); 5968 }); 5969 _.each(this.datasets, function(dataset) { 5970 var root = dataset.getRoot(); 5971 if (root && root.parent().length === 0) { 5972 that.$menu.append(root); 5973 } 5974 dataset.onSync('rendered', that._onRendered, that); 5975 }); 5976 5977 if (o.templates && o.templates.footer) { 5978 this.templates.footer = _.templatify(o.templates.footer); 5979 this.$menu.append(this.templates.footer()); 5980 } 5981 5982 var self = this; 5983 DOM.element(window).resize(function() { 5984 self._redraw(); 5985 }); 5986 } 5987 5988 // instance methods 5989 // ---------------- 5990 5991 _.mixin(Dropdown.prototype, EventEmitter, { 5992 5993 // ### private 5994 5995 _onSuggestionClick: function onSuggestionClick($e) { 5996 this.trigger('suggestionClicked', DOM.element($e.currentTarget)); 5997 }, 5998 5999 _onSuggestionMouseEnter: function onSuggestionMouseEnter($e) { 6000 var elt = DOM.element($e.currentTarget); 6001 if (elt.hasClass(_.className(this.cssClasses.prefix, this.cssClasses.cursor, true))) { 6002 // we're already on the cursor 6003 // => we're probably entering it again after leaving it for a nested div 6004 return; 6005 } 6006 this._removeCursor(); 6007 this._setCursor(elt, false); 6008 }, 6009 6010 _onSuggestionMouseLeave: function onSuggestionMouseLeave($e) { 6011 // $e.relatedTarget is the `EventTarget` the pointing device entered to 6012 if ($e.relatedTarget) { 6013 var elt = DOM.element($e.relatedTarget); 6014 if (elt.closest('.' + _.className(this.cssClasses.prefix, this.cssClasses.cursor, true)).length > 0) { 6015 // our father is a cursor 6016 // => it means we're just leaving the suggestion for a nested div 6017 return; 6018 } 6019 } 6020 this._removeCursor(); 6021 this.trigger('cursorRemoved'); 6022 }, 6023 6024 _onRendered: function onRendered(e, query) { 6025 this.isEmpty = _.every(this.datasets, isDatasetEmpty); 6026 6027 if (this.isEmpty) { 6028 if (query.length >= this.minLength) { 6029 this.trigger('empty'); 6030 } 6031 6032 if (this.$empty) { 6033 if (query.length < this.minLength) { 6034 this._hide(); 6035 } else { 6036 var html = this.templates.empty({ 6037 query: this.datasets[0] && this.datasets[0].query 6038 }); 6039 this.$empty.html(html); 6040 this._show(); 6041 } 6042 } else if (_.any(this.datasets, hasEmptyTemplate)) { 6043 if (query.length < this.minLength) { 6044 this._hide(); 6045 } else { 6046 this._show(); 6047 } 6048 } else { 6049 this._hide(); 6050 } 6051 } else if (this.isOpen) { 6052 if (this.$empty) { 6053 this.$empty.empty(); 6054 } 6055 6056 if (query.length >= this.minLength) { 6057 this._show(); 6058 } else { 6059 this._hide(); 6060 } 6061 } 6062 6063 this.trigger('datasetRendered'); 6064 6065 function isDatasetEmpty(dataset) { 6066 return dataset.isEmpty(); 6067 } 6068 6069 function hasEmptyTemplate(dataset) { 6070 return dataset.templates && dataset.templates.empty; 6071 } 6072 }, 6073 6074 _hide: function() { 6075 this.$container.hide(); 6076 }, 6077 6078 _show: function() { 6079 // can't use jQuery#show because $menu is a span element we want 6080 // display: block; not dislay: inline; 6081 this.$container.css('display', 'block'); 6082 6083 this._redraw(); 6084 6085 this.trigger('shown'); 6086 }, 6087 6088 _redraw: function redraw() { 6089 if (!this.isOpen || !this.appendTo) return; 6090 6091 this.trigger('redrawn'); 6092 }, 6093 6094 _getSuggestions: function getSuggestions() { 6095 return this.$menu.find(_.className(this.cssClasses.prefix, this.cssClasses.suggestion)); 6096 }, 6097 6098 _getCursor: function getCursor() { 6099 return this.$menu.find(_.className(this.cssClasses.prefix, this.cssClasses.cursor)).first(); 6100 }, 6101 6102 _setCursor: function setCursor($el, updateInput) { 6103 $el.first() 6104 .addClass(_.className(this.cssClasses.prefix, this.cssClasses.cursor, true)) 6105 .attr('aria-selected', 'true'); 6106 this.trigger('cursorMoved', updateInput); 6107 }, 6108 6109 _removeCursor: function removeCursor() { 6110 this._getCursor() 6111 .removeClass(_.className(this.cssClasses.prefix, this.cssClasses.cursor, true)) 6112 .removeAttr('aria-selected'); 6113 }, 6114 6115 _moveCursor: function moveCursor(increment) { 6116 var $suggestions; 6117 var $oldCursor; 6118 var newCursorIndex; 6119 var $newCursor; 6120 6121 if (!this.isOpen) { 6122 return; 6123 } 6124 6125 $oldCursor = this._getCursor(); 6126 $suggestions = this._getSuggestions(); 6127 6128 this._removeCursor(); 6129 6130 // shifting before and after modulo to deal with -1 index 6131 newCursorIndex = $suggestions.index($oldCursor) + increment; 6132 newCursorIndex = (newCursorIndex + 1) % ($suggestions.length + 1) - 1; 6133 6134 if (newCursorIndex === -1) { 6135 this.trigger('cursorRemoved'); 6136 6137 return; 6138 } else if (newCursorIndex < -1) { 6139 newCursorIndex = $suggestions.length - 1; 6140 } 6141 6142 this._setCursor($newCursor = $suggestions.eq(newCursorIndex), true); 6143 6144 // in the case of scrollable overflow 6145 // make sure the cursor is visible in the menu 6146 this._ensureVisible($newCursor); 6147 }, 6148 6149 _ensureVisible: function ensureVisible($el) { 6150 var elTop; 6151 var elBottom; 6152 var menuScrollTop; 6153 var menuHeight; 6154 6155 elTop = $el.position().top; 6156 elBottom = elTop + $el.height() + 6157 parseInt($el.css('margin-top'), 10) + 6158 parseInt($el.css('margin-bottom'), 10); 6159 menuScrollTop = this.$menu.scrollTop(); 6160 menuHeight = this.$menu.height() + 6161 parseInt(this.$menu.css('paddingTop'), 10) + 6162 parseInt(this.$menu.css('paddingBottom'), 10); 6163 6164 if (elTop < 0) { 6165 this.$menu.scrollTop(menuScrollTop + elTop); 6166 } else if (menuHeight < elBottom) { 6167 this.$menu.scrollTop(menuScrollTop + (elBottom - menuHeight)); 6168 } 6169 }, 6170 6171 // ### public 6172 6173 close: function close() { 6174 if (this.isOpen) { 6175 this.isOpen = false; 6176 6177 this._removeCursor(); 6178 this._hide(); 6179 6180 this.trigger('closed'); 6181 } 6182 }, 6183 6184 open: function open() { 6185 if (!this.isOpen) { 6186 this.isOpen = true; 6187 6188 if (!this.isEmpty) { 6189 this._show(); 6190 } 6191 6192 this.trigger('opened'); 6193 } 6194 }, 6195 6196 setLanguageDirection: function setLanguageDirection(dir) { 6197 this.$menu.css(dir === 'ltr' ? this.css.ltr : this.css.rtl); 6198 }, 6199 6200 moveCursorUp: function moveCursorUp() { 6201 this._moveCursor(-1); 6202 }, 6203 6204 moveCursorDown: function moveCursorDown() { 6205 this._moveCursor(+1); 6206 }, 6207 6208 getDatumForSuggestion: function getDatumForSuggestion($el) { 6209 var datum = null; 6210 6211 if ($el.length) { 6212 datum = { 6213 raw: Dataset.extractDatum($el), 6214 value: Dataset.extractValue($el), 6215 datasetName: Dataset.extractDatasetName($el) 6216 }; 6217 } 6218 6219 return datum; 6220 }, 6221 6222 getCurrentCursor: function getCurrentCursor() { 6223 return this._getCursor().first(); 6224 }, 6225 6226 getDatumForCursor: function getDatumForCursor() { 6227 return this.getDatumForSuggestion(this._getCursor().first()); 6228 }, 6229 6230 getDatumForTopSuggestion: function getDatumForTopSuggestion() { 6231 return this.getDatumForSuggestion(this._getSuggestions().first()); 6232 }, 6233 6234 cursorTopSuggestion: function cursorTopSuggestion() { 6235 this._setCursor(this._getSuggestions().first(), false); 6236 }, 6237 6238 update: function update(query) { 6239 _.each(this.datasets, updateDataset); 6240 6241 function updateDataset(dataset) { 6242 dataset.update(query); 6243 } 6244 }, 6245 6246 empty: function empty() { 6247 _.each(this.datasets, clearDataset); 6248 this.isEmpty = true; 6249 6250 function clearDataset(dataset) { 6251 dataset.clear(); 6252 } 6253 }, 6254 6255 isVisible: function isVisible() { 6256 return this.isOpen && !this.isEmpty; 6257 }, 6258 6259 destroy: function destroy() { 6260 this.$menu.off('.aa'); 6261 6262 this.$menu = null; 6263 6264 _.each(this.datasets, destroyDataset); 6265 6266 function destroyDataset(dataset) { 6267 dataset.destroy(); 6268 } 6269 } 6270 }); 6271 6272 // helper functions 6273 // ---------------- 6274 Dropdown.Dataset = Dataset; 6275 6276 function initializeDataset($menu, oDataset, cssClasses) { 6277 return new Dropdown.Dataset(_.mixin({$menu: $menu, cssClasses: cssClasses}, oDataset)); 6278 } 6279 6280 module.exports = Dropdown; 6281 6282 6283 /***/ }), 6284 /* 40 */ 6285 /***/ (function(module, exports, __webpack_require__) { 6286 6287 "use strict"; 6288 6289 6290 var specialKeyCodeMap; 6291 6292 specialKeyCodeMap = { 6293 9: 'tab', 6294 27: 'esc', 6295 37: 'left', 6296 39: 'right', 6297 13: 'enter', 6298 38: 'up', 6299 40: 'down' 6300 }; 6301 6302 var _ = __webpack_require__(0); 6303 var DOM = __webpack_require__(1); 6304 var EventEmitter = __webpack_require__(10); 6305 6306 // constructor 6307 // ----------- 6308 6309 function Input(o) { 6310 var that = this; 6311 var onBlur; 6312 var onFocus; 6313 var onKeydown; 6314 var onInput; 6315 6316 o = o || {}; 6317 6318 if (!o.input) { 6319 _.error('input is missing'); 6320 } 6321 6322 // bound functions 6323 onBlur = _.bind(this._onBlur, this); 6324 onFocus = _.bind(this._onFocus, this); 6325 onKeydown = _.bind(this._onKeydown, this); 6326 onInput = _.bind(this._onInput, this); 6327 6328 this.$hint = DOM.element(o.hint); 6329 this.$input = DOM.element(o.input) 6330 .on('blur.aa', onBlur) 6331 .on('focus.aa', onFocus) 6332 .on('keydown.aa', onKeydown); 6333 6334 // if no hint, noop all the hint related functions 6335 if (this.$hint.length === 0) { 6336 this.setHint = this.getHint = this.clearHint = this.clearHintIfInvalid = _.noop; 6337 } 6338 6339 // ie7 and ie8 don't support the input event 6340 // ie9 doesn't fire the input event when characters are removed 6341 // not sure if ie10 is compatible 6342 if (!_.isMsie()) { 6343 this.$input.on('input.aa', onInput); 6344 } else { 6345 this.$input.on('keydown.aa keypress.aa cut.aa paste.aa', function($e) { 6346 // if a special key triggered this, ignore it 6347 if (specialKeyCodeMap[$e.which || $e.keyCode]) { 6348 return; 6349 } 6350 6351 // give the browser a chance to update the value of the input 6352 // before checking to see if the query changed 6353 _.defer(_.bind(that._onInput, that, $e)); 6354 }); 6355 } 6356 6357 // the query defaults to whatever the value of the input is 6358 // on initialization, it'll most likely be an empty string 6359 this.query = this.$input.val(); 6360 6361 // helps with calculating the width of the input's value 6362 this.$overflowHelper = buildOverflowHelper(this.$input); 6363 } 6364 6365 // static methods 6366 // -------------- 6367 6368 Input.normalizeQuery = function(str) { 6369 // strips leading whitespace and condenses all whitespace 6370 return (str || '').replace(/^\s*/g, '').replace(/\s{2,}/g, ' '); 6371 }; 6372 6373 // instance methods 6374 // ---------------- 6375 6376 _.mixin(Input.prototype, EventEmitter, { 6377 6378 // ### private 6379 6380 _onBlur: function onBlur() { 6381 this.resetInputValue(); 6382 this.$input.removeAttr('aria-activedescendant'); 6383 this.trigger('blurred'); 6384 }, 6385 6386 _onFocus: function onFocus() { 6387 this.trigger('focused'); 6388 }, 6389 6390 _onKeydown: function onKeydown($e) { 6391 // which is normalized and consistent (but not for ie) 6392 var keyName = specialKeyCodeMap[$e.which || $e.keyCode]; 6393 6394 this._managePreventDefault(keyName, $e); 6395 if (keyName && this._shouldTrigger(keyName, $e)) { 6396 this.trigger(keyName + 'Keyed', $e); 6397 } 6398 }, 6399 6400 _onInput: function onInput() { 6401 this._checkInputValue(); 6402 }, 6403 6404 _managePreventDefault: function managePreventDefault(keyName, $e) { 6405 var preventDefault; 6406 var hintValue; 6407 var inputValue; 6408 6409 switch (keyName) { 6410 case 'tab': 6411 hintValue = this.getHint(); 6412 inputValue = this.getInputValue(); 6413 6414 preventDefault = hintValue && 6415 hintValue !== inputValue && 6416 !withModifier($e); 6417 break; 6418 6419 case 'up': 6420 case 'down': 6421 preventDefault = !withModifier($e); 6422 break; 6423 6424 default: 6425 preventDefault = false; 6426 } 6427 6428 if (preventDefault) { 6429 $e.preventDefault(); 6430 } 6431 }, 6432 6433 _shouldTrigger: function shouldTrigger(keyName, $e) { 6434 var trigger; 6435 6436 switch (keyName) { 6437 case 'tab': 6438 trigger = !withModifier($e); 6439 break; 6440 6441 default: 6442 trigger = true; 6443 } 6444 6445 return trigger; 6446 }, 6447 6448 _checkInputValue: function checkInputValue() { 6449 var inputValue; 6450 var areEquivalent; 6451 var hasDifferentWhitespace; 6452 6453 inputValue = this.getInputValue(); 6454 areEquivalent = areQueriesEquivalent(inputValue, this.query); 6455 hasDifferentWhitespace = areEquivalent && this.query ? 6456 this.query.length !== inputValue.length : false; 6457 6458 this.query = inputValue; 6459 6460 if (!areEquivalent) { 6461 this.trigger('queryChanged', this.query); 6462 } else if (hasDifferentWhitespace) { 6463 this.trigger('whitespaceChanged', this.query); 6464 } 6465 }, 6466 6467 // ### public 6468 6469 focus: function focus() { 6470 this.$input.focus(); 6471 }, 6472 6473 blur: function blur() { 6474 this.$input.blur(); 6475 }, 6476 6477 getQuery: function getQuery() { 6478 return this.query; 6479 }, 6480 6481 setQuery: function setQuery(query) { 6482 this.query = query; 6483 }, 6484 6485 getInputValue: function getInputValue() { 6486 return this.$input.val(); 6487 }, 6488 6489 setInputValue: function setInputValue(value, silent) { 6490 if (typeof value === 'undefined') { 6491 value = this.query; 6492 } 6493 this.$input.val(value); 6494 6495 // silent prevents any additional events from being triggered 6496 if (silent) { 6497 this.clearHint(); 6498 } else { 6499 this._checkInputValue(); 6500 } 6501 }, 6502 6503 expand: function expand() { 6504 this.$input.attr('aria-expanded', 'true'); 6505 }, 6506 6507 collapse: function collapse() { 6508 this.$input.attr('aria-expanded', 'false'); 6509 }, 6510 6511 setActiveDescendant: function setActiveDescendant(activedescendantId) { 6512 this.$input.attr('aria-activedescendant', activedescendantId); 6513 }, 6514 6515 removeActiveDescendant: function removeActiveDescendant() { 6516 this.$input.removeAttr('aria-activedescendant'); 6517 }, 6518 6519 resetInputValue: function resetInputValue() { 6520 this.setInputValue(this.query, true); 6521 }, 6522 6523 getHint: function getHint() { 6524 return this.$hint.val(); 6525 }, 6526 6527 setHint: function setHint(value) { 6528 this.$hint.val(value); 6529 }, 6530 6531 clearHint: function clearHint() { 6532 this.setHint(''); 6533 }, 6534 6535 clearHintIfInvalid: function clearHintIfInvalid() { 6536 var val; 6537 var hint; 6538 var valIsPrefixOfHint; 6539 var isValid; 6540 6541 val = this.getInputValue(); 6542 hint = this.getHint(); 6543 valIsPrefixOfHint = val !== hint && hint.indexOf(val) === 0; 6544 isValid = val !== '' && valIsPrefixOfHint && !this.hasOverflow(); 6545 6546 if (!isValid) { 6547 this.clearHint(); 6548 } 6549 }, 6550 6551 getLanguageDirection: function getLanguageDirection() { 6552 return (this.$input.css('direction') || 'ltr').toLowerCase(); 6553 }, 6554 6555 hasOverflow: function hasOverflow() { 6556 // 2 is arbitrary, just picking a small number to handle edge cases 6557 var constraint = this.$input.width() - 2; 6558 6559 this.$overflowHelper.text(this.getInputValue()); 6560 6561 return this.$overflowHelper.width() >= constraint; 6562 }, 6563 6564 isCursorAtEnd: function() { 6565 var valueLength; 6566 var selectionStart; 6567 var range; 6568 6569 valueLength = this.$input.val().length; 6570 selectionStart = this.$input[0].selectionStart; 6571 6572 if (_.isNumber(selectionStart)) { 6573 return selectionStart === valueLength; 6574 } else if (document.selection) { 6575 // NOTE: this won't work unless the input has focus, the good news 6576 // is this code should only get called when the input has focus 6577 range = document.selection.createRange(); 6578 range.moveStart('character', -valueLength); 6579 6580 return valueLength === range.text.length; 6581 } 6582 6583 return true; 6584 }, 6585 6586 destroy: function destroy() { 6587 this.$hint.off('.aa'); 6588 this.$input.off('.aa'); 6589 6590 this.$hint = this.$input = this.$overflowHelper = null; 6591 } 6592 }); 6593 6594 // helper functions 6595 // ---------------- 6596 6597 function buildOverflowHelper($input) { 6598 return DOM.element('<pre aria-hidden="true"></pre>') 6599 .css({ 6600 // position helper off-screen 6601 position: 'absolute', 6602 visibility: 'hidden', 6603 // avoid line breaks and whitespace collapsing 6604 whiteSpace: 'pre', 6605 // use same font css as input to calculate accurate width 6606 fontFamily: $input.css('font-family'), 6607 fontSize: $input.css('font-size'), 6608 fontStyle: $input.css('font-style'), 6609 fontVariant: $input.css('font-variant'), 6610 fontWeight: $input.css('font-weight'), 6611 wordSpacing: $input.css('word-spacing'), 6612 letterSpacing: $input.css('letter-spacing'), 6613 textIndent: $input.css('text-indent'), 6614 textRendering: $input.css('text-rendering'), 6615 textTransform: $input.css('text-transform') 6616 }) 6617 .insertAfter($input); 6618 } 6619 6620 function areQueriesEquivalent(a, b) { 6621 return Input.normalizeQuery(a) === Input.normalizeQuery(b); 6622 } 6623 6624 function withModifier($e) { 6625 return $e.altKey || $e.ctrlKey || $e.metaKey || $e.shiftKey; 6626 } 6627 6628 module.exports = Input; 6629 6630 6631 /***/ }), 6632 /* 41 */ 6633 /***/ (function(module, exports, __webpack_require__) { 6634 6635 "use strict"; 6636 6637 6638 var attrsKey = 'aaAttrs'; 6639 6640 var _ = __webpack_require__(0); 6641 var DOM = __webpack_require__(1); 6642 var EventBus = __webpack_require__(13); 6643 var Input = __webpack_require__(40); 6644 var Dropdown = __webpack_require__(39); 6645 var html = __webpack_require__(14); 6646 var css = __webpack_require__(9); 6647 6648 // constructor 6649 // ----------- 6650 6651 // THOUGHT: what if datasets could dynamically be added/removed? 6652 function Typeahead(o) { 6653 var $menu; 6654 var $hint; 6655 6656 o = o || {}; 6657 6658 if (!o.input) { 6659 _.error('missing input'); 6660 } 6661 6662 this.isActivated = false; 6663 this.debug = !!o.debug; 6664 this.autoselect = !!o.autoselect; 6665 this.autoselectOnBlur = !!o.autoselectOnBlur; 6666 this.openOnFocus = !!o.openOnFocus; 6667 this.minLength = _.isNumber(o.minLength) ? o.minLength : 1; 6668 this.autoWidth = (o.autoWidth === undefined) ? true : !!o.autoWidth; 6669 6670 o.hint = !!o.hint; 6671 6672 if (o.hint && o.appendTo) { 6673 throw new Error('[autocomplete.js] hint and appendTo options can\'t be used at the same time'); 6674 } 6675 6676 this.css = o.css = _.mixin({}, css, o.appendTo ? css.appendTo : {}); 6677 this.cssClasses = o.cssClasses = _.mixin({}, css.defaultClasses, o.cssClasses || {}); 6678 this.cssClasses.prefix = 6679 o.cssClasses.formattedPrefix = _.formatPrefix(this.cssClasses.prefix, this.cssClasses.noPrefix); 6680 this.listboxId = o.listboxId = [this.cssClasses.root, 'listbox', _.getUniqueId()].join('-'); 6681 6682 var domElts = buildDom(o); 6683 6684 this.$node = domElts.wrapper; 6685 var $input = this.$input = domElts.input; 6686 $menu = domElts.menu; 6687 $hint = domElts.hint; 6688 6689 if (o.dropdownMenuContainer) { 6690 DOM.element(o.dropdownMenuContainer) 6691 .css('position', 'relative') // ensure the container has a relative position 6692 .append($menu.css('top', '0')); // override the top: 100% 6693 } 6694 6695 // #705: if there's scrollable overflow, ie doesn't support 6696 // blur cancellations when the scrollbar is clicked 6697 // 6698 // #351: preventDefault won't cancel blurs in ie <= 8 6699 $input.on('blur.aa', function($e) { 6700 var active = document.activeElement; 6701 if (_.isMsie() && ($menu[0] === active || $menu[0].contains(active))) { 6702 $e.preventDefault(); 6703 // stop immediate in order to prevent Input#_onBlur from 6704 // getting executed 6705 $e.stopImmediatePropagation(); 6706 _.defer(function() { $input.focus(); }); 6707 } 6708 }); 6709 6710 // #351: prevents input blur due to clicks within dropdown menu 6711 $menu.on('mousedown.aa', function($e) { $e.preventDefault(); }); 6712 6713 this.eventBus = o.eventBus || new EventBus({el: $input}); 6714 6715 this.dropdown = new Typeahead.Dropdown({ 6716 appendTo: o.appendTo, 6717 wrapper: this.$node, 6718 menu: $menu, 6719 datasets: o.datasets, 6720 templates: o.templates, 6721 cssClasses: o.cssClasses, 6722 minLength: this.minLength 6723 }) 6724 .onSync('suggestionClicked', this._onSuggestionClicked, this) 6725 .onSync('cursorMoved', this._onCursorMoved, this) 6726 .onSync('cursorRemoved', this._onCursorRemoved, this) 6727 .onSync('opened', this._onOpened, this) 6728 .onSync('closed', this._onClosed, this) 6729 .onSync('shown', this._onShown, this) 6730 .onSync('empty', this._onEmpty, this) 6731 .onSync('redrawn', this._onRedrawn, this) 6732 .onAsync('datasetRendered', this._onDatasetRendered, this); 6733 6734 this.input = new Typeahead.Input({input: $input, hint: $hint}) 6735 .onSync('focused', this._onFocused, this) 6736 .onSync('blurred', this._onBlurred, this) 6737 .onSync('enterKeyed', this._onEnterKeyed, this) 6738 .onSync('tabKeyed', this._onTabKeyed, this) 6739 .onSync('escKeyed', this._onEscKeyed, this) 6740 .onSync('upKeyed', this._onUpKeyed, this) 6741 .onSync('downKeyed', this._onDownKeyed, this) 6742 .onSync('leftKeyed', this._onLeftKeyed, this) 6743 .onSync('rightKeyed', this._onRightKeyed, this) 6744 .onSync('queryChanged', this._onQueryChanged, this) 6745 .onSync('whitespaceChanged', this._onWhitespaceChanged, this); 6746 6747 this._bindKeyboardShortcuts(o); 6748 6749 this._setLanguageDirection(); 6750 } 6751 6752 // instance methods 6753 // ---------------- 6754 6755 _.mixin(Typeahead.prototype, { 6756 // ### private 6757 6758 _bindKeyboardShortcuts: function(options) { 6759 if (!options.keyboardShortcuts) { 6760 return; 6761 } 6762 var $input = this.$input; 6763 var keyboardShortcuts = []; 6764 _.each(options.keyboardShortcuts, function(key) { 6765 if (typeof key === 'string') { 6766 key = key.toUpperCase().charCodeAt(0); 6767 } 6768 keyboardShortcuts.push(key); 6769 }); 6770 DOM.element(document).keydown(function(event) { 6771 var elt = (event.target || event.srcElement); 6772 var tagName = elt.tagName; 6773 if (elt.isContentEditable || tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA') { 6774 // already in an input 6775 return; 6776 } 6777 6778 var which = event.which || event.keyCode; 6779 if (keyboardShortcuts.indexOf(which) === -1) { 6780 // not the right shortcut 6781 return; 6782 } 6783 6784 $input.focus(); 6785 event.stopPropagation(); 6786 event.preventDefault(); 6787 }); 6788 }, 6789 6790 _onSuggestionClicked: function onSuggestionClicked(type, $el) { 6791 var datum; 6792 6793 if (datum = this.dropdown.getDatumForSuggestion($el)) { 6794 this._select(datum); 6795 } 6796 }, 6797 6798 _onCursorMoved: function onCursorMoved(event, updateInput) { 6799 var datum = this.dropdown.getDatumForCursor(); 6800 var currentCursorId = this.dropdown.getCurrentCursor().attr('id'); 6801 this.input.setActiveDescendant(currentCursorId); 6802 6803 if (datum) { 6804 if (updateInput) { 6805 this.input.setInputValue(datum.value, true); 6806 } 6807 6808 this.eventBus.trigger('cursorchanged', datum.raw, datum.datasetName); 6809 } 6810 }, 6811 6812 _onCursorRemoved: function onCursorRemoved() { 6813 this.input.resetInputValue(); 6814 this._updateHint(); 6815 this.eventBus.trigger('cursorremoved'); 6816 }, 6817 6818 _onDatasetRendered: function onDatasetRendered() { 6819 this._updateHint(); 6820 6821 this.eventBus.trigger('updated'); 6822 }, 6823 6824 _onOpened: function onOpened() { 6825 this._updateHint(); 6826 this.input.expand(); 6827 6828 this.eventBus.trigger('opened'); 6829 }, 6830 6831 _onEmpty: function onEmpty() { 6832 this.eventBus.trigger('empty'); 6833 }, 6834 6835 _onRedrawn: function onRedrawn() { 6836 this.$node.css('top', 0 + 'px'); 6837 this.$node.css('left', 0 + 'px'); 6838 6839 var inputRect = this.$input[0].getBoundingClientRect(); 6840 6841 if (this.autoWidth) { 6842 this.$node.css('width', inputRect.width + 'px'); 6843 } 6844 6845 var wrapperRect = this.$node[0].getBoundingClientRect(); 6846 6847 var top = inputRect.bottom - wrapperRect.top; 6848 this.$node.css('top', top + 'px'); 6849 var left = inputRect.left - wrapperRect.left; 6850 this.$node.css('left', left + 'px'); 6851 6852 this.eventBus.trigger('redrawn'); 6853 }, 6854 6855 _onShown: function onShown() { 6856 this.eventBus.trigger('shown'); 6857 if (this.autoselect) { 6858 this.dropdown.cursorTopSuggestion(); 6859 } 6860 }, 6861 6862 _onClosed: function onClosed() { 6863 this.input.clearHint(); 6864 this.input.removeActiveDescendant(); 6865 this.input.collapse(); 6866 6867 this.eventBus.trigger('closed'); 6868 }, 6869 6870 _onFocused: function onFocused() { 6871 this.isActivated = true; 6872 6873 if (this.openOnFocus) { 6874 var query = this.input.getQuery(); 6875 if (query.length >= this.minLength) { 6876 this.dropdown.update(query); 6877 } else { 6878 this.dropdown.empty(); 6879 } 6880 6881 this.dropdown.open(); 6882 } 6883 }, 6884 6885 _onBlurred: function onBlurred() { 6886 var cursorDatum; 6887 var topSuggestionDatum; 6888 6889 cursorDatum = this.dropdown.getDatumForCursor(); 6890 topSuggestionDatum = this.dropdown.getDatumForTopSuggestion(); 6891 6892 if (!this.debug) { 6893 if (this.autoselectOnBlur && cursorDatum) { 6894 this._select(cursorDatum); 6895 } else if (this.autoselectOnBlur && topSuggestionDatum) { 6896 this._select(topSuggestionDatum); 6897 } else { 6898 this.isActivated = false; 6899 this.dropdown.empty(); 6900 this.dropdown.close(); 6901 } 6902 } 6903 }, 6904 6905 _onEnterKeyed: function onEnterKeyed(type, $e) { 6906 var cursorDatum; 6907 var topSuggestionDatum; 6908 6909 cursorDatum = this.dropdown.getDatumForCursor(); 6910 topSuggestionDatum = this.dropdown.getDatumForTopSuggestion(); 6911 6912 if (cursorDatum) { 6913 this._select(cursorDatum); 6914 $e.preventDefault(); 6915 } else if (this.autoselect && topSuggestionDatum) { 6916 this._select(topSuggestionDatum); 6917 $e.preventDefault(); 6918 } 6919 }, 6920 6921 _onTabKeyed: function onTabKeyed(type, $e) { 6922 var datum; 6923 6924 if (datum = this.dropdown.getDatumForCursor()) { 6925 this._select(datum); 6926 $e.preventDefault(); 6927 } else { 6928 this._autocomplete(true); 6929 } 6930 }, 6931 6932 _onEscKeyed: function onEscKeyed() { 6933 this.dropdown.close(); 6934 this.input.resetInputValue(); 6935 }, 6936 6937 _onUpKeyed: function onUpKeyed() { 6938 var query = this.input.getQuery(); 6939 6940 if (this.dropdown.isEmpty && query.length >= this.minLength) { 6941 this.dropdown.update(query); 6942 } else { 6943 this.dropdown.moveCursorUp(); 6944 } 6945 6946 this.dropdown.open(); 6947 }, 6948 6949 _onDownKeyed: function onDownKeyed() { 6950 var query = this.input.getQuery(); 6951 6952 if (this.dropdown.isEmpty && query.length >= this.minLength) { 6953 this.dropdown.update(query); 6954 } else { 6955 this.dropdown.moveCursorDown(); 6956 } 6957 6958 this.dropdown.open(); 6959 }, 6960 6961 _onLeftKeyed: function onLeftKeyed() { 6962 if (this.dir === 'rtl') { 6963 this._autocomplete(); 6964 } 6965 }, 6966 6967 _onRightKeyed: function onRightKeyed() { 6968 if (this.dir === 'ltr') { 6969 this._autocomplete(); 6970 } 6971 }, 6972 6973 _onQueryChanged: function onQueryChanged(e, query) { 6974 this.input.clearHintIfInvalid(); 6975 6976 if (query.length >= this.minLength) { 6977 this.dropdown.update(query); 6978 } else { 6979 this.dropdown.empty(); 6980 } 6981 6982 this.dropdown.open(); 6983 this._setLanguageDirection(); 6984 }, 6985 6986 _onWhitespaceChanged: function onWhitespaceChanged() { 6987 this._updateHint(); 6988 this.dropdown.open(); 6989 }, 6990 6991 _setLanguageDirection: function setLanguageDirection() { 6992 var dir = this.input.getLanguageDirection(); 6993 6994 if (this.dir !== dir) { 6995 this.dir = dir; 6996 this.$node.css('direction', dir); 6997 this.dropdown.setLanguageDirection(dir); 6998 } 6999 }, 7000 7001 _updateHint: function updateHint() { 7002 var datum; 7003 var val; 7004 var query; 7005 var escapedQuery; 7006 var frontMatchRegEx; 7007 var match; 7008 7009 datum = this.dropdown.getDatumForTopSuggestion(); 7010 7011 if (datum && this.dropdown.isVisible() && !this.input.hasOverflow()) { 7012 val = this.input.getInputValue(); 7013 query = Input.normalizeQuery(val); 7014 escapedQuery = _.escapeRegExChars(query); 7015 7016 // match input value, then capture trailing text 7017 frontMatchRegEx = new RegExp('^(?:' + escapedQuery + ')(.+$)', 'i'); 7018 match = frontMatchRegEx.exec(datum.value); 7019 7020 // clear hint if there's no trailing text 7021 if (match) { 7022 this.input.setHint(val + match[1]); 7023 } else { 7024 this.input.clearHint(); 7025 } 7026 } else { 7027 this.input.clearHint(); 7028 } 7029 }, 7030 7031 _autocomplete: function autocomplete(laxCursor) { 7032 var hint; 7033 var query; 7034 var isCursorAtEnd; 7035 var datum; 7036 7037 hint = this.input.getHint(); 7038 query = this.input.getQuery(); 7039 isCursorAtEnd = laxCursor || this.input.isCursorAtEnd(); 7040 7041 if (hint && query !== hint && isCursorAtEnd) { 7042 datum = this.dropdown.getDatumForTopSuggestion(); 7043 if (datum) { 7044 this.input.setInputValue(datum.value); 7045 } 7046 7047 this.eventBus.trigger('autocompleted', datum.raw, datum.datasetName); 7048 } 7049 }, 7050 7051 _select: function select(datum) { 7052 if (typeof datum.value !== 'undefined') { 7053 this.input.setQuery(datum.value); 7054 } 7055 this.input.setInputValue(datum.value, true); 7056 7057 this._setLanguageDirection(); 7058 7059 var event = this.eventBus.trigger('selected', datum.raw, datum.datasetName); 7060 if (event.isDefaultPrevented() === false) { 7061 this.dropdown.close(); 7062 7063 // #118: allow click event to bubble up to the body before removing 7064 // the suggestions otherwise we break event delegation 7065 _.defer(_.bind(this.dropdown.empty, this.dropdown)); 7066 } 7067 }, 7068 7069 // ### public 7070 7071 open: function open() { 7072 // if the menu is not activated yet, we need to update 7073 // the underlying dropdown menu to trigger the search 7074 // otherwise we're not gonna see anything 7075 if (!this.isActivated) { 7076 var query = this.input.getInputValue(); 7077 if (query.length >= this.minLength) { 7078 this.dropdown.update(query); 7079 } else { 7080 this.dropdown.empty(); 7081 } 7082 } 7083 this.dropdown.open(); 7084 }, 7085 7086 close: function close() { 7087 this.dropdown.close(); 7088 }, 7089 7090 setVal: function setVal(val) { 7091 // expect val to be a string, so be safe, and coerce 7092 val = _.toStr(val); 7093 7094 if (this.isActivated) { 7095 this.input.setInputValue(val); 7096 } else { 7097 this.input.setQuery(val); 7098 this.input.setInputValue(val, true); 7099 } 7100 7101 this._setLanguageDirection(); 7102 }, 7103 7104 getVal: function getVal() { 7105 return this.input.getQuery(); 7106 }, 7107 7108 destroy: function destroy() { 7109 this.input.destroy(); 7110 this.dropdown.destroy(); 7111 7112 destroyDomStructure(this.$node, this.cssClasses); 7113 7114 this.$node = null; 7115 }, 7116 7117 getWrapper: function getWrapper() { 7118 return this.dropdown.$container[0]; 7119 } 7120 }); 7121 7122 function buildDom(options) { 7123 var $input; 7124 var $wrapper; 7125 var $dropdown; 7126 var $hint; 7127 7128 $input = DOM.element(options.input); 7129 $wrapper = DOM 7130 .element(html.wrapper.replace('%ROOT%', options.cssClasses.root)) 7131 .css(options.css.wrapper); 7132 7133 // override the display property with the table-cell value 7134 // if the parent element is a table and the original input was a block 7135 // -> https://github.com/algolia/autocomplete.js/issues/16 7136 if (!options.appendTo && $input.css('display') === 'block' && $input.parent().css('display') === 'table') { 7137 $wrapper.css('display', 'table-cell'); 7138 } 7139 var dropdownHtml = html.dropdown. 7140 replace('%PREFIX%', options.cssClasses.prefix). 7141 replace('%DROPDOWN_MENU%', options.cssClasses.dropdownMenu); 7142 $dropdown = DOM.element(dropdownHtml) 7143 .css(options.css.dropdown) 7144 .attr({ 7145 role: 'listbox', 7146 id: options.listboxId 7147 }); 7148 if (options.templates && options.templates.dropdownMenu) { 7149 $dropdown.html(_.templatify(options.templates.dropdownMenu)()); 7150 } 7151 $hint = $input.clone().css(options.css.hint).css(getBackgroundStyles($input)); 7152 7153 $hint 7154 .val('') 7155 .addClass(_.className(options.cssClasses.prefix, options.cssClasses.hint, true)) 7156 .removeAttr('id name placeholder required') 7157 .prop('readonly', true) 7158 .attr({ 7159 'aria-hidden': 'true', 7160 autocomplete: 'off', 7161 spellcheck: 'false', 7162 tabindex: -1 7163 }); 7164 if ($hint.removeData) { 7165 $hint.removeData(); 7166 } 7167 7168 // store the original values of the attrs that get modified 7169 // so modifications can be reverted on destroy 7170 $input.data(attrsKey, { 7171 'aria-autocomplete': $input.attr('aria-autocomplete'), 7172 'aria-expanded': $input.attr('aria-expanded'), 7173 'aria-owns': $input.attr('aria-owns'), 7174 autocomplete: $input.attr('autocomplete'), 7175 dir: $input.attr('dir'), 7176 role: $input.attr('role'), 7177 spellcheck: $input.attr('spellcheck'), 7178 style: $input.attr('style'), 7179 type: $input.attr('type') 7180 }); 7181 7182 $input 7183 .addClass(_.className(options.cssClasses.prefix, options.cssClasses.input, true)) 7184 .attr({ 7185 autocomplete: 'off', 7186 spellcheck: false, 7187 7188 // Accessibility features 7189 // Give the field a presentation of a "select". 7190 // Combobox is the combined presentation of a single line textfield 7191 // with a listbox popup. 7192 // https://www.w3.org/WAI/PF/aria/roles#combobox 7193 role: 'combobox', 7194 // Let the screen reader know the field has an autocomplete 7195 // feature to it. 7196 'aria-autocomplete': (options.datasets && options.datasets[0] && options.datasets[0].displayKey ? 'both' : 'list'), 7197 // Indicates whether the dropdown it controls is currently expanded or collapsed 7198 'aria-expanded': 'false', 7199 // If a placeholder is set, label this field with itself, which in this case, 7200 // is an explicit pointer to use the placeholder attribute value. 7201 'aria-labelledby': ($input.attr('placeholder') ? $input.attr('id') : null), 7202 // Explicitly point to the listbox, 7203 // which is a list of suggestions (aka options) 7204 'aria-owns': options.listboxId 7205 }) 7206 .css(options.hint ? options.css.input : options.css.inputWithNoHint); 7207 7208 // ie7 does not like it when dir is set to auto 7209 try { 7210 if (!$input.attr('dir')) { 7211 $input.attr('dir', 'auto'); 7212 } 7213 } catch (e) { 7214 // ignore 7215 } 7216 7217 $wrapper = options.appendTo 7218 ? $wrapper.appendTo(DOM.element(options.appendTo).eq(0)).eq(0) 7219 : $input.wrap($wrapper).parent(); 7220 7221 $wrapper 7222 .prepend(options.hint ? $hint : null) 7223 .append($dropdown); 7224 7225 return { 7226 wrapper: $wrapper, 7227 input: $input, 7228 hint: $hint, 7229 menu: $dropdown 7230 }; 7231 } 7232 7233 function getBackgroundStyles($el) { 7234 return { 7235 backgroundAttachment: $el.css('background-attachment'), 7236 backgroundClip: $el.css('background-clip'), 7237 backgroundColor: $el.css('background-color'), 7238 backgroundImage: $el.css('background-image'), 7239 backgroundOrigin: $el.css('background-origin'), 7240 backgroundPosition: $el.css('background-position'), 7241 backgroundRepeat: $el.css('background-repeat'), 7242 backgroundSize: $el.css('background-size') 7243 }; 7244 } 7245 7246 function destroyDomStructure($node, cssClasses) { 7247 var $input = $node.find(_.className(cssClasses.prefix, cssClasses.input)); 7248 7249 // need to remove attrs that weren't previously defined and 7250 // revert attrs that originally had a value 7251 _.each($input.data(attrsKey), function(val, key) { 7252 if (val === undefined) { 7253 $input.removeAttr(key); 7254 } else { 7255 $input.attr(key, val); 7256 } 7257 }); 7258 7259 $input 7260 .detach() 7261 .removeClass(_.className(cssClasses.prefix, cssClasses.input, true)) 7262 .insertAfter($node); 7263 if ($input.removeData) { 7264 $input.removeData(attrsKey); 7265 } 7266 7267 $node.remove(); 7268 } 7269 7270 Typeahead.Dropdown = Dropdown; 7271 Typeahead.Input = Input; 7272 Typeahead.sources = __webpack_require__(43); 7273 7274 module.exports = Typeahead; 7275 7276 7277 /***/ }), 7278 /* 42 */ 7279 /***/ (function(module, exports, __webpack_require__) { 7280 7281 "use strict"; 7282 7283 7284 var _ = __webpack_require__(0); 7285 var version = __webpack_require__(16); 7286 var parseAlgoliaClientVersion = __webpack_require__(15); 7287 7288 module.exports = function search(index, params) { 7289 var algoliaVersion = parseAlgoliaClientVersion(index.as._ua); 7290 if (algoliaVersion && algoliaVersion[0] >= 3 && algoliaVersion[1] > 20) { 7291 params = params || {}; 7292 params.additionalUA = 'autocomplete.js ' + version; 7293 } 7294 return sourceFn; 7295 7296 function sourceFn(query, cb) { 7297 index.search(query, params, function(error, content) { 7298 if (error) { 7299 _.error(error.message); 7300 return; 7301 } 7302 cb(content.hits, content); 7303 }); 7304 } 7305 }; 7306 7307 7308 /***/ }), 7309 /* 43 */ 7310 /***/ (function(module, exports, __webpack_require__) { 7311 7312 "use strict"; 7313 7314 7315 module.exports = { 7316 hits: __webpack_require__(42), 7317 popularIn: __webpack_require__(44) 7318 }; 7319 7320 7321 /***/ }), 7322 /* 44 */ 7323 /***/ (function(module, exports, __webpack_require__) { 7324 7325 "use strict"; 7326 7327 7328 var _ = __webpack_require__(0); 7329 var version = __webpack_require__(16); 7330 var parseAlgoliaClientVersion = __webpack_require__(15); 7331 7332 module.exports = function popularIn(index, params, details, options) { 7333 var algoliaVersion = parseAlgoliaClientVersion(index.as._ua); 7334 if (algoliaVersion && algoliaVersion[0] >= 3 && algoliaVersion[1] > 20) { 7335 params = params || {}; 7336 params.additionalUA = 'autocomplete.js ' + version; 7337 } 7338 if (!details.source) { 7339 return _.error("Missing 'source' key"); 7340 } 7341 var source = _.isFunction(details.source) ? details.source : function(hit) { return hit[details.source]; }; 7342 7343 if (!details.index) { 7344 return _.error("Missing 'index' key"); 7345 } 7346 var detailsIndex = details.index; 7347 7348 options = options || {}; 7349 7350 return sourceFn; 7351 7352 function sourceFn(query, cb) { 7353 index.search(query, params, function(error, content) { 7354 if (error) { 7355 _.error(error.message); 7356 return; 7357 } 7358 7359 if (content.hits.length > 0) { 7360 var first = content.hits[0]; 7361 7362 var detailsParams = _.mixin({hitsPerPage: 0}, details); 7363 delete detailsParams.source; // not a query parameter 7364 delete detailsParams.index; // not a query parameter 7365 7366 var detailsAlgoliaVersion = parseAlgoliaClientVersion(detailsIndex.as._ua); 7367 if (detailsAlgoliaVersion && detailsAlgoliaVersion[0] >= 3 && detailsAlgoliaVersion[1] > 20) { 7368 params.additionalUA = 'autocomplete.js ' + version; 7369 } 7370 7371 detailsIndex.search(source(first), detailsParams, function(error2, content2) { 7372 if (error2) { 7373 _.error(error2.message); 7374 return; 7375 } 7376 7377 var suggestions = []; 7378 7379 // add the 'all department' entry before others 7380 if (options.includeAll) { 7381 var label = options.allTitle || 'All departments'; 7382 suggestions.push(_.mixin({ 7383 facet: {value: label, count: content2.nbHits} 7384 }, _.cloneDeep(first))); 7385 } 7386 7387 // enrich the first hit iterating over the facets 7388 _.each(content2.facets, function(values, facet) { 7389 _.each(values, function(count, value) { 7390 suggestions.push(_.mixin({ 7391 facet: {facet: facet, value: value, count: count} 7392 }, _.cloneDeep(first))); 7393 }); 7394 }); 7395 7396 // append all other hits 7397 for (var i = 1; i < content.hits.length; ++i) { 7398 suggestions.push(content.hits[i]); 7399 } 7400 7401 cb(suggestions, content); 7402 }); 7403 7404 return; 7405 } 7406 7407 cb([]); 7408 }); 7409 } 7410 }; 7411 7412 7413 /***/ }), 7414 /* 45 */ 7415 /***/ (function(module, exports, __webpack_require__) { 7416 7417 "use strict"; 7418 7419 7420 // this will inject Zepto in window, unfortunately no easy commonJS zepto build 7421 var zepto = __webpack_require__(17); 7422 7423 // setup DOM element 7424 var DOM = __webpack_require__(1); 7425 DOM.element = zepto; 7426 7427 // setup utils functions 7428 var _ = __webpack_require__(0); 7429 _.isArray = zepto.isArray; 7430 _.isFunction = zepto.isFunction; 7431 _.isObject = zepto.isPlainObject; 7432 _.bind = zepto.proxy; 7433 _.each = function(collection, cb) { 7434 // stupid argument order for jQuery.each 7435 zepto.each(collection, reverseArgs); 7436 function reverseArgs(index, value) { 7437 return cb(value, index); 7438 } 7439 }; 7440 _.map = zepto.map; 7441 _.mixin = zepto.extend; 7442 _.Event = zepto.Event; 7443 7444 var typeaheadKey = 'aaAutocomplete'; 7445 var Typeahead = __webpack_require__(41); 7446 var EventBus = __webpack_require__(13); 7447 7448 function autocomplete(selector, options, datasets, typeaheadObject) { 7449 datasets = _.isArray(datasets) ? datasets : [].slice.call(arguments, 2); 7450 7451 var inputs = zepto(selector).each(function(i, input) { 7452 var $input = zepto(input); 7453 var eventBus = new EventBus({el: $input}); 7454 var typeahead = typeaheadObject || new Typeahead({ 7455 input: $input, 7456 eventBus: eventBus, 7457 dropdownMenuContainer: options.dropdownMenuContainer, 7458 hint: options.hint === undefined ? true : !!options.hint, 7459 minLength: options.minLength, 7460 autoselect: options.autoselect, 7461 autoselectOnBlur: options.autoselectOnBlur, 7462 openOnFocus: options.openOnFocus, 7463 templates: options.templates, 7464 debug: options.debug, 7465 cssClasses: options.cssClasses, 7466 datasets: datasets, 7467 keyboardShortcuts: options.keyboardShortcuts, 7468 appendTo: options.appendTo, 7469 autoWidth: options.autoWidth 7470 }); 7471 $input.data(typeaheadKey, typeahead); 7472 }); 7473 7474 // expose all methods in the `autocomplete` attribute 7475 inputs.autocomplete = {}; 7476 _.each(['open', 'close', 'getVal', 'setVal', 'destroy', 'getWrapper'], function(method) { 7477 inputs.autocomplete[method] = function() { 7478 var methodArguments = arguments; 7479 var result; 7480 inputs.each(function(j, input) { 7481 var typeahead = zepto(input).data(typeaheadKey); 7482 result = typeahead[method].apply(typeahead, methodArguments); 7483 }); 7484 return result; 7485 }; 7486 }); 7487 7488 return inputs; 7489 } 7490 7491 autocomplete.sources = Typeahead.sources; 7492 autocomplete.escapeHighlightedString = _.escapeHighlightedString; 7493 7494 var wasAutocompleteSet = 'autocomplete' in window; 7495 var oldAutocomplete = window.autocomplete; 7496 autocomplete.noConflict = function noConflict() { 7497 if (wasAutocompleteSet) { 7498 window.autocomplete = oldAutocomplete; 7499 } else { 7500 delete window.autocomplete; 7501 } 7502 return autocomplete; 7503 }; 7504 7505 module.exports = autocomplete; 7506 7507 7508 /***/ }), 7509 /* 46 */ 7510 /***/ (function(module, exports, __webpack_require__) { 7511 7512 "use strict"; 7513 7514 7515 var _main = __webpack_require__(21); 7516 7517 var _main2 = _interopRequireDefault(_main); 7518 7519 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 7520 7521 module.exports = _main2.default; /* eslint-disable import/no-commonjs */ 7522 7523 /***/ }), 7524 /* 47 */ 7525 /***/ (function(module, exports, __webpack_require__) { 7526 7527 "use strict"; 7528 7529 7530 Object.defineProperty(exports, "__esModule", { 7531 value: true 7532 }); 7533 7534 var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; 7535 7536 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); 7537 7538 var _hogan = __webpack_require__(54); 7539 7540 var _hogan2 = _interopRequireDefault(_hogan); 7541 7542 var _lite = __webpack_require__(24); 7543 7544 var _lite2 = _interopRequireDefault(_lite); 7545 7546 var _autocomplete = __webpack_require__(37); 7547 7548 var _autocomplete2 = _interopRequireDefault(_autocomplete); 7549 7550 var _templates = __webpack_require__(48); 7551 7552 var _templates2 = _interopRequireDefault(_templates); 7553 7554 var _utils = __webpack_require__(49); 7555 7556 var _utils2 = _interopRequireDefault(_utils); 7557 7558 var _version = __webpack_require__(18); 7559 7560 var _version2 = _interopRequireDefault(_version); 7561 7562 var _zepto = __webpack_require__(19); 7563 7564 var _zepto2 = _interopRequireDefault(_zepto); 7565 7566 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 7567 7568 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 7569 7570 /** 7571 * Adds an autocomplete dropdown to an input field 7572 * @function DocSearch 7573 * @param {string} options.apiKey Read-only API key 7574 * @param {string} options.indexName Name of the index to target 7575 * @param {string} options.inputSelector CSS selector that targets the input 7576 * @param {string} [options.appId] Lets you override the applicationId used. 7577 * If using the default Algolia Crawler, you should not have to change this 7578 * value. 7579 * @param {Object} [options.algoliaOptions] Options to pass the underlying Algolia client 7580 * @param {Object} [options.autocompleteOptions] Options to pass to the underlying autocomplete instance 7581 * @return {Object} 7582 */ 7583 var usage = 'Usage:\n documentationSearch({\n apiKey,\n indexName,\n inputSelector,\n [ appId ],\n [ algoliaOptions.{hitsPerPage} ]\n [ autocompleteOptions.{hint,debug} ]\n})'; 7584 7585 var DocSearch = function () { 7586 function DocSearch(_ref) { 7587 var apiKey = _ref.apiKey, 7588 indexName = _ref.indexName, 7589 inputSelector = _ref.inputSelector, 7590 _ref$appId = _ref.appId, 7591 appId = _ref$appId === undefined ? 'BH4D9OD16A' : _ref$appId, 7592 _ref$debug = _ref.debug, 7593 debug = _ref$debug === undefined ? false : _ref$debug, 7594 _ref$algoliaOptions = _ref.algoliaOptions, 7595 algoliaOptions = _ref$algoliaOptions === undefined ? {} : _ref$algoliaOptions, 7596 _ref$autocompleteOpti = _ref.autocompleteOptions, 7597 autocompleteOptions = _ref$autocompleteOpti === undefined ? { 7598 debug: false, 7599 hint: false, 7600 autoselect: true 7601 } : _ref$autocompleteOpti, 7602 _ref$transformData = _ref.transformData, 7603 transformData = _ref$transformData === undefined ? false : _ref$transformData, 7604 _ref$handleSelected = _ref.handleSelected, 7605 handleSelected = _ref$handleSelected === undefined ? false : _ref$handleSelected, 7606 _ref$enhancedSearchIn = _ref.enhancedSearchInput, 7607 enhancedSearchInput = _ref$enhancedSearchIn === undefined ? false : _ref$enhancedSearchIn, 7608 _ref$layout = _ref.layout, 7609 layout = _ref$layout === undefined ? 'collumns' : _ref$layout; 7610 7611 _classCallCheck(this, DocSearch); 7612 7613 DocSearch.checkArguments({ 7614 apiKey: apiKey, 7615 indexName: indexName, 7616 inputSelector: inputSelector, 7617 debug: debug, 7618 algoliaOptions: algoliaOptions, 7619 autocompleteOptions: autocompleteOptions, 7620 transformData: transformData, 7621 handleSelected: handleSelected, 7622 enhancedSearchInput: enhancedSearchInput, 7623 layout: layout 7624 }); 7625 7626 this.apiKey = apiKey; 7627 this.appId = appId; 7628 this.indexName = indexName; 7629 this.input = DocSearch.getInputFromSelector(inputSelector); 7630 this.algoliaOptions = _extends({ hitsPerPage: 5 }, algoliaOptions); 7631 var autocompleteOptionsDebug = autocompleteOptions && autocompleteOptions.debug ? autocompleteOptions.debug : false; 7632 autocompleteOptions.debug = debug || autocompleteOptionsDebug; 7633 this.autocompleteOptions = autocompleteOptions; 7634 this.autocompleteOptions.cssClasses = { 7635 prefix: 'ds' 7636 }; 7637 7638 handleSelected = handleSelected || this.handleSelected; 7639 7640 this.isSimpleLayout = layout === 'simple'; 7641 7642 this.client = (0, _lite2.default)(this.appId, this.apiKey); 7643 this.client.addAlgoliaAgent('docsearch.js ' + _version2.default); 7644 7645 if (enhancedSearchInput) { 7646 this.input = DocSearch.injectSearchBox(this.input); 7647 } 7648 7649 this.autocomplete = (0, _autocomplete2.default)(this.input, autocompleteOptions, [{ 7650 source: this.getAutocompleteSource(transformData), 7651 templates: { 7652 suggestion: DocSearch.getSuggestionTemplate(this.isSimpleLayout), 7653 footer: _templates2.default.footer, 7654 empty: DocSearch.getEmptyTemplate() 7655 } 7656 }]); 7657 this.autocomplete.on('autocomplete:selected', handleSelected.bind(null, this.autocomplete.autocomplete)); 7658 this.autocomplete.on('autocomplete:shown', this.handleShown.bind(null, this.input)); 7659 7660 if (enhancedSearchInput) { 7661 DocSearch.bindSearchBoxEvent(); 7662 } 7663 } 7664 7665 /** 7666 * Checks that the passed arguments are valid. Will throw errors otherwise 7667 * @function checkArguments 7668 * @param {object} args Arguments as an option object 7669 * @returns {void} 7670 */ 7671 7672 7673 _createClass(DocSearch, [{ 7674 key: 'getAutocompleteSource', 7675 7676 7677 /** 7678 * Returns the `source` method to be passed to autocomplete.js. It will query 7679 * the Algolia index and call the callbacks with the formatted hits. 7680 * @function getAutocompleteSource 7681 * @param {function} transformData An optional function to transform the hits 7682 * @returns {function} Method to be passed as the `source` option of 7683 * autocomplete 7684 */ 7685 value: function getAutocompleteSource(transformData) { 7686 var _this = this; 7687 7688 return function (query, callback) { 7689 _this.client.search([{ 7690 indexName: _this.indexName, 7691 query: query, 7692 params: _this.algoliaOptions 7693 }]).then(function (data) { 7694 var hits = data.results[0].hits; 7695 if (transformData) { 7696 hits = transformData(hits) || hits; 7697 } 7698 callback(DocSearch.formatHits(hits)); 7699 }); 7700 }; 7701 } 7702 7703 // Given a list of hits returned by the API, will reformat them to be used in 7704 // a Hogan template 7705 7706 }, { 7707 key: 'handleSelected', 7708 value: function handleSelected(input, event, suggestion) { 7709 input.setVal(''); 7710 window.location.href = suggestion.url; 7711 } 7712 }, { 7713 key: 'handleShown', 7714 value: function handleShown(input) { 7715 var middleOfInput = input.offset().left + input.width() / 2; 7716 var middleOfWindow = (0, _zepto2.default)(document).width() / 2; 7717 7718 if (isNaN(middleOfWindow)) { 7719 middleOfWindow = 900; 7720 } 7721 7722 var alignClass = middleOfInput - middleOfWindow >= 0 ? 'algolia-autocomplete-right' : 'algolia-autocomplete-left'; 7723 var otherAlignClass = middleOfInput - middleOfWindow < 0 ? 'algolia-autocomplete-right' : 'algolia-autocomplete-left'; 7724 7725 var autocompleteWrapper = (0, _zepto2.default)('.algolia-autocomplete'); 7726 if (!autocompleteWrapper.hasClass(alignClass)) { 7727 autocompleteWrapper.addClass(alignClass); 7728 } 7729 7730 if (autocompleteWrapper.hasClass(otherAlignClass)) { 7731 autocompleteWrapper.removeClass(otherAlignClass); 7732 } 7733 } 7734 }], [{ 7735 key: 'checkArguments', 7736 value: function checkArguments(args) { 7737 if (!args.apiKey || !args.indexName) { 7738 throw new Error(usage); 7739 } 7740 7741 if (!DocSearch.getInputFromSelector(args.inputSelector)) { 7742 throw new Error('Error: No input element in the page matches ' + args.inputSelector); 7743 } 7744 } 7745 }, { 7746 key: 'injectSearchBox', 7747 value: function injectSearchBox(input) { 7748 input.before(_templates2.default.searchBox); 7749 var newInput = input.prev().prev().find('input'); 7750 input.remove(); 7751 return newInput; 7752 } 7753 }, { 7754 key: 'bindSearchBoxEvent', 7755 value: function bindSearchBoxEvent() { 7756 (0, _zepto2.default)('.searchbox [type="reset"]').on('click', function () { 7757 (0, _zepto2.default)('input#docsearch').focus(); 7758 (0, _zepto2.default)(this).addClass('hide'); 7759 _autocomplete2.default.autocomplete.setVal(''); 7760 }); 7761 7762 (0, _zepto2.default)('input#docsearch').on('keyup', function () { 7763 var searchbox = document.querySelector('input#docsearch'); 7764 var reset = document.querySelector('.searchbox [type="reset"]'); 7765 reset.className = 'searchbox__reset'; 7766 if (searchbox.value.length === 0) { 7767 reset.className += ' hide'; 7768 } 7769 }); 7770 } 7771 7772 /** 7773 * Returns the matching input from a CSS selector, null if none matches 7774 * @function getInputFromSelector 7775 * @param {string} selector CSS selector that matches the search 7776 * input of the page 7777 * @returns {void} 7778 */ 7779 7780 }, { 7781 key: 'getInputFromSelector', 7782 value: function getInputFromSelector(selector) { 7783 var input = (0, _zepto2.default)(selector).filter('input'); 7784 return input.length ? (0, _zepto2.default)(input[0]) : null; 7785 } 7786 }, { 7787 key: 'formatHits', 7788 value: function formatHits(receivedHits) { 7789 var clonedHits = _utils2.default.deepClone(receivedHits); 7790 var hits = clonedHits.map(function (hit) { 7791 if (hit._highlightResult) { 7792 hit._highlightResult = _utils2.default.mergeKeyWithParent(hit._highlightResult, 'hierarchy'); 7793 } 7794 return _utils2.default.mergeKeyWithParent(hit, 'hierarchy'); 7795 }); 7796 7797 // Group hits by category / subcategory 7798 var groupedHits = _utils2.default.groupBy(hits, 'lvl0'); 7799 _zepto2.default.each(groupedHits, function (level, collection) { 7800 var groupedHitsByLvl1 = _utils2.default.groupBy(collection, 'lvl1'); 7801 var flattenedHits = _utils2.default.flattenAndFlagFirst(groupedHitsByLvl1, 'isSubCategoryHeader'); 7802 groupedHits[level] = flattenedHits; 7803 }); 7804 groupedHits = _utils2.default.flattenAndFlagFirst(groupedHits, 'isCategoryHeader'); 7805 7806 // Translate hits into smaller objects to be send to the template 7807 return groupedHits.map(function (hit) { 7808 var url = DocSearch.formatURL(hit); 7809 var category = _utils2.default.getHighlightedValue(hit, 'lvl0'); 7810 var subcategory = _utils2.default.getHighlightedValue(hit, 'lvl1') || category; 7811 var displayTitle = _utils2.default.compact([_utils2.default.getHighlightedValue(hit, 'lvl2') || subcategory, _utils2.default.getHighlightedValue(hit, 'lvl3'), _utils2.default.getHighlightedValue(hit, 'lvl4'), _utils2.default.getHighlightedValue(hit, 'lvl5'), _utils2.default.getHighlightedValue(hit, 'lvl6')]).join('<span class="aa-suggestion-title-separator" aria-hidden="true"> › </span>'); 7812 var text = _utils2.default.getSnippetedValue(hit, 'content'); 7813 var isTextOrSubcatoryNonEmpty = subcategory && subcategory !== '' || displayTitle && displayTitle !== ''; 7814 var isLvl1EmptyOrDuplicate = !subcategory || subcategory === '' || subcategory === category; 7815 var isLvl2 = displayTitle && displayTitle !== '' && displayTitle !== subcategory; 7816 var isLvl1 = !isLvl2 && subcategory && subcategory !== '' && subcategory !== category; 7817 var isLvl0 = !isLvl1 && !isLvl2; 7818 7819 return { 7820 isLvl0: isLvl0, 7821 isLvl1: isLvl1, 7822 isLvl2: isLvl2, 7823 isLvl1EmptyOrDuplicate: isLvl1EmptyOrDuplicate, 7824 isCategoryHeader: hit.isCategoryHeader, 7825 isSubCategoryHeader: hit.isSubCategoryHeader, 7826 isTextOrSubcatoryNonEmpty: isTextOrSubcatoryNonEmpty, 7827 category: category, 7828 subcategory: subcategory, 7829 title: displayTitle, 7830 text: text, 7831 url: url 7832 }; 7833 }); 7834 } 7835 }, { 7836 key: 'formatURL', 7837 value: function formatURL(hit) { 7838 var url = hit.url, 7839 anchor = hit.anchor; 7840 7841 if (url) { 7842 var containsAnchor = url.indexOf('#') !== -1; 7843 if (containsAnchor) return url;else if (anchor) return hit.url + '#' + hit.anchor; 7844 return url; 7845 } else if (anchor) return '#' + hit.anchor; 7846 /* eslint-disable */ 7847 console.warn('no anchor nor url for : ', JSON.stringify(hit)); 7848 /* eslint-enable */ 7849 return null; 7850 } 7851 }, { 7852 key: 'getEmptyTemplate', 7853 value: function getEmptyTemplate() { 7854 return function (args) { 7855 return _hogan2.default.compile(_templates2.default.empty).render(args); 7856 }; 7857 } 7858 }, { 7859 key: 'getSuggestionTemplate', 7860 value: function getSuggestionTemplate(isSimpleLayout) { 7861 var stringTemplate = isSimpleLayout ? _templates2.default.suggestionSimple : _templates2.default.suggestion; 7862 var template = _hogan2.default.compile(stringTemplate); 7863 return function (suggestion) { 7864 return template.render(suggestion); 7865 }; 7866 } 7867 }]); 7868 7869 return DocSearch; 7870 }(); 7871 7872 exports.default = DocSearch; 7873 7874 /***/ }), 7875 /* 48 */ 7876 /***/ (function(module, exports, __webpack_require__) { 7877 7878 "use strict"; 7879 7880 7881 Object.defineProperty(exports, "__esModule", { 7882 value: true 7883 }); 7884 var prefix = 'algolia-docsearch'; 7885 var suggestionPrefix = prefix + '-suggestion'; 7886 var footerPrefix = prefix + '-footer'; 7887 7888 /* eslint-disable max-len */ 7889 7890 var templates = { 7891 suggestion: '\n <div class="' + suggestionPrefix + '\n {{#isCategoryHeader}}' + suggestionPrefix + '__main{{/isCategoryHeader}}\n {{#isSubCategoryHeader}}' + suggestionPrefix + '__secondary{{/isSubCategoryHeader}}\n ">\n <div class="' + suggestionPrefix + '--category-header">\n <span class="' + suggestionPrefix + '--category-header-lvl0">{{{category}}}</span>\n </div>\n <div class="' + suggestionPrefix + '--wrapper">\n <div class="' + suggestionPrefix + '--subcategory-column">\n <span class="' + suggestionPrefix + '--subcategory-column-text">{{{subcategory}}}</span>\n </div>\n {{#isTextOrSubcatoryNonEmpty}}\n <div class="' + suggestionPrefix + '--content">\n <div class="' + suggestionPrefix + '--subcategory-inline">{{{subcategory}}}</div>\n <div class="' + suggestionPrefix + '--title">{{{title}}}</div>\n {{#text}}<div class="' + suggestionPrefix + '--text">{{{text}}}</div>{{/text}}\n </div>\n {{/isTextOrSubcatoryNonEmpty}}\n </div>\n </div>\n ', 7892 suggestionSimple: '\n <div class="' + suggestionPrefix + '\n {{#isCategoryHeader}}' + suggestionPrefix + '__main{{/isCategoryHeader}}\n {{#isSubCategoryHeader}}' + suggestionPrefix + '__secondary{{/isSubCategoryHeader}}\n suggestion-layout-simple\n ">\n <div class="' + suggestionPrefix + '--category-header">\n {{^isLvl0}}\n <span class="' + suggestionPrefix + '--category-header-lvl0 ' + suggestionPrefix + '--category-header-item">{{{category}}}</span>\n {{^isLvl1}}\n {{^isLvl1EmptyOrDuplicate}}\n <span class="' + suggestionPrefix + '--category-header-lvl1 ' + suggestionPrefix + '--category-header-item">\n {{{subcategory}}}\n </span>\n {{/isLvl1EmptyOrDuplicate}}\n {{/isLvl1}}\n {{/isLvl0}}\n <div class="' + suggestionPrefix + '--title ' + suggestionPrefix + '--category-header-item">\n {{#isLvl2}}\n {{{title}}}\n {{/isLvl2}}\n {{#isLvl1}}\n {{{subcategory}}}\n {{/isLvl1}}\n {{#isLvl0}}\n {{{category}}}\n {{/isLvl0}}\n </div>\n </div>\n <div class="' + suggestionPrefix + '--wrapper">\n {{#text}}\n <div class="' + suggestionPrefix + '--content">\n <div class="' + suggestionPrefix + '--text">{{{text}}}</div>\n </div>\n {{/text}}\n </div>\n </div>\n ', 7893 footer: '\n <div class="' + footerPrefix + '">\n Search by <a class="' + footerPrefix + '--logo" href="https://www.algolia.com/docsearch">Algolia</a>\n </div>\n ', 7894 empty: '\n <div class="' + suggestionPrefix + '">\n <div class="' + suggestionPrefix + '--wrapper">\n <div class="' + suggestionPrefix + '--content ' + suggestionPrefix + '--no-results">\n <div class="' + suggestionPrefix + '--title">\n <div class="' + suggestionPrefix + '--text">\n No results found for query <b>"{{query}}"</b>\n </div>\n </div>\n </div>\n </div>\n </div>\n ', 7895 searchBox: '\n <form novalidate="novalidate" onsubmit="return false;" class="searchbox">\n <div role="search" class="searchbox__wrapper">\n <input id="docsearch" type="search" name="search" placeholder="Search the docs" autocomplete="off" required="required" class="searchbox__input"/>\n <button type="submit" title="Submit your search query." class="searchbox__submit" >\n <svg width=12 height=12 role="img" aria-label="Search">\n <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sbx-icon-search-13"></use>\n </svg>\n </button>\n <button type="reset" title="Clear the search query." class="searchbox__reset hide">\n <svg width=12 height=12 role="img" aria-label="Reset">\n <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sbx-icon-clear-3"></use>\n </svg>\n </button>\n </div>\n</form>\n\n<div class="svg-icons" style="height: 0; width: 0; position: absolute; visibility: hidden">\n <svg xmlns="http://www.w3.org/2000/svg">\n <symbol id="sbx-icon-clear-3" viewBox="0 0 40 40"><path d="M16.228 20L1.886 5.657 0 3.772 3.772 0l1.885 1.886L20 16.228 34.343 1.886 36.228 0 40 3.772l-1.886 1.885L23.772 20l14.342 14.343L40 36.228 36.228 40l-1.885-1.886L20 23.772 5.657 38.114 3.772 40 0 36.228l1.886-1.885L16.228 20z" fill-rule="evenodd"></symbol>\n <symbol id="sbx-icon-search-13" viewBox="0 0 40 40"><path d="M26.806 29.012a16.312 16.312 0 0 1-10.427 3.746C7.332 32.758 0 25.425 0 16.378 0 7.334 7.333 0 16.38 0c9.045 0 16.378 7.333 16.378 16.38 0 3.96-1.406 7.593-3.746 10.426L39.547 37.34c.607.608.61 1.59-.004 2.203a1.56 1.56 0 0 1-2.202.004L26.807 29.012zm-10.427.627c7.322 0 13.26-5.938 13.26-13.26 0-7.324-5.938-13.26-13.26-13.26-7.324 0-13.26 5.936-13.26 13.26 0 7.322 5.936 13.26 13.26 13.26z" fill-rule="evenodd"></symbol>\n </svg>\n</div>\n ' 7896 }; 7897 7898 exports.default = templates; 7899 7900 /***/ }), 7901 /* 49 */ 7902 /***/ (function(module, exports, __webpack_require__) { 7903 7904 "use strict"; 7905 7906 7907 Object.defineProperty(exports, "__esModule", { 7908 value: true 7909 }); 7910 7911 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 7912 7913 var _zepto = __webpack_require__(19); 7914 7915 var _zepto2 = _interopRequireDefault(_zepto); 7916 7917 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 7918 7919 var utils = { 7920 /* 7921 * Move the content of an object key one level higher. 7922 * eg. 7923 * { 7924 * name: 'My name', 7925 * hierarchy: { 7926 * lvl0: 'Foo', 7927 * lvl1: 'Bar' 7928 * } 7929 * } 7930 * Will be converted to 7931 * { 7932 * name: 'My name', 7933 * lvl0: 'Foo', 7934 * lvl1: 'Bar' 7935 * } 7936 * @param {Object} object Main object 7937 * @param {String} property Main object key to move up 7938 * @return {Object} 7939 * @throws Error when key is not an attribute of Object or is not an object itself 7940 */ 7941 mergeKeyWithParent: function mergeKeyWithParent(object, property) { 7942 if (object[property] === undefined) { 7943 return object; 7944 } 7945 if (_typeof(object[property]) !== 'object') { 7946 return object; 7947 } 7948 var newObject = _zepto2.default.extend({}, object, object[property]); 7949 delete newObject[property]; 7950 return newObject; 7951 }, 7952 7953 /* 7954 * Group all objects of a collection by the value of the specified attribute 7955 * If the attribute is a string, use the lowercase form. 7956 * 7957 * eg. 7958 * groupBy([ 7959 * {name: 'Tim', category: 'dev'}, 7960 * {name: 'Vincent', category: 'dev'}, 7961 * {name: 'Ben', category: 'sales'}, 7962 * {name: 'Jeremy', category: 'sales'}, 7963 * {name: 'AlexS', category: 'dev'}, 7964 * {name: 'AlexK', category: 'sales'} 7965 * ], 'category'); 7966 * => 7967 * { 7968 * 'devs': [ 7969 * {name: 'Tim', category: 'dev'}, 7970 * {name: 'Vincent', category: 'dev'}, 7971 * {name: 'AlexS', category: 'dev'} 7972 * ], 7973 * 'sales': [ 7974 * {name: 'Ben', category: 'sales'}, 7975 * {name: 'Jeremy', category: 'sales'}, 7976 * {name: 'AlexK', category: 'sales'} 7977 * ] 7978 * } 7979 * @param {array} collection Array of objects to group 7980 * @param {String} property The attribute on which apply the grouping 7981 * @return {array} 7982 * @throws Error when one of the element does not have the specified property 7983 */ 7984 groupBy: function groupBy(collection, property) { 7985 var newCollection = {}; 7986 _zepto2.default.each(collection, function (index, item) { 7987 if (item[property] === undefined) { 7988 throw new Error('[groupBy]: Object has no key ' + property); 7989 } 7990 var key = item[property]; 7991 if (typeof key === 'string') { 7992 key = key.toLowerCase(); 7993 } 7994 // fix #171 the given data type of docsearch hits might be conflict with the properties of the native Object, 7995 // such as the constructor, so we need to do this check. 7996 if (!Object.prototype.hasOwnProperty.call(newCollection, key)) { 7997 newCollection[key] = []; 7998 } 7999 newCollection[key].push(item); 8000 }); 8001 return newCollection; 8002 }, 8003 8004 /* 8005 * Return an array of all the values of the specified object 8006 * eg. 8007 * values({ 8008 * foo: 42, 8009 * bar: true, 8010 * baz: 'yep' 8011 * }) 8012 * => 8013 * [42, true, yep] 8014 * @param {object} object Object to extract values from 8015 * @return {array} 8016 */ 8017 values: function values(object) { 8018 return Object.keys(object).map(function (key) { 8019 return object[key]; 8020 }); 8021 }, 8022 8023 /* 8024 * Flattens an array 8025 * eg. 8026 * flatten([1, 2, [3, 4], [5, 6]]) 8027 * => 8028 * [1, 2, 3, 4, 5, 6] 8029 * @param {array} array Array to flatten 8030 * @return {array} 8031 */ 8032 flatten: function flatten(array) { 8033 var results = []; 8034 array.forEach(function (value) { 8035 if (!Array.isArray(value)) { 8036 results.push(value); 8037 return; 8038 } 8039 value.forEach(function (subvalue) { 8040 results.push(subvalue); 8041 }); 8042 }); 8043 return results; 8044 }, 8045 8046 /* 8047 * Flatten all values of an object into an array, marking each first element of 8048 * each group with a specific flag 8049 * eg. 8050 * flattenAndFlagFirst({ 8051 * 'devs': [ 8052 * {name: 'Tim', category: 'dev'}, 8053 * {name: 'Vincent', category: 'dev'}, 8054 * {name: 'AlexS', category: 'dev'} 8055 * ], 8056 * 'sales': [ 8057 * {name: 'Ben', category: 'sales'}, 8058 * {name: 'Jeremy', category: 'sales'}, 8059 * {name: 'AlexK', category: 'sales'} 8060 * ] 8061 * , 'isTop'); 8062 * => 8063 * [ 8064 * {name: 'Tim', category: 'dev', isTop: true}, 8065 * {name: 'Vincent', category: 'dev', isTop: false}, 8066 * {name: 'AlexS', category: 'dev', isTop: false}, 8067 * {name: 'Ben', category: 'sales', isTop: true}, 8068 * {name: 'Jeremy', category: 'sales', isTop: false}, 8069 * {name: 'AlexK', category: 'sales', isTop: false} 8070 * ] 8071 * @param {object} object Object to flatten 8072 * @param {string} flag Flag to set to true on first element of each group 8073 * @return {array} 8074 */ 8075 flattenAndFlagFirst: function flattenAndFlagFirst(object, flag) { 8076 var values = this.values(object).map(function (collection) { 8077 return collection.map(function (item, index) { 8078 item[flag] = index === 0; 8079 return item; 8080 }); 8081 }); 8082 return this.flatten(values); 8083 }, 8084 8085 /* 8086 * Removes all empty strings, null, false and undefined elements array 8087 * eg. 8088 * compact([42, false, null, undefined, '', [], 'foo']); 8089 * => 8090 * [42, [], 'foo'] 8091 * @param {array} array Array to compact 8092 * @return {array} 8093 */ 8094 compact: function compact(array) { 8095 var results = []; 8096 array.forEach(function (value) { 8097 if (!value) { 8098 return; 8099 } 8100 results.push(value); 8101 }); 8102 return results; 8103 }, 8104 8105 /* 8106 * Returns the highlighted value of the specified key in the specified object. 8107 * If no highlighted value is available, will return the key value directly 8108 * eg. 8109 * getHighlightedValue({ 8110 * _highlightResult: { 8111 * text: { 8112 * value: '<mark>foo</mark>' 8113 * } 8114 * }, 8115 * text: 'foo' 8116 * }, 'text'); 8117 * => 8118 * '<mark>foo</mark>' 8119 * @param {object} object Hit object returned by the Algolia API 8120 * @param {string} property Object key to look for 8121 * @return {string} 8122 **/ 8123 getHighlightedValue: function getHighlightedValue(object, property) { 8124 if (object._highlightResult && object._highlightResult.hierarchy_camel && object._highlightResult.hierarchy_camel[property] && object._highlightResult.hierarchy_camel[property].matchLevel && object._highlightResult.hierarchy_camel[property].matchLevel !== 'none' && object._highlightResult.hierarchy_camel[property].value) { 8125 return object._highlightResult.hierarchy_camel[property].value; 8126 } 8127 if (object._highlightResult && object._highlightResult && object._highlightResult[property] && object._highlightResult[property].value) { 8128 return object._highlightResult[property].value; 8129 } 8130 return object[property]; 8131 }, 8132 8133 /* 8134 * Returns the snippeted value of the specified key in the specified object. 8135 * If no highlighted value is available, will return the key value directly. 8136 * Will add starting and ending ellipsis (…) if we detect that a sentence is 8137 * incomplete 8138 * eg. 8139 * getSnippetedValue({ 8140 * _snippetResult: { 8141 * text: { 8142 * value: '<mark>This is an unfinished sentence</mark>' 8143 * } 8144 * }, 8145 * text: 'This is an unfinished sentence' 8146 * }, 'text'); 8147 * => 8148 * '<mark>This is an unefinished sentenced</mark>…' 8149 * @param {object} object Hit object returned by the Algolia API 8150 * @param {string} property Object key to look for 8151 * @return {string} 8152 **/ 8153 getSnippetedValue: function getSnippetedValue(object, property) { 8154 if (!object._snippetResult || !object._snippetResult[property] || !object._snippetResult[property].value) { 8155 return object[property]; 8156 } 8157 var snippet = object._snippetResult[property].value; 8158 8159 if (snippet[0] !== snippet[0].toUpperCase()) { 8160 snippet = '\u2026' + snippet; 8161 } 8162 if (['.', '!', '?'].indexOf(snippet[snippet.length - 1]) === -1) { 8163 snippet = snippet + '\u2026'; 8164 } 8165 return snippet; 8166 }, 8167 8168 /* 8169 * Deep clone an object. 8170 * Note: This will not clone functions and dates 8171 * @param {object} object Object to clone 8172 * @return {object} 8173 */ 8174 deepClone: function deepClone(object) { 8175 return JSON.parse(JSON.stringify(object)); 8176 } 8177 }; 8178 8179 exports.default = utils; 8180 8181 /***/ }), 8182 /* 50 */ 8183 /***/ (function(module, exports, __webpack_require__) { 8184 8185 8186 /** 8187 * This is the common logic for both the Node.js and web browser 8188 * implementations of `debug()`. 8189 * 8190 * Expose `debug()` as the module. 8191 */ 8192 8193 exports = module.exports = debug.debug = debug; 8194 exports.coerce = coerce; 8195 exports.disable = disable; 8196 exports.enable = enable; 8197 exports.enabled = enabled; 8198 exports.humanize = __webpack_require__(62); 8199 8200 /** 8201 * The currently active debug mode names, and names to skip. 8202 */ 8203 8204 exports.names = []; 8205 exports.skips = []; 8206 8207 /** 8208 * Map of special "%n" handling functions, for the debug "format" argument. 8209 * 8210 * Valid key names are a single, lowercased letter, i.e. "n". 8211 */ 8212 8213 exports.formatters = {}; 8214 8215 /** 8216 * Previously assigned color. 8217 */ 8218 8219 var prevColor = 0; 8220 8221 /** 8222 * Previous log timestamp. 8223 */ 8224 8225 var prevTime; 8226 8227 /** 8228 * Select a color. 8229 * 8230 * @return {Number} 8231 * @api private 8232 */ 8233 8234 function selectColor() { 8235 return exports.colors[prevColor++ % exports.colors.length]; 8236 } 8237 8238 /** 8239 * Create a debugger with the given `namespace`. 8240 * 8241 * @param {String} namespace 8242 * @return {Function} 8243 * @api public 8244 */ 8245 8246 function debug(namespace) { 8247 8248 // define the `disabled` version 8249 function disabled() { 8250 } 8251 disabled.enabled = false; 8252 8253 // define the `enabled` version 8254 function enabled() { 8255 8256 var self = enabled; 8257 8258 // set `diff` timestamp 8259 var curr = +new Date(); 8260 var ms = curr - (prevTime || curr); 8261 self.diff = ms; 8262 self.prev = prevTime; 8263 self.curr = curr; 8264 prevTime = curr; 8265 8266 // add the `color` if not set 8267 if (null == self.useColors) self.useColors = exports.useColors(); 8268 if (null == self.color && self.useColors) self.color = selectColor(); 8269 8270 var args = new Array(arguments.length); 8271 for (var i = 0; i < args.length; i++) { 8272 args[i] = arguments[i]; 8273 } 8274 8275 args[0] = exports.coerce(args[0]); 8276 8277 if ('string' !== typeof args[0]) { 8278 // anything else let's inspect with %o 8279 args = ['%o'].concat(args); 8280 } 8281 8282 // apply any `formatters` transformations 8283 var index = 0; 8284 args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { 8285 // if we encounter an escaped % then don't increase the array index 8286 if (match === '%%') return match; 8287 index++; 8288 var formatter = exports.formatters[format]; 8289 if ('function' === typeof formatter) { 8290 var val = args[index]; 8291 match = formatter.call(self, val); 8292 8293 // now we need to remove `args[index]` since it's inlined in the `format` 8294 args.splice(index, 1); 8295 index--; 8296 } 8297 return match; 8298 }); 8299 8300 // apply env-specific formatting 8301 args = exports.formatArgs.apply(self, args); 8302 8303 var logFn = enabled.log || exports.log || console.log.bind(console); 8304 logFn.apply(self, args); 8305 } 8306 enabled.enabled = true; 8307 8308 var fn = exports.enabled(namespace) ? enabled : disabled; 8309 8310 fn.namespace = namespace; 8311 8312 return fn; 8313 } 8314 8315 /** 8316 * Enables a debug mode by namespaces. This can include modes 8317 * separated by a colon and wildcards. 8318 * 8319 * @param {String} namespaces 8320 * @api public 8321 */ 8322 8323 function enable(namespaces) { 8324 exports.save(namespaces); 8325 8326 var split = (namespaces || '').split(/[\s,]+/); 8327 var len = split.length; 8328 8329 for (var i = 0; i < len; i++) { 8330 if (!split[i]) continue; // ignore empty strings 8331 namespaces = split[i].replace(/[\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '.*?'); 8332 if (namespaces[0] === '-') { 8333 exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); 8334 } else { 8335 exports.names.push(new RegExp('^' + namespaces + '$')); 8336 } 8337 } 8338 } 8339 8340 /** 8341 * Disable debug output. 8342 * 8343 * @api public 8344 */ 8345 8346 function disable() { 8347 exports.enable(''); 8348 } 8349 8350 /** 8351 * Returns true if the given mode name is enabled, false otherwise. 8352 * 8353 * @param {String} name 8354 * @return {Boolean} 8355 * @api public 8356 */ 8357 8358 function enabled(name) { 8359 var i, len; 8360 for (i = 0, len = exports.skips.length; i < len; i++) { 8361 if (exports.skips[i].test(name)) { 8362 return false; 8363 } 8364 } 8365 for (i = 0, len = exports.names.length; i < len; i++) { 8366 if (exports.names[i].test(name)) { 8367 return true; 8368 } 8369 } 8370 return false; 8371 } 8372 8373 /** 8374 * Coerce `val`. 8375 * 8376 * @param {Mixed} val 8377 * @return {Mixed} 8378 * @api private 8379 */ 8380 8381 function coerce(val) { 8382 if (val instanceof Error) return val.stack || val.message; 8383 return val; 8384 } 8385 8386 8387 /***/ }), 8388 /* 51 */ 8389 /***/ (function(module, exports, __webpack_require__) { 8390 8391 /* WEBPACK VAR INJECTION */(function(process, global) {var require;/*! 8392 * @overview es6-promise - a tiny implementation of Promises/A+. 8393 * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald) 8394 * @license Licensed under MIT license 8395 * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE 8396 * @version 4.0.5 8397 */ 8398 8399 (function (global, factory) { 8400 true ? module.exports = factory() : 8401 typeof define === 'function' && define.amd ? define(factory) : 8402 (global.ES6Promise = factory()); 8403 }(this, (function () { 'use strict'; 8404 8405 function objectOrFunction(x) { 8406 return typeof x === 'function' || typeof x === 'object' && x !== null; 8407 } 8408 8409 function isFunction(x) { 8410 return typeof x === 'function'; 8411 } 8412 8413 var _isArray = undefined; 8414 if (!Array.isArray) { 8415 _isArray = function (x) { 8416 return Object.prototype.toString.call(x) === '[object Array]'; 8417 }; 8418 } else { 8419 _isArray = Array.isArray; 8420 } 8421 8422 var isArray = _isArray; 8423 8424 var len = 0; 8425 var vertxNext = undefined; 8426 var customSchedulerFn = undefined; 8427 8428 var asap = function asap(callback, arg) { 8429 queue[len] = callback; 8430 queue[len + 1] = arg; 8431 len += 2; 8432 if (len === 2) { 8433 // If len is 2, that means that we need to schedule an async flush. 8434 // If additional callbacks are queued before the queue is flushed, they 8435 // will be processed by this flush that we are scheduling. 8436 if (customSchedulerFn) { 8437 customSchedulerFn(flush); 8438 } else { 8439 scheduleFlush(); 8440 } 8441 } 8442 }; 8443 8444 function setScheduler(scheduleFn) { 8445 customSchedulerFn = scheduleFn; 8446 } 8447 8448 function setAsap(asapFn) { 8449 asap = asapFn; 8450 } 8451 8452 var browserWindow = typeof window !== 'undefined' ? window : undefined; 8453 var browserGlobal = browserWindow || {}; 8454 var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver; 8455 var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && ({}).toString.call(process) === '[object process]'; 8456 8457 // test for web worker but not in IE10 8458 var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined'; 8459 8460 // node 8461 function useNextTick() { 8462 // node version 0.10.x displays a deprecation warning when nextTick is used recursively 8463 // see https://github.com/cujojs/when/issues/410 for details 8464 return function () { 8465 return process.nextTick(flush); 8466 }; 8467 } 8468 8469 // vertx 8470 function useVertxTimer() { 8471 if (typeof vertxNext !== 'undefined') { 8472 return function () { 8473 vertxNext(flush); 8474 }; 8475 } 8476 8477 return useSetTimeout(); 8478 } 8479 8480 function useMutationObserver() { 8481 var iterations = 0; 8482 var observer = new BrowserMutationObserver(flush); 8483 var node = document.createTextNode(''); 8484 observer.observe(node, { characterData: true }); 8485 8486 return function () { 8487 node.data = iterations = ++iterations % 2; 8488 }; 8489 } 8490 8491 // web worker 8492 function useMessageChannel() { 8493 var channel = new MessageChannel(); 8494 channel.port1.onmessage = flush; 8495 return function () { 8496 return channel.port2.postMessage(0); 8497 }; 8498 } 8499 8500 function useSetTimeout() { 8501 // Store setTimeout reference so es6-promise will be unaffected by 8502 // other code modifying setTimeout (like sinon.useFakeTimers()) 8503 var globalSetTimeout = setTimeout; 8504 return function () { 8505 return globalSetTimeout(flush, 1); 8506 }; 8507 } 8508 8509 var queue = new Array(1000); 8510 function flush() { 8511 for (var i = 0; i < len; i += 2) { 8512 var callback = queue[i]; 8513 var arg = queue[i + 1]; 8514 8515 callback(arg); 8516 8517 queue[i] = undefined; 8518 queue[i + 1] = undefined; 8519 } 8520 8521 len = 0; 8522 } 8523 8524 function attemptVertx() { 8525 try { 8526 var r = require; 8527 var vertx = __webpack_require__(67); 8528 vertxNext = vertx.runOnLoop || vertx.runOnContext; 8529 return useVertxTimer(); 8530 } catch (e) { 8531 return useSetTimeout(); 8532 } 8533 } 8534 8535 var scheduleFlush = undefined; 8536 // Decide what async method to use to triggering processing of queued callbacks: 8537 if (isNode) { 8538 scheduleFlush = useNextTick(); 8539 } else if (BrowserMutationObserver) { 8540 scheduleFlush = useMutationObserver(); 8541 } else if (isWorker) { 8542 scheduleFlush = useMessageChannel(); 8543 } else if (browserWindow === undefined && "function" === 'function') { 8544 scheduleFlush = attemptVertx(); 8545 } else { 8546 scheduleFlush = useSetTimeout(); 8547 } 8548 8549 function then(onFulfillment, onRejection) { 8550 var _arguments = arguments; 8551 8552 var parent = this; 8553 8554 var child = new this.constructor(noop); 8555 8556 if (child[PROMISE_ID] === undefined) { 8557 makePromise(child); 8558 } 8559 8560 var _state = parent._state; 8561 8562 if (_state) { 8563 (function () { 8564 var callback = _arguments[_state - 1]; 8565 asap(function () { 8566 return invokeCallback(_state, child, callback, parent._result); 8567 }); 8568 })(); 8569 } else { 8570 subscribe(parent, child, onFulfillment, onRejection); 8571 } 8572 8573 return child; 8574 } 8575 8576 /** 8577 `Promise.resolve` returns a promise that will become resolved with the 8578 passed `value`. It is shorthand for the following: 8579 8580 ```javascript 8581 let promise = new Promise(function(resolve, reject){ 8582 resolve(1); 8583 }); 8584 8585 promise.then(function(value){ 8586 // value === 1 8587 }); 8588 ``` 8589 8590 Instead of writing the above, your code now simply becomes the following: 8591 8592 ```javascript 8593 let promise = Promise.resolve(1); 8594 8595 promise.then(function(value){ 8596 // value === 1 8597 }); 8598 ``` 8599 8600 @method resolve 8601 @static 8602 @param {Any} value value that the returned promise will be resolved with 8603 Useful for tooling. 8604 @return {Promise} a promise that will become fulfilled with the given 8605 `value` 8606 */ 8607 function resolve(object) { 8608 /*jshint validthis:true */ 8609 var Constructor = this; 8610 8611 if (object && typeof object === 'object' && object.constructor === Constructor) { 8612 return object; 8613 } 8614 8615 var promise = new Constructor(noop); 8616 _resolve(promise, object); 8617 return promise; 8618 } 8619 8620 var PROMISE_ID = Math.random().toString(36).substring(16); 8621 8622 function noop() {} 8623 8624 var PENDING = void 0; 8625 var FULFILLED = 1; 8626 var REJECTED = 2; 8627 8628 var GET_THEN_ERROR = new ErrorObject(); 8629 8630 function selfFulfillment() { 8631 return new TypeError("You cannot resolve a promise with itself"); 8632 } 8633 8634 function cannotReturnOwn() { 8635 return new TypeError('A promises callback cannot return that same promise.'); 8636 } 8637 8638 function getThen(promise) { 8639 try { 8640 return promise.then; 8641 } catch (error) { 8642 GET_THEN_ERROR.error = error; 8643 return GET_THEN_ERROR; 8644 } 8645 } 8646 8647 function tryThen(then, value, fulfillmentHandler, rejectionHandler) { 8648 try { 8649 then.call(value, fulfillmentHandler, rejectionHandler); 8650 } catch (e) { 8651 return e; 8652 } 8653 } 8654 8655 function handleForeignThenable(promise, thenable, then) { 8656 asap(function (promise) { 8657 var sealed = false; 8658 var error = tryThen(then, thenable, function (value) { 8659 if (sealed) { 8660 return; 8661 } 8662 sealed = true; 8663 if (thenable !== value) { 8664 _resolve(promise, value); 8665 } else { 8666 fulfill(promise, value); 8667 } 8668 }, function (reason) { 8669 if (sealed) { 8670 return; 8671 } 8672 sealed = true; 8673 8674 _reject(promise, reason); 8675 }, 'Settle: ' + (promise._label || ' unknown promise')); 8676 8677 if (!sealed && error) { 8678 sealed = true; 8679 _reject(promise, error); 8680 } 8681 }, promise); 8682 } 8683 8684 function handleOwnThenable(promise, thenable) { 8685 if (thenable._state === FULFILLED) { 8686 fulfill(promise, thenable._result); 8687 } else if (thenable._state === REJECTED) { 8688 _reject(promise, thenable._result); 8689 } else { 8690 subscribe(thenable, undefined, function (value) { 8691 return _resolve(promise, value); 8692 }, function (reason) { 8693 return _reject(promise, reason); 8694 }); 8695 } 8696 } 8697 8698 function handleMaybeThenable(promise, maybeThenable, then$$) { 8699 if (maybeThenable.constructor === promise.constructor && then$$ === then && maybeThenable.constructor.resolve === resolve) { 8700 handleOwnThenable(promise, maybeThenable); 8701 } else { 8702 if (then$$ === GET_THEN_ERROR) { 8703 _reject(promise, GET_THEN_ERROR.error); 8704 } else if (then$$ === undefined) { 8705 fulfill(promise, maybeThenable); 8706 } else if (isFunction(then$$)) { 8707 handleForeignThenable(promise, maybeThenable, then$$); 8708 } else { 8709 fulfill(promise, maybeThenable); 8710 } 8711 } 8712 } 8713 8714 function _resolve(promise, value) { 8715 if (promise === value) { 8716 _reject(promise, selfFulfillment()); 8717 } else if (objectOrFunction(value)) { 8718 handleMaybeThenable(promise, value, getThen(value)); 8719 } else { 8720 fulfill(promise, value); 8721 } 8722 } 8723 8724 function publishRejection(promise) { 8725 if (promise._onerror) { 8726 promise._onerror(promise._result); 8727 } 8728 8729 publish(promise); 8730 } 8731 8732 function fulfill(promise, value) { 8733 if (promise._state !== PENDING) { 8734 return; 8735 } 8736 8737 promise._result = value; 8738 promise._state = FULFILLED; 8739 8740 if (promise._subscribers.length !== 0) { 8741 asap(publish, promise); 8742 } 8743 } 8744 8745 function _reject(promise, reason) { 8746 if (promise._state !== PENDING) { 8747 return; 8748 } 8749 promise._state = REJECTED; 8750 promise._result = reason; 8751 8752 asap(publishRejection, promise); 8753 } 8754 8755 function subscribe(parent, child, onFulfillment, onRejection) { 8756 var _subscribers = parent._subscribers; 8757 var length = _subscribers.length; 8758 8759 parent._onerror = null; 8760 8761 _subscribers[length] = child; 8762 _subscribers[length + FULFILLED] = onFulfillment; 8763 _subscribers[length + REJECTED] = onRejection; 8764 8765 if (length === 0 && parent._state) { 8766 asap(publish, parent); 8767 } 8768 } 8769 8770 function publish(promise) { 8771 var subscribers = promise._subscribers; 8772 var settled = promise._state; 8773 8774 if (subscribers.length === 0) { 8775 return; 8776 } 8777 8778 var child = undefined, 8779 callback = undefined, 8780 detail = promise._result; 8781 8782 for (var i = 0; i < subscribers.length; i += 3) { 8783 child = subscribers[i]; 8784 callback = subscribers[i + settled]; 8785 8786 if (child) { 8787 invokeCallback(settled, child, callback, detail); 8788 } else { 8789 callback(detail); 8790 } 8791 } 8792 8793 promise._subscribers.length = 0; 8794 } 8795 8796 function ErrorObject() { 8797 this.error = null; 8798 } 8799 8800 var TRY_CATCH_ERROR = new ErrorObject(); 8801 8802 function tryCatch(callback, detail) { 8803 try { 8804 return callback(detail); 8805 } catch (e) { 8806 TRY_CATCH_ERROR.error = e; 8807 return TRY_CATCH_ERROR; 8808 } 8809 } 8810 8811 function invokeCallback(settled, promise, callback, detail) { 8812 var hasCallback = isFunction(callback), 8813 value = undefined, 8814 error = undefined, 8815 succeeded = undefined, 8816 failed = undefined; 8817 8818 if (hasCallback) { 8819 value = tryCatch(callback, detail); 8820 8821 if (value === TRY_CATCH_ERROR) { 8822 failed = true; 8823 error = value.error; 8824 value = null; 8825 } else { 8826 succeeded = true; 8827 } 8828 8829 if (promise === value) { 8830 _reject(promise, cannotReturnOwn()); 8831 return; 8832 } 8833 } else { 8834 value = detail; 8835 succeeded = true; 8836 } 8837 8838 if (promise._state !== PENDING) { 8839 // noop 8840 } else if (hasCallback && succeeded) { 8841 _resolve(promise, value); 8842 } else if (failed) { 8843 _reject(promise, error); 8844 } else if (settled === FULFILLED) { 8845 fulfill(promise, value); 8846 } else if (settled === REJECTED) { 8847 _reject(promise, value); 8848 } 8849 } 8850 8851 function initializePromise(promise, resolver) { 8852 try { 8853 resolver(function resolvePromise(value) { 8854 _resolve(promise, value); 8855 }, function rejectPromise(reason) { 8856 _reject(promise, reason); 8857 }); 8858 } catch (e) { 8859 _reject(promise, e); 8860 } 8861 } 8862 8863 var id = 0; 8864 function nextId() { 8865 return id++; 8866 } 8867 8868 function makePromise(promise) { 8869 promise[PROMISE_ID] = id++; 8870 promise._state = undefined; 8871 promise._result = undefined; 8872 promise._subscribers = []; 8873 } 8874 8875 function Enumerator(Constructor, input) { 8876 this._instanceConstructor = Constructor; 8877 this.promise = new Constructor(noop); 8878 8879 if (!this.promise[PROMISE_ID]) { 8880 makePromise(this.promise); 8881 } 8882 8883 if (isArray(input)) { 8884 this._input = input; 8885 this.length = input.length; 8886 this._remaining = input.length; 8887 8888 this._result = new Array(this.length); 8889 8890 if (this.length === 0) { 8891 fulfill(this.promise, this._result); 8892 } else { 8893 this.length = this.length || 0; 8894 this._enumerate(); 8895 if (this._remaining === 0) { 8896 fulfill(this.promise, this._result); 8897 } 8898 } 8899 } else { 8900 _reject(this.promise, validationError()); 8901 } 8902 } 8903 8904 function validationError() { 8905 return new Error('Array Methods must be provided an Array'); 8906 }; 8907 8908 Enumerator.prototype._enumerate = function () { 8909 var length = this.length; 8910 var _input = this._input; 8911 8912 for (var i = 0; this._state === PENDING && i < length; i++) { 8913 this._eachEntry(_input[i], i); 8914 } 8915 }; 8916 8917 Enumerator.prototype._eachEntry = function (entry, i) { 8918 var c = this._instanceConstructor; 8919 var resolve$$ = c.resolve; 8920 8921 if (resolve$$ === resolve) { 8922 var _then = getThen(entry); 8923 8924 if (_then === then && entry._state !== PENDING) { 8925 this._settledAt(entry._state, i, entry._result); 8926 } else if (typeof _then !== 'function') { 8927 this._remaining--; 8928 this._result[i] = entry; 8929 } else if (c === Promise) { 8930 var promise = new c(noop); 8931 handleMaybeThenable(promise, entry, _then); 8932 this._willSettleAt(promise, i); 8933 } else { 8934 this._willSettleAt(new c(function (resolve$$) { 8935 return resolve$$(entry); 8936 }), i); 8937 } 8938 } else { 8939 this._willSettleAt(resolve$$(entry), i); 8940 } 8941 }; 8942 8943 Enumerator.prototype._settledAt = function (state, i, value) { 8944 var promise = this.promise; 8945 8946 if (promise._state === PENDING) { 8947 this._remaining--; 8948 8949 if (state === REJECTED) { 8950 _reject(promise, value); 8951 } else { 8952 this._result[i] = value; 8953 } 8954 } 8955 8956 if (this._remaining === 0) { 8957 fulfill(promise, this._result); 8958 } 8959 }; 8960 8961 Enumerator.prototype._willSettleAt = function (promise, i) { 8962 var enumerator = this; 8963 8964 subscribe(promise, undefined, function (value) { 8965 return enumerator._settledAt(FULFILLED, i, value); 8966 }, function (reason) { 8967 return enumerator._settledAt(REJECTED, i, reason); 8968 }); 8969 }; 8970 8971 /** 8972 `Promise.all` accepts an array of promises, and returns a new promise which 8973 is fulfilled with an array of fulfillment values for the passed promises, or 8974 rejected with the reason of the first passed promise to be rejected. It casts all 8975 elements of the passed iterable to promises as it runs this algorithm. 8976 8977 Example: 8978 8979 ```javascript 8980 let promise1 = resolve(1); 8981 let promise2 = resolve(2); 8982 let promise3 = resolve(3); 8983 let promises = [ promise1, promise2, promise3 ]; 8984 8985 Promise.all(promises).then(function(array){ 8986 // The array here would be [ 1, 2, 3 ]; 8987 }); 8988 ``` 8989 8990 If any of the `promises` given to `all` are rejected, the first promise 8991 that is rejected will be given as an argument to the returned promises's 8992 rejection handler. For example: 8993 8994 Example: 8995 8996 ```javascript 8997 let promise1 = resolve(1); 8998 let promise2 = reject(new Error("2")); 8999 let promise3 = reject(new Error("3")); 9000 let promises = [ promise1, promise2, promise3 ]; 9001 9002 Promise.all(promises).then(function(array){ 9003 // Code here never runs because there are rejected promises! 9004 }, function(error) { 9005 // error.message === "2" 9006 }); 9007 ``` 9008 9009 @method all 9010 @static 9011 @param {Array} entries array of promises 9012 @param {String} label optional string for labeling the promise. 9013 Useful for tooling. 9014 @return {Promise} promise that is fulfilled when all `promises` have been 9015 fulfilled, or rejected if any of them become rejected. 9016 @static 9017 */ 9018 function all(entries) { 9019 return new Enumerator(this, entries).promise; 9020 } 9021 9022 /** 9023 `Promise.race` returns a new promise which is settled in the same way as the 9024 first passed promise to settle. 9025 9026 Example: 9027 9028 ```javascript 9029 let promise1 = new Promise(function(resolve, reject){ 9030 setTimeout(function(){ 9031 resolve('promise 1'); 9032 }, 200); 9033 }); 9034 9035 let promise2 = new Promise(function(resolve, reject){ 9036 setTimeout(function(){ 9037 resolve('promise 2'); 9038 }, 100); 9039 }); 9040 9041 Promise.race([promise1, promise2]).then(function(result){ 9042 // result === 'promise 2' because it was resolved before promise1 9043 // was resolved. 9044 }); 9045 ``` 9046 9047 `Promise.race` is deterministic in that only the state of the first 9048 settled promise matters. For example, even if other promises given to the 9049 `promises` array argument are resolved, but the first settled promise has 9050 become rejected before the other promises became fulfilled, the returned 9051 promise will become rejected: 9052 9053 ```javascript 9054 let promise1 = new Promise(function(resolve, reject){ 9055 setTimeout(function(){ 9056 resolve('promise 1'); 9057 }, 200); 9058 }); 9059 9060 let promise2 = new Promise(function(resolve, reject){ 9061 setTimeout(function(){ 9062 reject(new Error('promise 2')); 9063 }, 100); 9064 }); 9065 9066 Promise.race([promise1, promise2]).then(function(result){ 9067 // Code here never runs 9068 }, function(reason){ 9069 // reason.message === 'promise 2' because promise 2 became rejected before 9070 // promise 1 became fulfilled 9071 }); 9072 ``` 9073 9074 An example real-world use case is implementing timeouts: 9075 9076 ```javascript 9077 Promise.race([ajax('foo.json'), timeout(5000)]) 9078 ``` 9079 9080 @method race 9081 @static 9082 @param {Array} promises array of promises to observe 9083 Useful for tooling. 9084 @return {Promise} a promise which settles in the same way as the first passed 9085 promise to settle. 9086 */ 9087 function race(entries) { 9088 /*jshint validthis:true */ 9089 var Constructor = this; 9090 9091 if (!isArray(entries)) { 9092 return new Constructor(function (_, reject) { 9093 return reject(new TypeError('You must pass an array to race.')); 9094 }); 9095 } else { 9096 return new Constructor(function (resolve, reject) { 9097 var length = entries.length; 9098 for (var i = 0; i < length; i++) { 9099 Constructor.resolve(entries[i]).then(resolve, reject); 9100 } 9101 }); 9102 } 9103 } 9104 9105 /** 9106 `Promise.reject` returns a promise rejected with the passed `reason`. 9107 It is shorthand for the following: 9108 9109 ```javascript 9110 let promise = new Promise(function(resolve, reject){ 9111 reject(new Error('WHOOPS')); 9112 }); 9113 9114 promise.then(function(value){ 9115 // Code here doesn't run because the promise is rejected! 9116 }, function(reason){ 9117 // reason.message === 'WHOOPS' 9118 }); 9119 ``` 9120 9121 Instead of writing the above, your code now simply becomes the following: 9122 9123 ```javascript 9124 let promise = Promise.reject(new Error('WHOOPS')); 9125 9126 promise.then(function(value){ 9127 // Code here doesn't run because the promise is rejected! 9128 }, function(reason){ 9129 // reason.message === 'WHOOPS' 9130 }); 9131 ``` 9132 9133 @method reject 9134 @static 9135 @param {Any} reason value that the returned promise will be rejected with. 9136 Useful for tooling. 9137 @return {Promise} a promise rejected with the given `reason`. 9138 */ 9139 function reject(reason) { 9140 /*jshint validthis:true */ 9141 var Constructor = this; 9142 var promise = new Constructor(noop); 9143 _reject(promise, reason); 9144 return promise; 9145 } 9146 9147 function needsResolver() { 9148 throw new TypeError('You must pass a resolver function as the first argument to the promise constructor'); 9149 } 9150 9151 function needsNew() { 9152 throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function."); 9153 } 9154 9155 /** 9156 Promise objects represent the eventual result of an asynchronous operation. The 9157 primary way of interacting with a promise is through its `then` method, which 9158 registers callbacks to receive either a promise's eventual value or the reason 9159 why the promise cannot be fulfilled. 9160 9161 Terminology 9162 ----------- 9163 9164 - `promise` is an object or function with a `then` method whose behavior conforms to this specification. 9165 - `thenable` is an object or function that defines a `then` method. 9166 - `value` is any legal JavaScript value (including undefined, a thenable, or a promise). 9167 - `exception` is a value that is thrown using the throw statement. 9168 - `reason` is a value that indicates why a promise was rejected. 9169 - `settled` the final resting state of a promise, fulfilled or rejected. 9170 9171 A promise can be in one of three states: pending, fulfilled, or rejected. 9172 9173 Promises that are fulfilled have a fulfillment value and are in the fulfilled 9174 state. Promises that are rejected have a rejection reason and are in the 9175 rejected state. A fulfillment value is never a thenable. 9176 9177 Promises can also be said to *resolve* a value. If this value is also a 9178 promise, then the original promise's settled state will match the value's 9179 settled state. So a promise that *resolves* a promise that rejects will 9180 itself reject, and a promise that *resolves* a promise that fulfills will 9181 itself fulfill. 9182 9183 9184 Basic Usage: 9185 ------------ 9186 9187 ```js 9188 let promise = new Promise(function(resolve, reject) { 9189 // on success 9190 resolve(value); 9191 9192 // on failure 9193 reject(reason); 9194 }); 9195 9196 promise.then(function(value) { 9197 // on fulfillment 9198 }, function(reason) { 9199 // on rejection 9200 }); 9201 ``` 9202 9203 Advanced Usage: 9204 --------------- 9205 9206 Promises shine when abstracting away asynchronous interactions such as 9207 `XMLHttpRequest`s. 9208 9209 ```js 9210 function getJSON(url) { 9211 return new Promise(function(resolve, reject){ 9212 let xhr = new XMLHttpRequest(); 9213 9214 xhr.open('GET', url); 9215 xhr.onreadystatechange = handler; 9216 xhr.responseType = 'json'; 9217 xhr.setRequestHeader('Accept', 'application/json'); 9218 xhr.send(); 9219 9220 function handler() { 9221 if (this.readyState === this.DONE) { 9222 if (this.status === 200) { 9223 resolve(this.response); 9224 } else { 9225 reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']')); 9226 } 9227 } 9228 }; 9229 }); 9230 } 9231 9232 getJSON('/posts.json').then(function(json) { 9233 // on fulfillment 9234 }, function(reason) { 9235 // on rejection 9236 }); 9237 ``` 9238 9239 Unlike callbacks, promises are great composable primitives. 9240 9241 ```js 9242 Promise.all([ 9243 getJSON('/posts'), 9244 getJSON('/comments') 9245 ]).then(function(values){ 9246 values[0] // => postsJSON 9247 values[1] // => commentsJSON 9248 9249 return values; 9250 }); 9251 ``` 9252 9253 @class Promise 9254 @param {function} resolver 9255 Useful for tooling. 9256 @constructor 9257 */ 9258 function Promise(resolver) { 9259 this[PROMISE_ID] = nextId(); 9260 this._result = this._state = undefined; 9261 this._subscribers = []; 9262 9263 if (noop !== resolver) { 9264 typeof resolver !== 'function' && needsResolver(); 9265 this instanceof Promise ? initializePromise(this, resolver) : needsNew(); 9266 } 9267 } 9268 9269 Promise.all = all; 9270 Promise.race = race; 9271 Promise.resolve = resolve; 9272 Promise.reject = reject; 9273 Promise._setScheduler = setScheduler; 9274 Promise._setAsap = setAsap; 9275 Promise._asap = asap; 9276 9277 Promise.prototype = { 9278 constructor: Promise, 9279 9280 /** 9281 The primary way of interacting with a promise is through its `then` method, 9282 which registers callbacks to receive either a promise's eventual value or the 9283 reason why the promise cannot be fulfilled. 9284 9285 ```js 9286 findUser().then(function(user){ 9287 // user is available 9288 }, function(reason){ 9289 // user is unavailable, and you are given the reason why 9290 }); 9291 ``` 9292 9293 Chaining 9294 -------- 9295 9296 The return value of `then` is itself a promise. This second, 'downstream' 9297 promise is resolved with the return value of the first promise's fulfillment 9298 or rejection handler, or rejected if the handler throws an exception. 9299 9300 ```js 9301 findUser().then(function (user) { 9302 return user.name; 9303 }, function (reason) { 9304 return 'default name'; 9305 }).then(function (userName) { 9306 // If `findUser` fulfilled, `userName` will be the user's name, otherwise it 9307 // will be `'default name'` 9308 }); 9309 9310 findUser().then(function (user) { 9311 throw new Error('Found user, but still unhappy'); 9312 }, function (reason) { 9313 throw new Error('`findUser` rejected and we're unhappy'); 9314 }).then(function (value) { 9315 // never reached 9316 }, function (reason) { 9317 // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. 9318 // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. 9319 }); 9320 ``` 9321 If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. 9322 9323 ```js 9324 findUser().then(function (user) { 9325 throw new PedagogicalException('Upstream error'); 9326 }).then(function (value) { 9327 // never reached 9328 }).then(function (value) { 9329 // never reached 9330 }, function (reason) { 9331 // The `PedgagocialException` is propagated all the way down to here 9332 }); 9333 ``` 9334 9335 Assimilation 9336 ------------ 9337 9338 Sometimes the value you want to propagate to a downstream promise can only be 9339 retrieved asynchronously. This can be achieved by returning a promise in the 9340 fulfillment or rejection handler. The downstream promise will then be pending 9341 until the returned promise is settled. This is called *assimilation*. 9342 9343 ```js 9344 findUser().then(function (user) { 9345 return findCommentsByAuthor(user); 9346 }).then(function (comments) { 9347 // The user's comments are now available 9348 }); 9349 ``` 9350 9351 If the assimliated promise rejects, then the downstream promise will also reject. 9352 9353 ```js 9354 findUser().then(function (user) { 9355 return findCommentsByAuthor(user); 9356 }).then(function (comments) { 9357 // If `findCommentsByAuthor` fulfills, we'll have the value here 9358 }, function (reason) { 9359 // If `findCommentsByAuthor` rejects, we'll have the reason here 9360 }); 9361 ``` 9362 9363 Simple Example 9364 -------------- 9365 9366 Synchronous Example 9367 9368 ```javascript 9369 let result; 9370 9371 try { 9372 result = findResult(); 9373 // success 9374 } catch(reason) { 9375 // failure 9376 } 9377 ``` 9378 9379 Errback Example 9380 9381 ```js 9382 findResult(function(result, err){ 9383 if (err) { 9384 // failure 9385 } else { 9386 // success 9387 } 9388 }); 9389 ``` 9390 9391 Promise Example; 9392 9393 ```javascript 9394 findResult().then(function(result){ 9395 // success 9396 }, function(reason){ 9397 // failure 9398 }); 9399 ``` 9400 9401 Advanced Example 9402 -------------- 9403 9404 Synchronous Example 9405 9406 ```javascript 9407 let author, books; 9408 9409 try { 9410 author = findAuthor(); 9411 books = findBooksByAuthor(author); 9412 // success 9413 } catch(reason) { 9414 // failure 9415 } 9416 ``` 9417 9418 Errback Example 9419 9420 ```js 9421 9422 function foundBooks(books) { 9423 9424 } 9425 9426 function failure(reason) { 9427 9428 } 9429 9430 findAuthor(function(author, err){ 9431 if (err) { 9432 failure(err); 9433 // failure 9434 } else { 9435 try { 9436 findBoooksByAuthor(author, function(books, err) { 9437 if (err) { 9438 failure(err); 9439 } else { 9440 try { 9441 foundBooks(books); 9442 } catch(reason) { 9443 failure(reason); 9444 } 9445 } 9446 }); 9447 } catch(error) { 9448 failure(err); 9449 } 9450 // success 9451 } 9452 }); 9453 ``` 9454 9455 Promise Example; 9456 9457 ```javascript 9458 findAuthor(). 9459 then(findBooksByAuthor). 9460 then(function(books){ 9461 // found books 9462 }).catch(function(reason){ 9463 // something went wrong 9464 }); 9465 ``` 9466 9467 @method then 9468 @param {Function} onFulfilled 9469 @param {Function} onRejected 9470 Useful for tooling. 9471 @return {Promise} 9472 */ 9473 then: then, 9474 9475 /** 9476 `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same 9477 as the catch block of a try/catch statement. 9478 9479 ```js 9480 function findAuthor(){ 9481 throw new Error('couldn't find that author'); 9482 } 9483 9484 // synchronous 9485 try { 9486 findAuthor(); 9487 } catch(reason) { 9488 // something went wrong 9489 } 9490 9491 // async with promises 9492 findAuthor().catch(function(reason){ 9493 // something went wrong 9494 }); 9495 ``` 9496 9497 @method catch 9498 @param {Function} onRejection 9499 Useful for tooling. 9500 @return {Promise} 9501 */ 9502 'catch': function _catch(onRejection) { 9503 return this.then(null, onRejection); 9504 } 9505 }; 9506 9507 function polyfill() { 9508 var local = undefined; 9509 9510 if (typeof global !== 'undefined') { 9511 local = global; 9512 } else if (typeof self !== 'undefined') { 9513 local = self; 9514 } else { 9515 try { 9516 local = Function('return this')(); 9517 } catch (e) { 9518 throw new Error('polyfill failed because global object is unavailable in this environment'); 9519 } 9520 } 9521 9522 var P = local.Promise; 9523 9524 if (P) { 9525 var promiseToString = null; 9526 try { 9527 promiseToString = Object.prototype.toString.call(P.resolve()); 9528 } catch (e) { 9529 // silently ignored 9530 } 9531 9532 if (promiseToString === '[object Promise]' && !P.cast) { 9533 return; 9534 } 9535 } 9536 9537 local.Promise = Promise; 9538 } 9539 9540 // Strange compat.. 9541 Promise.polyfill = polyfill; 9542 Promise.Promise = Promise; 9543 9544 return Promise; 9545 9546 }))); 9547 //# sourceMappingURL=es6-promise.map 9548 /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(11), __webpack_require__(3))) 9549 9550 /***/ }), 9551 /* 52 */ 9552 /***/ (function(module, exports, __webpack_require__) { 9553 9554 /* WEBPACK VAR INJECTION */(function(global) {if (typeof window !== "undefined") { 9555 module.exports = window; 9556 } else if (typeof global !== "undefined") { 9557 module.exports = global; 9558 } else if (typeof self !== "undefined"){ 9559 module.exports = self; 9560 } else { 9561 module.exports = {}; 9562 } 9563 9564 /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) 9565 9566 /***/ }), 9567 /* 53 */ 9568 /***/ (function(module, exports, __webpack_require__) { 9569 9570 /* 9571 * Copyright 2011 Twitter, Inc. 9572 * Licensed under the Apache License, Version 2.0 (the "License"); 9573 * you may not use this file except in compliance with the License. 9574 * You may obtain a copy of the License at 9575 * 9576 * http://www.apache.org/licenses/LICENSE-2.0 9577 * 9578 * Unless required by applicable law or agreed to in writing, software 9579 * distributed under the License is distributed on an "AS IS" BASIS, 9580 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9581 * See the License for the specific language governing permissions and 9582 * limitations under the License. 9583 */ 9584 9585 (function (Hogan) { 9586 // Setup regex assignments 9587 // remove whitespace according to Mustache spec 9588 var rIsWhitespace = /\S/, 9589 rQuot = /\"/g, 9590 rNewline = /\n/g, 9591 rCr = /\r/g, 9592 rSlash = /\\/g, 9593 rLineSep = /\u2028/, 9594 rParagraphSep = /\u2029/; 9595 9596 Hogan.tags = { 9597 '#': 1, '^': 2, '<': 3, '$': 4, 9598 '/': 5, '!': 6, '>': 7, '=': 8, '_v': 9, 9599 '{': 10, '&': 11, '_t': 12 9600 }; 9601 9602 Hogan.scan = function scan(text, delimiters) { 9603 var len = text.length, 9604 IN_TEXT = 0, 9605 IN_TAG_TYPE = 1, 9606 IN_TAG = 2, 9607 state = IN_TEXT, 9608 tagType = null, 9609 tag = null, 9610 buf = '', 9611 tokens = [], 9612 seenTag = false, 9613 i = 0, 9614 lineStart = 0, 9615 otag = '{{', 9616 ctag = '}}'; 9617 9618 function addBuf() { 9619 if (buf.length > 0) { 9620 tokens.push({tag: '_t', text: new String(buf)}); 9621 buf = ''; 9622 } 9623 } 9624 9625 function lineIsWhitespace() { 9626 var isAllWhitespace = true; 9627 for (var j = lineStart; j < tokens.length; j++) { 9628 isAllWhitespace = 9629 (Hogan.tags[tokens[j].tag] < Hogan.tags['_v']) || 9630 (tokens[j].tag == '_t' && tokens[j].text.match(rIsWhitespace) === null); 9631 if (!isAllWhitespace) { 9632 return false; 9633 } 9634 } 9635 9636 return isAllWhitespace; 9637 } 9638 9639 function filterLine(haveSeenTag, noNewLine) { 9640 addBuf(); 9641 9642 if (haveSeenTag && lineIsWhitespace()) { 9643 for (var j = lineStart, next; j < tokens.length; j++) { 9644 if (tokens[j].text) { 9645 if ((next = tokens[j+1]) && next.tag == '>') { 9646 // set indent to token value 9647 next.indent = tokens[j].text.toString() 9648 } 9649 tokens.splice(j, 1); 9650 } 9651 } 9652 } else if (!noNewLine) { 9653 tokens.push({tag:'\n'}); 9654 } 9655 9656 seenTag = false; 9657 lineStart = tokens.length; 9658 } 9659 9660 function changeDelimiters(text, index) { 9661 var close = '=' + ctag, 9662 closeIndex = text.indexOf(close, index), 9663 delimiters = trim( 9664 text.substring(text.indexOf('=', index) + 1, closeIndex) 9665 ).split(' '); 9666 9667 otag = delimiters[0]; 9668 ctag = delimiters[delimiters.length - 1]; 9669 9670 return closeIndex + close.length - 1; 9671 } 9672 9673 if (delimiters) { 9674 delimiters = delimiters.split(' '); 9675 otag = delimiters[0]; 9676 ctag = delimiters[1]; 9677 } 9678 9679 for (i = 0; i < len; i++) { 9680 if (state == IN_TEXT) { 9681 if (tagChange(otag, text, i)) { 9682 --i; 9683 addBuf(); 9684 state = IN_TAG_TYPE; 9685 } else { 9686 if (text.charAt(i) == '\n') { 9687 filterLine(seenTag); 9688 } else { 9689 buf += text.charAt(i); 9690 } 9691 } 9692 } else if (state == IN_TAG_TYPE) { 9693 i += otag.length - 1; 9694 tag = Hogan.tags[text.charAt(i + 1)]; 9695 tagType = tag ? text.charAt(i + 1) : '_v'; 9696 if (tagType == '=') { 9697 i = changeDelimiters(text, i); 9698 state = IN_TEXT; 9699 } else { 9700 if (tag) { 9701 i++; 9702 } 9703 state = IN_TAG; 9704 } 9705 seenTag = i; 9706 } else { 9707 if (tagChange(ctag, text, i)) { 9708 tokens.push({tag: tagType, n: trim(buf), otag: otag, ctag: ctag, 9709 i: (tagType == '/') ? seenTag - otag.length : i + ctag.length}); 9710 buf = ''; 9711 i += ctag.length - 1; 9712 state = IN_TEXT; 9713 if (tagType == '{') { 9714 if (ctag == '}}') { 9715 i++; 9716 } else { 9717 cleanTripleStache(tokens[tokens.length - 1]); 9718 } 9719 } 9720 } else { 9721 buf += text.charAt(i); 9722 } 9723 } 9724 } 9725 9726 filterLine(seenTag, true); 9727 9728 return tokens; 9729 } 9730 9731 function cleanTripleStache(token) { 9732 if (token.n.substr(token.n.length - 1) === '}') { 9733 token.n = token.n.substring(0, token.n.length - 1); 9734 } 9735 } 9736 9737 function trim(s) { 9738 if (s.trim) { 9739 return s.trim(); 9740 } 9741 9742 return s.replace(/^\s*|\s*$/g, ''); 9743 } 9744 9745 function tagChange(tag, text, index) { 9746 if (text.charAt(index) != tag.charAt(0)) { 9747 return false; 9748 } 9749 9750 for (var i = 1, l = tag.length; i < l; i++) { 9751 if (text.charAt(index + i) != tag.charAt(i)) { 9752 return false; 9753 } 9754 } 9755 9756 return true; 9757 } 9758 9759 // the tags allowed inside super templates 9760 var allowedInSuper = {'_t': true, '\n': true, '$': true, '/': true}; 9761 9762 function buildTree(tokens, kind, stack, customTags) { 9763 var instructions = [], 9764 opener = null, 9765 tail = null, 9766 token = null; 9767 9768 tail = stack[stack.length - 1]; 9769 9770 while (tokens.length > 0) { 9771 token = tokens.shift(); 9772 9773 if (tail && tail.tag == '<' && !(token.tag in allowedInSuper)) { 9774 throw new Error('Illegal content in < super tag.'); 9775 } 9776 9777 if (Hogan.tags[token.tag] <= Hogan.tags['$'] || isOpener(token, customTags)) { 9778 stack.push(token); 9779 token.nodes = buildTree(tokens, token.tag, stack, customTags); 9780 } else if (token.tag == '/') { 9781 if (stack.length === 0) { 9782 throw new Error('Closing tag without opener: /' + token.n); 9783 } 9784 opener = stack.pop(); 9785 if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) { 9786 throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n); 9787 } 9788 opener.end = token.i; 9789 return instructions; 9790 } else if (token.tag == '\n') { 9791 token.last = (tokens.length == 0) || (tokens[0].tag == '\n'); 9792 } 9793 9794 instructions.push(token); 9795 } 9796 9797 if (stack.length > 0) { 9798 throw new Error('missing closing tag: ' + stack.pop().n); 9799 } 9800 9801 return instructions; 9802 } 9803 9804 function isOpener(token, tags) { 9805 for (var i = 0, l = tags.length; i < l; i++) { 9806 if (tags[i].o == token.n) { 9807 token.tag = '#'; 9808 return true; 9809 } 9810 } 9811 } 9812 9813 function isCloser(close, open, tags) { 9814 for (var i = 0, l = tags.length; i < l; i++) { 9815 if (tags[i].c == close && tags[i].o == open) { 9816 return true; 9817 } 9818 } 9819 } 9820 9821 function stringifySubstitutions(obj) { 9822 var items = []; 9823 for (var key in obj) { 9824 items.push('"' + esc(key) + '": function(c,p,t,i) {' + obj[key] + '}'); 9825 } 9826 return "{ " + items.join(",") + " }"; 9827 } 9828 9829 function stringifyPartials(codeObj) { 9830 var partials = []; 9831 for (var key in codeObj.partials) { 9832 partials.push('"' + esc(key) + '":{name:"' + esc(codeObj.partials[key].name) + '", ' + stringifyPartials(codeObj.partials[key]) + "}"); 9833 } 9834 return "partials: {" + partials.join(",") + "}, subs: " + stringifySubstitutions(codeObj.subs); 9835 } 9836 9837 Hogan.stringify = function(codeObj, text, options) { 9838 return "{code: function (c,p,i) { " + Hogan.wrapMain(codeObj.code) + " }," + stringifyPartials(codeObj) + "}"; 9839 } 9840 9841 var serialNo = 0; 9842 Hogan.generate = function(tree, text, options) { 9843 serialNo = 0; 9844 var context = { code: '', subs: {}, partials: {} }; 9845 Hogan.walk(tree, context); 9846 9847 if (options.asString) { 9848 return this.stringify(context, text, options); 9849 } 9850 9851 return this.makeTemplate(context, text, options); 9852 } 9853 9854 Hogan.wrapMain = function(code) { 9855 return 'var t=this;t.b(i=i||"");' + code + 'return t.fl();'; 9856 } 9857 9858 Hogan.template = Hogan.Template; 9859 9860 Hogan.makeTemplate = function(codeObj, text, options) { 9861 var template = this.makePartials(codeObj); 9862 template.code = new Function('c', 'p', 'i', this.wrapMain(codeObj.code)); 9863 return new this.template(template, text, this, options); 9864 } 9865 9866 Hogan.makePartials = function(codeObj) { 9867 var key, template = {subs: {}, partials: codeObj.partials, name: codeObj.name}; 9868 for (key in template.partials) { 9869 template.partials[key] = this.makePartials(template.partials[key]); 9870 } 9871 for (key in codeObj.subs) { 9872 template.subs[key] = new Function('c', 'p', 't', 'i', codeObj.subs[key]); 9873 } 9874 return template; 9875 } 9876 9877 function esc(s) { 9878 return s.replace(rSlash, '\\\\') 9879 .replace(rQuot, '\\\"') 9880 .replace(rNewline, '\\n') 9881 .replace(rCr, '\\r') 9882 .replace(rLineSep, '\\u2028') 9883 .replace(rParagraphSep, '\\u2029'); 9884 } 9885 9886 function chooseMethod(s) { 9887 return (~s.indexOf('.')) ? 'd' : 'f'; 9888 } 9889 9890 function createPartial(node, context) { 9891 var prefix = "<" + (context.prefix || ""); 9892 var sym = prefix + node.n + serialNo++; 9893 context.partials[sym] = {name: node.n, partials: {}}; 9894 context.code += 't.b(t.rp("' + esc(sym) + '",c,p,"' + (node.indent || '') + '"));'; 9895 return sym; 9896 } 9897 9898 Hogan.codegen = { 9899 '#': function(node, context) { 9900 context.code += 'if(t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),' + 9901 'c,p,0,' + node.i + ',' + node.end + ',"' + node.otag + " " + node.ctag + '")){' + 9902 't.rs(c,p,' + 'function(c,p,t){'; 9903 Hogan.walk(node.nodes, context); 9904 context.code += '});c.pop();}'; 9905 }, 9906 9907 '^': function(node, context) { 9908 context.code += 'if(!t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),c,p,1,0,0,"")){'; 9909 Hogan.walk(node.nodes, context); 9910 context.code += '};'; 9911 }, 9912 9913 '>': createPartial, 9914 '<': function(node, context) { 9915 var ctx = {partials: {}, code: '', subs: {}, inPartial: true}; 9916 Hogan.walk(node.nodes, ctx); 9917 var template = context.partials[createPartial(node, context)]; 9918 template.subs = ctx.subs; 9919 template.partials = ctx.partials; 9920 }, 9921 9922 '$': function(node, context) { 9923 var ctx = {subs: {}, code: '', partials: context.partials, prefix: node.n}; 9924 Hogan.walk(node.nodes, ctx); 9925 context.subs[node.n] = ctx.code; 9926 if (!context.inPartial) { 9927 context.code += 't.sub("' + esc(node.n) + '",c,p,i);'; 9928 } 9929 }, 9930 9931 '\n': function(node, context) { 9932 context.code += write('"\\n"' + (node.last ? '' : ' + i')); 9933 }, 9934 9935 '_v': function(node, context) { 9936 context.code += 't.b(t.v(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));'; 9937 }, 9938 9939 '_t': function(node, context) { 9940 context.code += write('"' + esc(node.text) + '"'); 9941 }, 9942 9943 '{': tripleStache, 9944 9945 '&': tripleStache 9946 } 9947 9948 function tripleStache(node, context) { 9949 context.code += 't.b(t.t(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));'; 9950 } 9951 9952 function write(s) { 9953 return 't.b(' + s + ');'; 9954 } 9955 9956 Hogan.walk = function(nodelist, context) { 9957 var func; 9958 for (var i = 0, l = nodelist.length; i < l; i++) { 9959 func = Hogan.codegen[nodelist[i].tag]; 9960 func && func(nodelist[i], context); 9961 } 9962 return context; 9963 } 9964 9965 Hogan.parse = function(tokens, text, options) { 9966 options = options || {}; 9967 return buildTree(tokens, '', [], options.sectionTags || []); 9968 } 9969 9970 Hogan.cache = {}; 9971 9972 Hogan.cacheKey = function(text, options) { 9973 return [text, !!options.asString, !!options.disableLambda, options.delimiters, !!options.modelGet].join('||'); 9974 } 9975 9976 Hogan.compile = function(text, options) { 9977 options = options || {}; 9978 var key = Hogan.cacheKey(text, options); 9979 var template = this.cache[key]; 9980 9981 if (template) { 9982 var partials = template.partials; 9983 for (var name in partials) { 9984 delete partials[name].instance; 9985 } 9986 return template; 9987 } 9988 9989 template = this.generate(this.parse(this.scan(text, options.delimiters), text, options), text, options); 9990 return this.cache[key] = template; 9991 } 9992 })( true ? exports : Hogan); 9993 9994 9995 /***/ }), 9996 /* 54 */ 9997 /***/ (function(module, exports, __webpack_require__) { 9998 9999 /* 10000 * Copyright 2011 Twitter, Inc. 10001 * Licensed under the Apache License, Version 2.0 (the "License"); 10002 * you may not use this file except in compliance with the License. 10003 * You may obtain a copy of the License at 10004 * 10005 * http://www.apache.org/licenses/LICENSE-2.0 10006 * 10007 * Unless required by applicable law or agreed to in writing, software 10008 * distributed under the License is distributed on an "AS IS" BASIS, 10009 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10010 * See the License for the specific language governing permissions and 10011 * limitations under the License. 10012 */ 10013 10014 // This file is for use with Node.js. See dist/ for browser files. 10015 10016 var Hogan = __webpack_require__(53); 10017 Hogan.Template = __webpack_require__(55).Template; 10018 Hogan.template = Hogan.Template; 10019 module.exports = Hogan; 10020 10021 10022 /***/ }), 10023 /* 55 */ 10024 /***/ (function(module, exports, __webpack_require__) { 10025 10026 /* 10027 * Copyright 2011 Twitter, Inc. 10028 * Licensed under the Apache License, Version 2.0 (the "License"); 10029 * you may not use this file except in compliance with the License. 10030 * You may obtain a copy of the License at 10031 * 10032 * http://www.apache.org/licenses/LICENSE-2.0 10033 * 10034 * Unless required by applicable law or agreed to in writing, software 10035 * distributed under the License is distributed on an "AS IS" BASIS, 10036 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10037 * See the License for the specific language governing permissions and 10038 * limitations under the License. 10039 */ 10040 10041 var Hogan = {}; 10042 10043 (function (Hogan) { 10044 Hogan.Template = function (codeObj, text, compiler, options) { 10045 codeObj = codeObj || {}; 10046 this.r = codeObj.code || this.r; 10047 this.c = compiler; 10048 this.options = options || {}; 10049 this.text = text || ''; 10050 this.partials = codeObj.partials || {}; 10051 this.subs = codeObj.subs || {}; 10052 this.buf = ''; 10053 } 10054 10055 Hogan.Template.prototype = { 10056 // render: replaced by generated code. 10057 r: function (context, partials, indent) { return ''; }, 10058 10059 // variable escaping 10060 v: hoganEscape, 10061 10062 // triple stache 10063 t: coerceToString, 10064 10065 render: function render(context, partials, indent) { 10066 return this.ri([context], partials || {}, indent); 10067 }, 10068 10069 // render internal -- a hook for overrides that catches partials too 10070 ri: function (context, partials, indent) { 10071 return this.r(context, partials, indent); 10072 }, 10073 10074 // ensurePartial 10075 ep: function(symbol, partials) { 10076 var partial = this.partials[symbol]; 10077 10078 // check to see that if we've instantiated this partial before 10079 var template = partials[partial.name]; 10080 if (partial.instance && partial.base == template) { 10081 return partial.instance; 10082 } 10083 10084 if (typeof template == 'string') { 10085 if (!this.c) { 10086 throw new Error("No compiler available."); 10087 } 10088 template = this.c.compile(template, this.options); 10089 } 10090 10091 if (!template) { 10092 return null; 10093 } 10094 10095 // We use this to check whether the partials dictionary has changed 10096 this.partials[symbol].base = template; 10097 10098 if (partial.subs) { 10099 // Make sure we consider parent template now 10100 if (!partials.stackText) partials.stackText = {}; 10101 for (key in partial.subs) { 10102 if (!partials.stackText[key]) { 10103 partials.stackText[key] = (this.activeSub !== undefined && partials.stackText[this.activeSub]) ? partials.stackText[this.activeSub] : this.text; 10104 } 10105 } 10106 template = createSpecializedPartial(template, partial.subs, partial.partials, 10107 this.stackSubs, this.stackPartials, partials.stackText); 10108 } 10109 this.partials[symbol].instance = template; 10110 10111 return template; 10112 }, 10113 10114 // tries to find a partial in the current scope and render it 10115 rp: function(symbol, context, partials, indent) { 10116 var partial = this.ep(symbol, partials); 10117 if (!partial) { 10118 return ''; 10119 } 10120 10121 return partial.ri(context, partials, indent); 10122 }, 10123 10124 // render a section 10125 rs: function(context, partials, section) { 10126 var tail = context[context.length - 1]; 10127 10128 if (!isArray(tail)) { 10129 section(context, partials, this); 10130 return; 10131 } 10132 10133 for (var i = 0; i < tail.length; i++) { 10134 context.push(tail[i]); 10135 section(context, partials, this); 10136 context.pop(); 10137 } 10138 }, 10139 10140 // maybe start a section 10141 s: function(val, ctx, partials, inverted, start, end, tags) { 10142 var pass; 10143 10144 if (isArray(val) && val.length === 0) { 10145 return false; 10146 } 10147 10148 if (typeof val == 'function') { 10149 val = this.ms(val, ctx, partials, inverted, start, end, tags); 10150 } 10151 10152 pass = !!val; 10153 10154 if (!inverted && pass && ctx) { 10155 ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]); 10156 } 10157 10158 return pass; 10159 }, 10160 10161 // find values with dotted names 10162 d: function(key, ctx, partials, returnFound) { 10163 var found, 10164 names = key.split('.'), 10165 val = this.f(names[0], ctx, partials, returnFound), 10166 doModelGet = this.options.modelGet, 10167 cx = null; 10168 10169 if (key === '.' && isArray(ctx[ctx.length - 2])) { 10170 val = ctx[ctx.length - 1]; 10171 } else { 10172 for (var i = 1; i < names.length; i++) { 10173 found = findInScope(names[i], val, doModelGet); 10174 if (found !== undefined) { 10175 cx = val; 10176 val = found; 10177 } else { 10178 val = ''; 10179 } 10180 } 10181 } 10182 10183 if (returnFound && !val) { 10184 return false; 10185 } 10186 10187 if (!returnFound && typeof val == 'function') { 10188 ctx.push(cx); 10189 val = this.mv(val, ctx, partials); 10190 ctx.pop(); 10191 } 10192 10193 return val; 10194 }, 10195 10196 // find values with normal names 10197 f: function(key, ctx, partials, returnFound) { 10198 var val = false, 10199 v = null, 10200 found = false, 10201 doModelGet = this.options.modelGet; 10202 10203 for (var i = ctx.length - 1; i >= 0; i--) { 10204 v = ctx[i]; 10205 val = findInScope(key, v, doModelGet); 10206 if (val !== undefined) { 10207 found = true; 10208 break; 10209 } 10210 } 10211 10212 if (!found) { 10213 return (returnFound) ? false : ""; 10214 } 10215 10216 if (!returnFound && typeof val == 'function') { 10217 val = this.mv(val, ctx, partials); 10218 } 10219 10220 return val; 10221 }, 10222 10223 // higher order templates 10224 ls: function(func, cx, partials, text, tags) { 10225 var oldTags = this.options.delimiters; 10226 10227 this.options.delimiters = tags; 10228 this.b(this.ct(coerceToString(func.call(cx, text)), cx, partials)); 10229 this.options.delimiters = oldTags; 10230 10231 return false; 10232 }, 10233 10234 // compile text 10235 ct: function(text, cx, partials) { 10236 if (this.options.disableLambda) { 10237 throw new Error('Lambda features disabled.'); 10238 } 10239 return this.c.compile(text, this.options).render(cx, partials); 10240 }, 10241 10242 // template result buffering 10243 b: function(s) { this.buf += s; }, 10244 10245 fl: function() { var r = this.buf; this.buf = ''; return r; }, 10246 10247 // method replace section 10248 ms: function(func, ctx, partials, inverted, start, end, tags) { 10249 var textSource, 10250 cx = ctx[ctx.length - 1], 10251 result = func.call(cx); 10252 10253 if (typeof result == 'function') { 10254 if (inverted) { 10255 return true; 10256 } else { 10257 textSource = (this.activeSub && this.subsText && this.subsText[this.activeSub]) ? this.subsText[this.activeSub] : this.text; 10258 return this.ls(result, cx, partials, textSource.substring(start, end), tags); 10259 } 10260 } 10261 10262 return result; 10263 }, 10264 10265 // method replace variable 10266 mv: function(func, ctx, partials) { 10267 var cx = ctx[ctx.length - 1]; 10268 var result = func.call(cx); 10269 10270 if (typeof result == 'function') { 10271 return this.ct(coerceToString(result.call(cx)), cx, partials); 10272 } 10273 10274 return result; 10275 }, 10276 10277 sub: function(name, context, partials, indent) { 10278 var f = this.subs[name]; 10279 if (f) { 10280 this.activeSub = name; 10281 f(context, partials, this, indent); 10282 this.activeSub = false; 10283 } 10284 } 10285 10286 }; 10287 10288 //Find a key in an object 10289 function findInScope(key, scope, doModelGet) { 10290 var val; 10291 10292 if (scope && typeof scope == 'object') { 10293 10294 if (scope[key] !== undefined) { 10295 val = scope[key]; 10296 10297 // try lookup with get for backbone or similar model data 10298 } else if (doModelGet && scope.get && typeof scope.get == 'function') { 10299 val = scope.get(key); 10300 } 10301 } 10302 10303 return val; 10304 } 10305 10306 function createSpecializedPartial(instance, subs, partials, stackSubs, stackPartials, stackText) { 10307 function PartialTemplate() {}; 10308 PartialTemplate.prototype = instance; 10309 function Substitutions() {}; 10310 Substitutions.prototype = instance.subs; 10311 var key; 10312 var partial = new PartialTemplate(); 10313 partial.subs = new Substitutions(); 10314 partial.subsText = {}; //hehe. substext. 10315 partial.buf = ''; 10316 10317 stackSubs = stackSubs || {}; 10318 partial.stackSubs = stackSubs; 10319 partial.subsText = stackText; 10320 for (key in subs) { 10321 if (!stackSubs[key]) stackSubs[key] = subs[key]; 10322 } 10323 for (key in stackSubs) { 10324 partial.subs[key] = stackSubs[key]; 10325 } 10326 10327 stackPartials = stackPartials || {}; 10328 partial.stackPartials = stackPartials; 10329 for (key in partials) { 10330 if (!stackPartials[key]) stackPartials[key] = partials[key]; 10331 } 10332 for (key in stackPartials) { 10333 partial.partials[key] = stackPartials[key]; 10334 } 10335 10336 return partial; 10337 } 10338 10339 var rAmp = /&/g, 10340 rLt = /</g, 10341 rGt = />/g, 10342 rApos = /\'/g, 10343 rQuot = /\"/g, 10344 hChars = /[&<>\"\']/; 10345 10346 function coerceToString(val) { 10347 return String((val === null || val === undefined) ? '' : val); 10348 } 10349 10350 function hoganEscape(str) { 10351 str = coerceToString(str); 10352 return hChars.test(str) ? 10353 str 10354 .replace(rAmp, '&') 10355 .replace(rLt, '<') 10356 .replace(rGt, '>') 10357 .replace(rApos, ''') 10358 .replace(rQuot, '"') : 10359 str; 10360 } 10361 10362 var isArray = Array.isArray || function(a) { 10363 return Object.prototype.toString.call(a) === '[object Array]'; 10364 }; 10365 10366 })( true ? exports : Hogan); 10367 10368 10369 /***/ }), 10370 /* 56 */ 10371 /***/ (function(module, exports, __webpack_require__) { 10372 10373 "use strict"; 10374 10375 var types = [ 10376 __webpack_require__(59), 10377 __webpack_require__(58), 10378 __webpack_require__(57), 10379 __webpack_require__(60), 10380 __webpack_require__(61) 10381 ]; 10382 var draining; 10383 var currentQueue; 10384 var queueIndex = -1; 10385 var queue = []; 10386 var scheduled = false; 10387 function cleanUpNextTick() { 10388 if (!draining || !currentQueue) { 10389 return; 10390 } 10391 draining = false; 10392 if (currentQueue.length) { 10393 queue = currentQueue.concat(queue); 10394 } else { 10395 queueIndex = -1; 10396 } 10397 if (queue.length) { 10398 nextTick(); 10399 } 10400 } 10401 10402 //named nextTick for less confusing stack traces 10403 function nextTick() { 10404 if (draining) { 10405 return; 10406 } 10407 scheduled = false; 10408 draining = true; 10409 var len = queue.length; 10410 var timeout = setTimeout(cleanUpNextTick); 10411 while (len) { 10412 currentQueue = queue; 10413 queue = []; 10414 while (currentQueue && ++queueIndex < len) { 10415 currentQueue[queueIndex].run(); 10416 } 10417 queueIndex = -1; 10418 len = queue.length; 10419 } 10420 currentQueue = null; 10421 queueIndex = -1; 10422 draining = false; 10423 clearTimeout(timeout); 10424 } 10425 var scheduleDrain; 10426 var i = -1; 10427 var len = types.length; 10428 while (++i < len) { 10429 if (types[i] && types[i].test && types[i].test()) { 10430 scheduleDrain = types[i].install(nextTick); 10431 break; 10432 } 10433 } 10434 // v8 likes predictable objects 10435 function Item(fun, array) { 10436 this.fun = fun; 10437 this.array = array; 10438 } 10439 Item.prototype.run = function () { 10440 var fun = this.fun; 10441 var array = this.array; 10442 switch (array.length) { 10443 case 0: 10444 return fun(); 10445 case 1: 10446 return fun(array[0]); 10447 case 2: 10448 return fun(array[0], array[1]); 10449 case 3: 10450 return fun(array[0], array[1], array[2]); 10451 default: 10452 return fun.apply(null, array); 10453 } 10454 10455 }; 10456 module.exports = immediate; 10457 function immediate(task) { 10458 var args = new Array(arguments.length - 1); 10459 if (arguments.length > 1) { 10460 for (var i = 1; i < arguments.length; i++) { 10461 args[i - 1] = arguments[i]; 10462 } 10463 } 10464 queue.push(new Item(task, args)); 10465 if (!scheduled && !draining) { 10466 scheduled = true; 10467 scheduleDrain(); 10468 } 10469 } 10470 10471 10472 /***/ }), 10473 /* 57 */ 10474 /***/ (function(module, exports, __webpack_require__) { 10475 10476 "use strict"; 10477 /* WEBPACK VAR INJECTION */(function(global) { 10478 10479 exports.test = function () { 10480 if (global.setImmediate) { 10481 // we can only get here in IE10 10482 // which doesn't handel postMessage well 10483 return false; 10484 } 10485 return typeof global.MessageChannel !== 'undefined'; 10486 }; 10487 10488 exports.install = function (func) { 10489 var channel = new global.MessageChannel(); 10490 channel.port1.onmessage = func; 10491 return function () { 10492 channel.port2.postMessage(0); 10493 }; 10494 }; 10495 /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) 10496 10497 /***/ }), 10498 /* 58 */ 10499 /***/ (function(module, exports, __webpack_require__) { 10500 10501 "use strict"; 10502 /* WEBPACK VAR INJECTION */(function(global) { 10503 //based off rsvp https://github.com/tildeio/rsvp.js 10504 //license https://github.com/tildeio/rsvp.js/blob/master/LICENSE 10505 //https://github.com/tildeio/rsvp.js/blob/master/lib/rsvp/asap.js 10506 10507 var Mutation = global.MutationObserver || global.WebKitMutationObserver; 10508 10509 exports.test = function () { 10510 return Mutation; 10511 }; 10512 10513 exports.install = function (handle) { 10514 var called = 0; 10515 var observer = new Mutation(handle); 10516 var element = global.document.createTextNode(''); 10517 observer.observe(element, { 10518 characterData: true 10519 }); 10520 return function () { 10521 element.data = (called = ++called % 2); 10522 }; 10523 }; 10524 /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) 10525 10526 /***/ }), 10527 /* 59 */ 10528 /***/ (function(module, exports, __webpack_require__) { 10529 10530 "use strict"; 10531 /* WEBPACK VAR INJECTION */(function(process) { 10532 exports.test = function () { 10533 // Don't get fooled by e.g. browserify environments. 10534 return (typeof process !== 'undefined') && !process.browser; 10535 }; 10536 10537 exports.install = function (func) { 10538 return function () { 10539 process.nextTick(func); 10540 }; 10541 }; 10542 10543 /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(11))) 10544 10545 /***/ }), 10546 /* 60 */ 10547 /***/ (function(module, exports, __webpack_require__) { 10548 10549 "use strict"; 10550 /* WEBPACK VAR INJECTION */(function(global) { 10551 10552 exports.test = function () { 10553 return 'document' in global && 'onreadystatechange' in global.document.createElement('script'); 10554 }; 10555 10556 exports.install = function (handle) { 10557 return function () { 10558 10559 // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted 10560 // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called. 10561 var scriptEl = global.document.createElement('script'); 10562 scriptEl.onreadystatechange = function () { 10563 handle(); 10564 10565 scriptEl.onreadystatechange = null; 10566 scriptEl.parentNode.removeChild(scriptEl); 10567 scriptEl = null; 10568 }; 10569 global.document.documentElement.appendChild(scriptEl); 10570 10571 return handle; 10572 }; 10573 }; 10574 /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(3))) 10575 10576 /***/ }), 10577 /* 61 */ 10578 /***/ (function(module, exports, __webpack_require__) { 10579 10580 "use strict"; 10581 10582 exports.test = function () { 10583 return true; 10584 }; 10585 10586 exports.install = function (t) { 10587 return function () { 10588 setTimeout(t, 0); 10589 }; 10590 }; 10591 10592 /***/ }), 10593 /* 62 */ 10594 /***/ (function(module, exports) { 10595 10596 /** 10597 * Helpers. 10598 */ 10599 10600 var s = 1000 10601 var m = s * 60 10602 var h = m * 60 10603 var d = h * 24 10604 var y = d * 365.25 10605 10606 /** 10607 * Parse or format the given `val`. 10608 * 10609 * Options: 10610 * 10611 * - `long` verbose formatting [false] 10612 * 10613 * @param {String|Number} val 10614 * @param {Object} options 10615 * @throws {Error} throw an error if val is not a non-empty string or a number 10616 * @return {String|Number} 10617 * @api public 10618 */ 10619 10620 module.exports = function (val, options) { 10621 options = options || {} 10622 var type = typeof val 10623 if (type === 'string' && val.length > 0) { 10624 return parse(val) 10625 } else if (type === 'number' && isNaN(val) === false) { 10626 return options.long ? 10627 fmtLong(val) : 10628 fmtShort(val) 10629 } 10630 throw new Error('val is not a non-empty string or a valid number. val=' + JSON.stringify(val)) 10631 } 10632 10633 /** 10634 * Parse the given `str` and return milliseconds. 10635 * 10636 * @param {String} str 10637 * @return {Number} 10638 * @api private 10639 */ 10640 10641 function parse(str) { 10642 str = String(str) 10643 if (str.length > 10000) { 10644 return 10645 } 10646 var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str) 10647 if (!match) { 10648 return 10649 } 10650 var n = parseFloat(match[1]) 10651 var type = (match[2] || 'ms').toLowerCase() 10652 switch (type) { 10653 case 'years': 10654 case 'year': 10655 case 'yrs': 10656 case 'yr': 10657 case 'y': 10658 return n * y 10659 case 'days': 10660 case 'day': 10661 case 'd': 10662 return n * d 10663 case 'hours': 10664 case 'hour': 10665 case 'hrs': 10666 case 'hr': 10667 case 'h': 10668 return n * h 10669 case 'minutes': 10670 case 'minute': 10671 case 'mins': 10672 case 'min': 10673 case 'm': 10674 return n * m 10675 case 'seconds': 10676 case 'second': 10677 case 'secs': 10678 case 'sec': 10679 case 's': 10680 return n * s 10681 case 'milliseconds': 10682 case 'millisecond': 10683 case 'msecs': 10684 case 'msec': 10685 case 'ms': 10686 return n 10687 default: 10688 return undefined 10689 } 10690 } 10691 10692 /** 10693 * Short format for `ms`. 10694 * 10695 * @param {Number} ms 10696 * @return {String} 10697 * @api private 10698 */ 10699 10700 function fmtShort(ms) { 10701 if (ms >= d) { 10702 return Math.round(ms / d) + 'd' 10703 } 10704 if (ms >= h) { 10705 return Math.round(ms / h) + 'h' 10706 } 10707 if (ms >= m) { 10708 return Math.round(ms / m) + 'm' 10709 } 10710 if (ms >= s) { 10711 return Math.round(ms / s) + 's' 10712 } 10713 return ms + 'ms' 10714 } 10715 10716 /** 10717 * Long format for `ms`. 10718 * 10719 * @param {Number} ms 10720 * @return {String} 10721 * @api private 10722 */ 10723 10724 function fmtLong(ms) { 10725 return plural(ms, d, 'day') || 10726 plural(ms, h, 'hour') || 10727 plural(ms, m, 'minute') || 10728 plural(ms, s, 'second') || 10729 ms + ' ms' 10730 } 10731 10732 /** 10733 * Pluralization helper. 10734 */ 10735 10736 function plural(ms, n, name) { 10737 if (ms < n) { 10738 return 10739 } 10740 if (ms < n * 1.5) { 10741 return Math.floor(ms / n) + ' ' + name 10742 } 10743 return Math.ceil(ms / n) + ' ' + name + 's' 10744 } 10745 10746 10747 /***/ }), 10748 /* 63 */ 10749 /***/ (function(module, exports, __webpack_require__) { 10750 10751 "use strict"; 10752 10753 10754 // modified from https://github.com/es-shims/es5-shim 10755 var has = Object.prototype.hasOwnProperty; 10756 var toStr = Object.prototype.toString; 10757 var slice = Array.prototype.slice; 10758 var isArgs = __webpack_require__(64); 10759 var isEnumerable = Object.prototype.propertyIsEnumerable; 10760 var hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString'); 10761 var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype'); 10762 var dontEnums = [ 10763 'toString', 10764 'toLocaleString', 10765 'valueOf', 10766 'hasOwnProperty', 10767 'isPrototypeOf', 10768 'propertyIsEnumerable', 10769 'constructor' 10770 ]; 10771 var equalsConstructorPrototype = function (o) { 10772 var ctor = o.constructor; 10773 return ctor && ctor.prototype === o; 10774 }; 10775 var excludedKeys = { 10776 $console: true, 10777 $external: true, 10778 $frame: true, 10779 $frameElement: true, 10780 $frames: true, 10781 $innerHeight: true, 10782 $innerWidth: true, 10783 $outerHeight: true, 10784 $outerWidth: true, 10785 $pageXOffset: true, 10786 $pageYOffset: true, 10787 $parent: true, 10788 $scrollLeft: true, 10789 $scrollTop: true, 10790 $scrollX: true, 10791 $scrollY: true, 10792 $self: true, 10793 $webkitIndexedDB: true, 10794 $webkitStorageInfo: true, 10795 $window: true 10796 }; 10797 var hasAutomationEqualityBug = (function () { 10798 /* global window */ 10799 if (typeof window === 'undefined') { return false; } 10800 for (var k in window) { 10801 try { 10802 if (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') { 10803 try { 10804 equalsConstructorPrototype(window[k]); 10805 } catch (e) { 10806 return true; 10807 } 10808 } 10809 } catch (e) { 10810 return true; 10811 } 10812 } 10813 return false; 10814 }()); 10815 var equalsConstructorPrototypeIfNotBuggy = function (o) { 10816 /* global window */ 10817 if (typeof window === 'undefined' || !hasAutomationEqualityBug) { 10818 return equalsConstructorPrototype(o); 10819 } 10820 try { 10821 return equalsConstructorPrototype(o); 10822 } catch (e) { 10823 return false; 10824 } 10825 }; 10826 10827 var keysShim = function keys(object) { 10828 var isObject = object !== null && typeof object === 'object'; 10829 var isFunction = toStr.call(object) === '[object Function]'; 10830 var isArguments = isArgs(object); 10831 var isString = isObject && toStr.call(object) === '[object String]'; 10832 var theKeys = []; 10833 10834 if (!isObject && !isFunction && !isArguments) { 10835 throw new TypeError('Object.keys called on a non-object'); 10836 } 10837 10838 var skipProto = hasProtoEnumBug && isFunction; 10839 if (isString && object.length > 0 && !has.call(object, 0)) { 10840 for (var i = 0; i < object.length; ++i) { 10841 theKeys.push(String(i)); 10842 } 10843 } 10844 10845 if (isArguments && object.length > 0) { 10846 for (var j = 0; j < object.length; ++j) { 10847 theKeys.push(String(j)); 10848 } 10849 } else { 10850 for (var name in object) { 10851 if (!(skipProto && name === 'prototype') && has.call(object, name)) { 10852 theKeys.push(String(name)); 10853 } 10854 } 10855 } 10856 10857 if (hasDontEnumBug) { 10858 var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object); 10859 10860 for (var k = 0; k < dontEnums.length; ++k) { 10861 if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) { 10862 theKeys.push(dontEnums[k]); 10863 } 10864 } 10865 } 10866 return theKeys; 10867 }; 10868 10869 keysShim.shim = function shimObjectKeys() { 10870 if (Object.keys) { 10871 var keysWorksWithArguments = (function () { 10872 // Safari 5.0 bug 10873 return (Object.keys(arguments) || '').length === 2; 10874 }(1, 2)); 10875 if (!keysWorksWithArguments) { 10876 var originalKeys = Object.keys; 10877 Object.keys = function keys(object) { 10878 if (isArgs(object)) { 10879 return originalKeys(slice.call(object)); 10880 } else { 10881 return originalKeys(object); 10882 } 10883 }; 10884 } 10885 } else { 10886 Object.keys = keysShim; 10887 } 10888 return Object.keys || keysShim; 10889 }; 10890 10891 module.exports = keysShim; 10892 10893 10894 /***/ }), 10895 /* 64 */ 10896 /***/ (function(module, exports, __webpack_require__) { 10897 10898 "use strict"; 10899 10900 10901 var toStr = Object.prototype.toString; 10902 10903 module.exports = function isArguments(value) { 10904 var str = toStr.call(value); 10905 var isArgs = str === '[object Arguments]'; 10906 if (!isArgs) { 10907 isArgs = str !== '[object Array]' && 10908 value !== null && 10909 typeof value === 'object' && 10910 typeof value.length === 'number' && 10911 value.length >= 0 && 10912 toStr.call(value.callee) === '[object Function]'; 10913 } 10914 return isArgs; 10915 }; 10916 10917 10918 /***/ }), 10919 /* 65 */ 10920 /***/ (function(module, exports, __webpack_require__) { 10921 10922 "use strict"; 10923 // Copyright Joyent, Inc. and other Node contributors. 10924 // 10925 // Permission is hereby granted, free of charge, to any person obtaining a 10926 // copy of this software and associated documentation files (the 10927 // "Software"), to deal in the Software without restriction, including 10928 // without limitation the rights to use, copy, modify, merge, publish, 10929 // distribute, sublicense, and/or sell copies of the Software, and to permit 10930 // persons to whom the Software is furnished to do so, subject to the 10931 // following conditions: 10932 // 10933 // The above copyright notice and this permission notice shall be included 10934 // in all copies or substantial portions of the Software. 10935 // 10936 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 10937 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 10938 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 10939 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 10940 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 10941 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 10942 // USE OR OTHER DEALINGS IN THE SOFTWARE. 10943 10944 10945 10946 var stringifyPrimitive = function(v) { 10947 switch (typeof v) { 10948 case 'string': 10949 return v; 10950 10951 case 'boolean': 10952 return v ? 'true' : 'false'; 10953 10954 case 'number': 10955 return isFinite(v) ? v : ''; 10956 10957 default: 10958 return ''; 10959 } 10960 }; 10961 10962 module.exports = function(obj, sep, eq, name) { 10963 sep = sep || '&'; 10964 eq = eq || '='; 10965 if (obj === null) { 10966 obj = undefined; 10967 } 10968 10969 if (typeof obj === 'object') { 10970 return map(objectKeys(obj), function(k) { 10971 var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; 10972 if (isArray(obj[k])) { 10973 return map(obj[k], function(v) { 10974 return ks + encodeURIComponent(stringifyPrimitive(v)); 10975 }).join(sep); 10976 } else { 10977 return ks + encodeURIComponent(stringifyPrimitive(obj[k])); 10978 } 10979 }).join(sep); 10980 10981 } 10982 10983 if (!name) return ''; 10984 return encodeURIComponent(stringifyPrimitive(name)) + eq + 10985 encodeURIComponent(stringifyPrimitive(obj)); 10986 }; 10987 10988 var isArray = Array.isArray || function (xs) { 10989 return Object.prototype.toString.call(xs) === '[object Array]'; 10990 }; 10991 10992 function map (xs, f) { 10993 if (xs.map) return xs.map(f); 10994 var res = []; 10995 for (var i = 0; i < xs.length; i++) { 10996 res.push(f(xs[i], i)); 10997 } 10998 return res; 10999 } 11000 11001 var objectKeys = Object.keys || function (obj) { 11002 var res = []; 11003 for (var key in obj) { 11004 if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key); 11005 } 11006 return res; 11007 }; 11008 11009 11010 /***/ }), 11011 /* 66 */ 11012 /***/ (function(module, exports, __webpack_require__) { 11013 11014 "use strict"; 11015 11016 11017 var _bind = Function.prototype.bind; 11018 function toFactory(Class) { 11019 var Factory = function Factory() { 11020 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { 11021 args[_key] = arguments[_key]; 11022 } 11023 11024 return new (_bind.apply(Class, [null].concat(args)))(); 11025 }; 11026 Factory.__proto__ = Class; 11027 Factory.prototype = Class.prototype; 11028 return Factory; 11029 } 11030 11031 module.exports = toFactory; 11032 11033 11034 11035 /***/ }), 11036 /* 67 */ 11037 /***/ (function(module, exports) { 11038 11039 /* (ignored) */ 11040 11041 /***/ }) 11042 /******/ ]); 11043 }); 11044 //# sourceMappingURL=docsearch.js.map 11045 11046 /***/ }), 11047 /* 14 */ 11048 /***/ (function(module, exports) { 11049 11050 (function(window, factory) { 11051 var lazySizes = factory(window, window.document); 11052 window.lazySizes = lazySizes; 11053 if(typeof module == 'object' && module.exports){ 11054 module.exports = lazySizes; 11055 } 11056 }(window, function l(window, document) { 11057 'use strict'; 11058 /*jshint eqnull:true */ 11059 if(!document.getElementsByClassName){return;} 11060 11061 var lazySizesConfig; 11062 11063 var docElem = document.documentElement; 11064 11065 var Date = window.Date; 11066 11067 var supportPicture = window.HTMLPictureElement; 11068 11069 var _addEventListener = 'addEventListener'; 11070 11071 var _getAttribute = 'getAttribute'; 11072 11073 var addEventListener = window[_addEventListener]; 11074 11075 var setTimeout = window.setTimeout; 11076 11077 var requestAnimationFrame = window.requestAnimationFrame || setTimeout; 11078 11079 var requestIdleCallback = window.requestIdleCallback; 11080 11081 var regPicture = /^picture$/i; 11082 11083 var loadEvents = ['load', 'error', 'lazyincluded', '_lazyloaded']; 11084 11085 var regClassCache = {}; 11086 11087 var forEach = Array.prototype.forEach; 11088 11089 var hasClass = function(ele, cls) { 11090 if(!regClassCache[cls]){ 11091 regClassCache[cls] = new RegExp('(\\s|^)'+cls+'(\\s|$)'); 11092 } 11093 return regClassCache[cls].test(ele[_getAttribute]('class') || '') && regClassCache[cls]; 11094 }; 11095 11096 var addClass = function(ele, cls) { 11097 if (!hasClass(ele, cls)){ 11098 ele.setAttribute('class', (ele[_getAttribute]('class') || '').trim() + ' ' + cls); 11099 } 11100 }; 11101 11102 var removeClass = function(ele, cls) { 11103 var reg; 11104 if ((reg = hasClass(ele,cls))) { 11105 ele.setAttribute('class', (ele[_getAttribute]('class') || '').replace(reg, ' ')); 11106 } 11107 }; 11108 11109 var addRemoveLoadEvents = function(dom, fn, add){ 11110 var action = add ? _addEventListener : 'removeEventListener'; 11111 if(add){ 11112 addRemoveLoadEvents(dom, fn); 11113 } 11114 loadEvents.forEach(function(evt){ 11115 dom[action](evt, fn); 11116 }); 11117 }; 11118 11119 var triggerEvent = function(elem, name, detail, noBubbles, noCancelable){ 11120 var event = document.createEvent('CustomEvent'); 11121 11122 event.initCustomEvent(name, !noBubbles, !noCancelable, detail || {}); 11123 11124 elem.dispatchEvent(event); 11125 return event; 11126 }; 11127 11128 var updatePolyfill = function (el, full){ 11129 var polyfill; 11130 if( !supportPicture && ( polyfill = (window.picturefill || lazySizesConfig.pf) ) ){ 11131 polyfill({reevaluate: true, elements: [el]}); 11132 } else if(full && full.src){ 11133 el.src = full.src; 11134 } 11135 }; 11136 11137 var getCSS = function (elem, style){ 11138 return (getComputedStyle(elem, null) || {})[style]; 11139 }; 11140 11141 var getWidth = function(elem, parent, width){ 11142 width = width || elem.offsetWidth; 11143 11144 while(width < lazySizesConfig.minSize && parent && !elem._lazysizesWidth){ 11145 width = parent.offsetWidth; 11146 parent = parent.parentNode; 11147 } 11148 11149 return width; 11150 }; 11151 11152 var rAF = (function(){ 11153 var running, waiting; 11154 var firstFns = []; 11155 var secondFns = []; 11156 var fns = firstFns; 11157 11158 var run = function(){ 11159 var runFns = fns; 11160 11161 fns = firstFns.length ? secondFns : firstFns; 11162 11163 running = true; 11164 waiting = false; 11165 11166 while(runFns.length){ 11167 runFns.shift()(); 11168 } 11169 11170 running = false; 11171 }; 11172 11173 var rafBatch = function(fn, queue){ 11174 if(running && !queue){ 11175 fn.apply(this, arguments); 11176 } else { 11177 fns.push(fn); 11178 11179 if(!waiting){ 11180 waiting = true; 11181 (document.hidden ? setTimeout : requestAnimationFrame)(run); 11182 } 11183 } 11184 }; 11185 11186 rafBatch._lsFlush = run; 11187 11188 return rafBatch; 11189 })(); 11190 11191 var rAFIt = function(fn, simple){ 11192 return simple ? 11193 function() { 11194 rAF(fn); 11195 } : 11196 function(){ 11197 var that = this; 11198 var args = arguments; 11199 rAF(function(){ 11200 fn.apply(that, args); 11201 }); 11202 } 11203 ; 11204 }; 11205 11206 var throttle = function(fn){ 11207 var running; 11208 var lastTime = 0; 11209 var gDelay = 125; 11210 var RIC_DEFAULT_TIMEOUT = 666; 11211 var rICTimeout = RIC_DEFAULT_TIMEOUT; 11212 var run = function(){ 11213 running = false; 11214 lastTime = Date.now(); 11215 fn(); 11216 }; 11217 var idleCallback = requestIdleCallback ? 11218 function(){ 11219 requestIdleCallback(run, {timeout: rICTimeout}); 11220 if(rICTimeout !== RIC_DEFAULT_TIMEOUT){ 11221 rICTimeout = RIC_DEFAULT_TIMEOUT; 11222 } 11223 }: 11224 rAFIt(function(){ 11225 setTimeout(run); 11226 }, true) 11227 ; 11228 11229 return function(isPriority){ 11230 var delay; 11231 if((isPriority = isPriority === true)){ 11232 rICTimeout = 44; 11233 } 11234 11235 if(running){ 11236 return; 11237 } 11238 11239 running = true; 11240 11241 delay = gDelay - (Date.now() - lastTime); 11242 11243 if(delay < 0){ 11244 delay = 0; 11245 } 11246 11247 if(isPriority || (delay < 9 && requestIdleCallback)){ 11248 idleCallback(); 11249 } else { 11250 setTimeout(idleCallback, delay); 11251 } 11252 }; 11253 }; 11254 11255 //based on http://modernjavascript.blogspot.de/2013/08/building-better-debounce.html 11256 var debounce = function(func) { 11257 var timeout, timestamp; 11258 var wait = 99; 11259 var run = function(){ 11260 timeout = null; 11261 func(); 11262 }; 11263 var later = function() { 11264 var last = Date.now() - timestamp; 11265 11266 if (last < wait) { 11267 setTimeout(later, wait - last); 11268 } else { 11269 (requestIdleCallback || run)(run); 11270 } 11271 }; 11272 11273 return function() { 11274 timestamp = Date.now(); 11275 11276 if (!timeout) { 11277 timeout = setTimeout(later, wait); 11278 } 11279 }; 11280 }; 11281 11282 11283 var loader = (function(){ 11284 var lazyloadElems, preloadElems, isCompleted, resetPreloadingTimer, loadMode, started; 11285 11286 var eLvW, elvH, eLtop, eLleft, eLright, eLbottom; 11287 11288 var defaultExpand, preloadExpand, hFac; 11289 11290 var regImg = /^img$/i; 11291 var regIframe = /^iframe$/i; 11292 11293 var supportScroll = ('onscroll' in window) && !(/glebot/.test(navigator.userAgent)); 11294 11295 var shrinkExpand = 0; 11296 var currentExpand = 0; 11297 11298 var isLoading = 0; 11299 var lowRuns = -1; 11300 11301 var resetPreloading = function(e){ 11302 isLoading--; 11303 if(e && e.target){ 11304 addRemoveLoadEvents(e.target, resetPreloading); 11305 } 11306 11307 if(!e || isLoading < 0 || !e.target){ 11308 isLoading = 0; 11309 } 11310 }; 11311 11312 var isNestedVisible = function(elem, elemExpand){ 11313 var outerRect; 11314 var parent = elem; 11315 var visible = getCSS(document.body, 'visibility') == 'hidden' || getCSS(elem, 'visibility') != 'hidden'; 11316 11317 eLtop -= elemExpand; 11318 eLbottom += elemExpand; 11319 eLleft -= elemExpand; 11320 eLright += elemExpand; 11321 11322 while(visible && (parent = parent.offsetParent) && parent != document.body && parent != docElem){ 11323 visible = ((getCSS(parent, 'opacity') || 1) > 0); 11324 11325 if(visible && getCSS(parent, 'overflow') != 'visible'){ 11326 outerRect = parent.getBoundingClientRect(); 11327 visible = eLright > outerRect.left && 11328 eLleft < outerRect.right && 11329 eLbottom > outerRect.top - 1 && 11330 eLtop < outerRect.bottom + 1 11331 ; 11332 } 11333 } 11334 11335 return visible; 11336 }; 11337 11338 var checkElements = function() { 11339 var eLlen, i, rect, autoLoadElem, loadedSomething, elemExpand, elemNegativeExpand, elemExpandVal, beforeExpandVal; 11340 11341 if((loadMode = lazySizesConfig.loadMode) && isLoading < 8 && (eLlen = lazyloadElems.length)){ 11342 11343 i = 0; 11344 11345 lowRuns++; 11346 11347 if(preloadExpand == null){ 11348 if(!('expand' in lazySizesConfig)){ 11349 lazySizesConfig.expand = docElem.clientHeight > 500 && docElem.clientWidth > 500 ? 500 : 370; 11350 } 11351 11352 defaultExpand = lazySizesConfig.expand; 11353 preloadExpand = defaultExpand * lazySizesConfig.expFactor; 11354 } 11355 11356 if(currentExpand < preloadExpand && isLoading < 1 && lowRuns > 2 && loadMode > 2 && !document.hidden){ 11357 currentExpand = preloadExpand; 11358 lowRuns = 0; 11359 } else if(loadMode > 1 && lowRuns > 1 && isLoading < 6){ 11360 currentExpand = defaultExpand; 11361 } else { 11362 currentExpand = shrinkExpand; 11363 } 11364 11365 for(; i < eLlen; i++){ 11366 11367 if(!lazyloadElems[i] || lazyloadElems[i]._lazyRace){continue;} 11368 11369 if(!supportScroll){unveilElement(lazyloadElems[i]);continue;} 11370 11371 if(!(elemExpandVal = lazyloadElems[i][_getAttribute]('data-expand')) || !(elemExpand = elemExpandVal * 1)){ 11372 elemExpand = currentExpand; 11373 } 11374 11375 if(beforeExpandVal !== elemExpand){ 11376 eLvW = innerWidth + (elemExpand * hFac); 11377 elvH = innerHeight + elemExpand; 11378 elemNegativeExpand = elemExpand * -1; 11379 beforeExpandVal = elemExpand; 11380 } 11381 11382 rect = lazyloadElems[i].getBoundingClientRect(); 11383 11384 if ((eLbottom = rect.bottom) >= elemNegativeExpand && 11385 (eLtop = rect.top) <= elvH && 11386 (eLright = rect.right) >= elemNegativeExpand * hFac && 11387 (eLleft = rect.left) <= eLvW && 11388 (eLbottom || eLright || eLleft || eLtop) && 11389 ((isCompleted && isLoading < 3 && !elemExpandVal && (loadMode < 3 || lowRuns < 4)) || isNestedVisible(lazyloadElems[i], elemExpand))){ 11390 unveilElement(lazyloadElems[i]); 11391 loadedSomething = true; 11392 if(isLoading > 9){break;} 11393 } else if(!loadedSomething && isCompleted && !autoLoadElem && 11394 isLoading < 4 && lowRuns < 4 && loadMode > 2 && 11395 (preloadElems[0] || lazySizesConfig.preloadAfterLoad) && 11396 (preloadElems[0] || (!elemExpandVal && ((eLbottom || eLright || eLleft || eLtop) || lazyloadElems[i][_getAttribute](lazySizesConfig.sizesAttr) != 'auto')))){ 11397 autoLoadElem = preloadElems[0] || lazyloadElems[i]; 11398 } 11399 } 11400 11401 if(autoLoadElem && !loadedSomething){ 11402 unveilElement(autoLoadElem); 11403 } 11404 } 11405 }; 11406 11407 var throttledCheckElements = throttle(checkElements); 11408 11409 var switchLoadingClass = function(e){ 11410 addClass(e.target, lazySizesConfig.loadedClass); 11411 removeClass(e.target, lazySizesConfig.loadingClass); 11412 addRemoveLoadEvents(e.target, rafSwitchLoadingClass); 11413 }; 11414 var rafedSwitchLoadingClass = rAFIt(switchLoadingClass); 11415 var rafSwitchLoadingClass = function(e){ 11416 rafedSwitchLoadingClass({target: e.target}); 11417 }; 11418 11419 var changeIframeSrc = function(elem, src){ 11420 try { 11421 elem.contentWindow.location.replace(src); 11422 } catch(e){ 11423 elem.src = src; 11424 } 11425 }; 11426 11427 var handleSources = function(source){ 11428 var customMedia, parent; 11429 11430 var sourceSrcset = source[_getAttribute](lazySizesConfig.srcsetAttr); 11431 11432 if( (customMedia = lazySizesConfig.customMedia[source[_getAttribute]('data-media') || source[_getAttribute]('media')]) ){ 11433 source.setAttribute('media', customMedia); 11434 } 11435 11436 if(sourceSrcset){ 11437 source.setAttribute('srcset', sourceSrcset); 11438 } 11439 11440 //https://bugzilla.mozilla.org/show_bug.cgi?id=1170572 11441 if(customMedia){ 11442 parent = source.parentNode; 11443 parent.insertBefore(source.cloneNode(), source); 11444 parent.removeChild(source); 11445 } 11446 }; 11447 11448 var lazyUnveil = rAFIt(function (elem, detail, isAuto, sizes, isImg){ 11449 var src, srcset, parent, isPicture, event, firesLoad; 11450 11451 if(!(event = triggerEvent(elem, 'lazybeforeunveil', detail)).defaultPrevented){ 11452 11453 if(sizes){ 11454 if(isAuto){ 11455 addClass(elem, lazySizesConfig.autosizesClass); 11456 } else { 11457 elem.setAttribute('sizes', sizes); 11458 } 11459 } 11460 11461 srcset = elem[_getAttribute](lazySizesConfig.srcsetAttr); 11462 src = elem[_getAttribute](lazySizesConfig.srcAttr); 11463 11464 if(isImg) { 11465 parent = elem.parentNode; 11466 isPicture = parent && regPicture.test(parent.nodeName || ''); 11467 } 11468 11469 firesLoad = detail.firesLoad || (('src' in elem) && (srcset || src || isPicture)); 11470 11471 event = {target: elem}; 11472 11473 if(firesLoad){ 11474 addRemoveLoadEvents(elem, resetPreloading, true); 11475 clearTimeout(resetPreloadingTimer); 11476 resetPreloadingTimer = setTimeout(resetPreloading, 2500); 11477 11478 addClass(elem, lazySizesConfig.loadingClass); 11479 addRemoveLoadEvents(elem, rafSwitchLoadingClass, true); 11480 } 11481 11482 if(isPicture){ 11483 forEach.call(parent.getElementsByTagName('source'), handleSources); 11484 } 11485 11486 if(srcset){ 11487 elem.setAttribute('srcset', srcset); 11488 } else if(src && !isPicture){ 11489 if(regIframe.test(elem.nodeName)){ 11490 changeIframeSrc(elem, src); 11491 } else { 11492 elem.src = src; 11493 } 11494 } 11495 11496 if(srcset || isPicture){ 11497 updatePolyfill(elem, {src: src}); 11498 } 11499 } 11500 11501 if(elem._lazyRace){ 11502 delete elem._lazyRace; 11503 } 11504 removeClass(elem, lazySizesConfig.lazyClass); 11505 11506 rAF(function(){ 11507 if( !firesLoad || (elem.complete && elem.naturalWidth > 1)){ 11508 if(firesLoad){ 11509 resetPreloading(event); 11510 } else { 11511 isLoading--; 11512 } 11513 switchLoadingClass(event); 11514 } 11515 }, true); 11516 }); 11517 11518 var unveilElement = function (elem){ 11519 var detail; 11520 11521 var isImg = regImg.test(elem.nodeName); 11522 11523 //allow using sizes="auto", but don't use. it's invalid. Use data-sizes="auto" or a valid value for sizes instead (i.e.: sizes="80vw") 11524 var sizes = isImg && (elem[_getAttribute](lazySizesConfig.sizesAttr) || elem[_getAttribute]('sizes')); 11525 var isAuto = sizes == 'auto'; 11526 11527 if( (isAuto || !isCompleted) && isImg && (elem.src || elem.srcset) && !elem.complete && !hasClass(elem, lazySizesConfig.errorClass)){return;} 11528 11529 detail = triggerEvent(elem, 'lazyunveilread').detail; 11530 11531 if(isAuto){ 11532 autoSizer.updateElem(elem, true, elem.offsetWidth); 11533 } 11534 11535 elem._lazyRace = true; 11536 isLoading++; 11537 11538 lazyUnveil(elem, detail, isAuto, sizes, isImg); 11539 }; 11540 11541 var onload = function(){ 11542 if(isCompleted){return;} 11543 if(Date.now() - started < 999){ 11544 setTimeout(onload, 999); 11545 return; 11546 } 11547 var afterScroll = debounce(function(){ 11548 lazySizesConfig.loadMode = 3; 11549 throttledCheckElements(); 11550 }); 11551 11552 isCompleted = true; 11553 11554 lazySizesConfig.loadMode = 3; 11555 11556 throttledCheckElements(); 11557 11558 addEventListener('scroll', function(){ 11559 if(lazySizesConfig.loadMode == 3){ 11560 lazySizesConfig.loadMode = 2; 11561 } 11562 afterScroll(); 11563 }, true); 11564 }; 11565 11566 return { 11567 _: function(){ 11568 started = Date.now(); 11569 11570 lazyloadElems = document.getElementsByClassName(lazySizesConfig.lazyClass); 11571 preloadElems = document.getElementsByClassName(lazySizesConfig.lazyClass + ' ' + lazySizesConfig.preloadClass); 11572 hFac = lazySizesConfig.hFac; 11573 11574 addEventListener('scroll', throttledCheckElements, true); 11575 11576 addEventListener('resize', throttledCheckElements, true); 11577 11578 if(window.MutationObserver){ 11579 new MutationObserver( throttledCheckElements ).observe( docElem, {childList: true, subtree: true, attributes: true} ); 11580 } else { 11581 docElem[_addEventListener]('DOMNodeInserted', throttledCheckElements, true); 11582 docElem[_addEventListener]('DOMAttrModified', throttledCheckElements, true); 11583 setInterval(throttledCheckElements, 999); 11584 } 11585 11586 addEventListener('hashchange', throttledCheckElements, true); 11587 11588 //, 'fullscreenchange' 11589 ['focus', 'mouseover', 'click', 'load', 'transitionend', 'animationend', 'webkitAnimationEnd'].forEach(function(name){ 11590 document[_addEventListener](name, throttledCheckElements, true); 11591 }); 11592 11593 if((/d$|^c/.test(document.readyState))){ 11594 onload(); 11595 } else { 11596 addEventListener('load', onload); 11597 document[_addEventListener]('DOMContentLoaded', throttledCheckElements); 11598 setTimeout(onload, 20000); 11599 } 11600 11601 if(lazyloadElems.length){ 11602 checkElements(); 11603 rAF._lsFlush(); 11604 } else { 11605 throttledCheckElements(); 11606 } 11607 }, 11608 checkElems: throttledCheckElements, 11609 unveil: unveilElement 11610 }; 11611 })(); 11612 11613 11614 var autoSizer = (function(){ 11615 var autosizesElems; 11616 11617 var sizeElement = rAFIt(function(elem, parent, event, width){ 11618 var sources, i, len; 11619 elem._lazysizesWidth = width; 11620 width += 'px'; 11621 11622 elem.setAttribute('sizes', width); 11623 11624 if(regPicture.test(parent.nodeName || '')){ 11625 sources = parent.getElementsByTagName('source'); 11626 for(i = 0, len = sources.length; i < len; i++){ 11627 sources[i].setAttribute('sizes', width); 11628 } 11629 } 11630 11631 if(!event.detail.dataAttr){ 11632 updatePolyfill(elem, event.detail); 11633 } 11634 }); 11635 var getSizeElement = function (elem, dataAttr, width){ 11636 var event; 11637 var parent = elem.parentNode; 11638 11639 if(parent){ 11640 width = getWidth(elem, parent, width); 11641 event = triggerEvent(elem, 'lazybeforesizes', {width: width, dataAttr: !!dataAttr}); 11642 11643 if(!event.defaultPrevented){ 11644 width = event.detail.width; 11645 11646 if(width && width !== elem._lazysizesWidth){ 11647 sizeElement(elem, parent, event, width); 11648 } 11649 } 11650 } 11651 }; 11652 11653 var updateElementsSizes = function(){ 11654 var i; 11655 var len = autosizesElems.length; 11656 if(len){ 11657 i = 0; 11658 11659 for(; i < len; i++){ 11660 getSizeElement(autosizesElems[i]); 11661 } 11662 } 11663 }; 11664 11665 var debouncedUpdateElementsSizes = debounce(updateElementsSizes); 11666 11667 return { 11668 _: function(){ 11669 autosizesElems = document.getElementsByClassName(lazySizesConfig.autosizesClass); 11670 addEventListener('resize', debouncedUpdateElementsSizes); 11671 }, 11672 checkElems: debouncedUpdateElementsSizes, 11673 updateElem: getSizeElement 11674 }; 11675 })(); 11676 11677 var init = function(){ 11678 if(!init.i){ 11679 init.i = true; 11680 autoSizer._(); 11681 loader._(); 11682 } 11683 }; 11684 11685 (function(){ 11686 var prop; 11687 11688 var lazySizesDefaults = { 11689 lazyClass: 'lazyload', 11690 loadedClass: 'lazyloaded', 11691 loadingClass: 'lazyloading', 11692 preloadClass: 'lazypreload', 11693 errorClass: 'lazyerror', 11694 //strictClass: 'lazystrict', 11695 autosizesClass: 'lazyautosizes', 11696 srcAttr: 'data-src', 11697 srcsetAttr: 'data-srcset', 11698 sizesAttr: 'data-sizes', 11699 //preloadAfterLoad: false, 11700 minSize: 40, 11701 customMedia: {}, 11702 init: true, 11703 expFactor: 1.5, 11704 hFac: 0.8, 11705 loadMode: 2 11706 }; 11707 11708 lazySizesConfig = window.lazySizesConfig || window.lazysizesConfig || {}; 11709 11710 for(prop in lazySizesDefaults){ 11711 if(!(prop in lazySizesConfig)){ 11712 lazySizesConfig[prop] = lazySizesDefaults[prop]; 11713 } 11714 } 11715 11716 window.lazySizesConfig = lazySizesConfig; 11717 11718 setTimeout(function(){ 11719 if(lazySizesConfig.init){ 11720 init(); 11721 } 11722 }); 11723 })(); 11724 11725 return { 11726 cfg: lazySizesConfig, 11727 autoSizer: autoSizer, 11728 loader: loader, 11729 init: init, 11730 uP: updatePolyfill, 11731 aC: addClass, 11732 rC: removeClass, 11733 hC: hasClass, 11734 fire: triggerEvent, 11735 gW: getWidth, 11736 rAF: rAF, 11737 }; 11738 } 11739 )); 11740 11741 11742 /***/ }), 11743 /* 15 */ 11744 /***/ (function(module, exports) { 11745 11746 /* 11747 This plugin extends lazySizes to lazyLoad: 11748 background images, videos/posters and scripts 11749 11750 Background-Image: 11751 For background images, use data-bg attribute: 11752 <div class="lazyload" data-bg="bg-img.jpg"></div> 11753 11754 Video: 11755 For video/audio use data-poster and preload="none": 11756 <video class="lazyload" data-poster="poster.jpg" preload="none"> 11757 <!-- sources --> 11758 </video> 11759 11760 Scripts: 11761 For scripts use data-script: 11762 <div class="lazyload" data-script="module-name.js"></div> 11763 11764 11765 Script modules using require: 11766 For modules using require use data-require: 11767 <div class="lazyload" data-require="module-name"></div> 11768 */ 11769 11770 (function(window, document){ 11771 /*jshint eqnull:true */ 11772 'use strict'; 11773 var bgLoad, regBgUrlEscape; 11774 var uniqueUrls = {}; 11775 11776 if(document.addEventListener){ 11777 regBgUrlEscape = /\(|\)|\s|'/; 11778 11779 bgLoad = function (url, cb){ 11780 var img = document.createElement('img'); 11781 img.onload = function(){ 11782 img.onload = null; 11783 img.onerror = null; 11784 img = null; 11785 cb(); 11786 }; 11787 img.onerror = img.onload; 11788 11789 img.src = url; 11790 11791 if(img && img.complete && img.onload){ 11792 img.onload(); 11793 } 11794 }; 11795 11796 addEventListener('lazybeforeunveil', function(e){ 11797 var tmp, load, bg, poster; 11798 if(!e.defaultPrevented) { 11799 11800 if(e.target.preload == 'none'){ 11801 e.target.preload = 'auto'; 11802 } 11803 11804 tmp = e.target.getAttribute('data-link'); 11805 if(tmp){ 11806 addStyleScript(tmp, true); 11807 } 11808 11809 // handle data-script 11810 tmp = e.target.getAttribute('data-script'); 11811 if(tmp){ 11812 addStyleScript(tmp); 11813 } 11814 11815 // handle data-require 11816 tmp = e.target.getAttribute('data-require'); 11817 if(tmp){ 11818 if(lazySizes.cfg.requireJs){ 11819 lazySizes.cfg.requireJs([tmp]); 11820 } else { 11821 addStyleScript(tmp); 11822 } 11823 } 11824 11825 // handle data-bg 11826 bg = e.target.getAttribute('data-bg'); 11827 if (bg) { 11828 e.detail.firesLoad = true; 11829 load = function(){ 11830 e.target.style.backgroundImage = 'url(' + (regBgUrlEscape.test(bg) ? JSON.stringify(bg) : bg ) + ')'; 11831 e.detail.firesLoad = false; 11832 lazySizes.fire(e.target, '_lazyloaded', {}, true, true); 11833 }; 11834 11835 bgLoad(bg, load); 11836 } 11837 11838 // handle data-poster 11839 poster = e.target.getAttribute('data-poster'); 11840 if(poster){ 11841 e.detail.firesLoad = true; 11842 load = function(){ 11843 e.target.poster = poster; 11844 e.detail.firesLoad = false; 11845 lazySizes.fire(e.target, '_lazyloaded', {}, true, true); 11846 }; 11847 11848 bgLoad(poster, load); 11849 11850 } 11851 } 11852 }, false); 11853 11854 } 11855 11856 function addStyleScript(src, style){ 11857 if(uniqueUrls[src]){ 11858 return; 11859 } 11860 var elem = document.createElement(style ? 'link' : 'script'); 11861 var insertElem = document.getElementsByTagName('script')[0]; 11862 11863 if(style){ 11864 elem.rel = 'stylesheet'; 11865 elem.href = src; 11866 } else { 11867 elem.src = src; 11868 } 11869 uniqueUrls[src] = true; 11870 uniqueUrls[elem.src || elem.href] = true; 11871 insertElem.parentNode.insertBefore(elem, insertElem); 11872 } 11873 })(window, document); 11874 11875 11876 /***/ }), 11877 /* 16 */ 11878 /***/ (function(module, exports, __webpack_require__) { 11879 11880 /** 11881 * scrolldir - Vertical scroll direction in CSS 11882 * @version v1.2.8 11883 * @link https://github.com/dollarshaveclub/scrolldir.git 11884 * @author Patrick Fisher <patrick@pwfisher.com> 11885 * @license MIT 11886 **/ 11887 !function(t,e){ true?e():"function"==typeof define&&define.amd?define(e):e()}(0,function(){"use strict";!function(){var t=document.documentElement,e=window,n=document.body,o=Array(32),i="down",d=void 0,r=void 0,a=0,f=function(){var f=e.scrollY,u=d.timeStamp,c="down"===i?Math.max:Math.min,s=n.offsetHeight-e.innerHeight;if(f=Math.max(0,f),f=Math.min(s,f),o.unshift({y:f,t:u}),o.pop(),f===c(r,f))return a=u,void(r=f);var m=u-512;if(m>a){r=f;for(var l=0;l<32&&o[l]&&!(o[l].t<m);l+=1)r=c(r,o[l].y)}Math.abs(f-r)>64&&(r=f,a=u,i="down"===i?"up":"down",t.setAttribute("data-scrolldir",i))},u=function(t){d=t,e.requestAnimationFrame(f)};r=e.scrollY,t.setAttribute("data-scrolldir",i),e.addEventListener("scroll",u)}()}); 11888 11889 /***/ }) 11890 /******/ ]);